content: package com.example.identityservice.token;
  
  import io.github.cdimascio.dotenv.Dotenv;
  import io.jsonwebtoken.Claims;
  import io.jsonwebtoken.Jwts;
  import io.jsonwebtoken.SignatureAlgorithm;
  import io.jsonwebtoken.io.Decoders;
  import io.jsonwebtoken.security.Keys;
  import org.springframework.security.core.userdetails.UserDetails;
  import org.springframework.stereotype.Service;
  
  import java.security.Key;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.function.Function;
  
  @Service
  public class JwtService {
  
      private final String secretKey;
  
      public JwtService() {
          Dotenv dotenv = Dotenv.load();
          this.secretKey = dotenv.get("SECRET_KEY");
      }
  
      public String extractUsername(String token) {
          return extractClaim(token, Claims::getSubject);
      }
  
      public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
          final Claims claims = extractAllClaims(token);
          return claimsResolver.apply(claims);
      }
  
      public String generateToken(UserDetails userDetails) {
          return generateToken(new HashMap<>(), userDetails);
      }
  
      public String generateToken(Map<String, Object> extractClaims, UserDetails userDetails) {
          return Jwts
              .builder()
              .setClaims(extractClaims)
              .setSubject(userDetails.getUsername())
              .setIssuedAt(new Date(System.currentTimeMillis()))
              .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 24))
              .signWith(getSigningKey(), SignatureAlgorithm.HS256)
              .compact();
      }
  
      public boolean isTokenValid(String token, UserDetails userDetails) {
          final String username = extractUsername(token);
          return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
      }
  
      private boolean isTokenExpired(String token) {
          return extractExpiration(token).before(new Date());
      }
  
      private Date extractExpiration(String token) {
          return extractClaim(token, Claims::getExpiration);
      }
  
      private Claims extractAllClaims(String token) {
          return Jwts
                  .parserBuilder()
                  .setSigningKey(getSigningKey())
                  .build()
                  .parseClaimsJws(token)
                  .getBody();
      }
  
      private Key getSigningKey() {
          byte[] keyBytes = Decoders.BASE64.decode(secretKey);
          return Keys.hmacShaKeyFor(keyBytes);
      }
  }