content: package com.amran.dynamic.multitenant.util;
  
  import com.amran.dynamic.multitenant.constant.JWTConstants;
  import io.jsonwebtoken.Claims;
  import io.jsonwebtoken.Jwts;
  import io.jsonwebtoken.SignatureAlgorithm;
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
  import org.springframework.security.core.userdetails.UserDetails;
  import org.springframework.stereotype.Component;
  
  import java.io.Serializable;
  import java.util.Arrays;
  import java.util.Date;
  import java.util.function.Function;
  
  /**
   * @author Md. Amran Hossain
   */
  @Component
  public class JwtTokenUtil implements Serializable {
  
      private static final long serialVersionUID = -2550185165626007488L;
  
      public String getUsernameFromToken(String token) {
          return getClaimFromToken(token, Claims::getSubject);
      }
  
      public String getAudienceFromToken(String token) {
          return getClaimFromToken(token, Claims::getAudience);
      }
  
      public Date getExpirationDateFromToken(String token) {
          return getClaimFromToken(token, Claims::getExpiration);
      }
  
      public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
          final Claims claims = getAllClaimsFromToken(token);
          return claimsResolver.apply(claims);
      }
  
      private Claims getAllClaimsFromToken(String token) {
          return Jwts.parser()
                  .setSigningKey(JWTConstants.SIGNING_KEY)
                  .parseClaimsJws(token)
                  .getBody();
      }
  
      private Boolean isTokenExpired(String token) {
          final Date expiration = getExpirationDateFromToken(token);
          return expiration.before(new Date());
      }
  
      public String generateToken(String userName, String tenantOrClientId) {
          return doGenerateToken(userName,tenantOrClientId);
      }
  
      private String doGenerateToken(String subject, String tenantOrClientId) {
  
          Claims claims = Jwts.claims().setSubject(subject).setAudience(tenantOrClientId);
          claims.put("scopes", Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN")));
  
          return Jwts.builder()
                  .setClaims(claims)
                  .setIssuer("system")
                  .setIssuedAt(new Date(System.currentTimeMillis()))
                  .setExpiration(new Date(System.currentTimeMillis() + JWTConstants.ACCESS_TOKEN_VALIDITY_SECONDS * 1000))
                  .signWith(SignatureAlgorithm.HS256, JWTConstants.SIGNING_KEY)
                  .compact();
      }
  
      public Boolean validateToken(String token, UserDetails userDetails) {
          final String username = getUsernameFromToken(token);
          return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
      }
  }
  