11package com .iemr .tm .utils ;
22
3- import java .security .Key ;
4- import java .util .Date ;
53import java .util .function .Function ;
64
5+ import javax .crypto .SecretKey ;
6+
7+ import org .springframework .beans .factory .annotation .Autowired ;
78import org .springframework .beans .factory .annotation .Value ;
89import org .springframework .stereotype .Component ;
910
1011import io .jsonwebtoken .Claims ;
1112import io .jsonwebtoken .Jwts ;
12- import io .jsonwebtoken .SignatureAlgorithm ;
1313import io .jsonwebtoken .security .Keys ;
1414
1515@ Component
@@ -18,46 +18,70 @@ public class JwtUtil {
1818 @ Value ("${jwt.secret}" )
1919 private String SECRET_KEY ;
2020
21- private static final long EXPIRATION_TIME = 24L * 60 * 60 * 1000 ; // 1 day in milliseconds
21+ @ Autowired
22+ private TokenDenylist tokenDenylist ;
2223
2324 // Generate a key using the secret
24- private Key getSigningKey () {
25+ private SecretKey getSigningKey () {
2526 if (SECRET_KEY == null || SECRET_KEY .isEmpty ()) {
2627 throw new IllegalStateException ("JWT secret key is not set in application.properties" );
2728 }
2829 return Keys .hmacShaKeyFor (SECRET_KEY .getBytes ());
2930 }
3031
31- // Generate JWT Token
32- public String generateToken (String username , String userId ) {
33- Date now = new Date ();
34- Date expiryDate = new Date (now .getTime () + EXPIRATION_TIME );
35-
36- // Include the userId in the JWT claims
37- return Jwts .builder ().setSubject (username ).claim ("userId" , userId ) // Add userId as a claim
38- .setIssuedAt (now ).setExpiration (expiryDate ).signWith (getSigningKey (), SignatureAlgorithm .HS256 )
39- .compact ();
40- }
41-
4232 // Validate and parse JWT Token
4333 public Claims validateToken (String token ) {
4434 try {
45- return Jwts .parser ().setSigningKey (getSigningKey ()).build ().parseClaimsJws (token ).getBody ();
35+ Claims claims = Jwts .parser ()
36+ .verifyWith (getSigningKey ())
37+ .build ()
38+ .parseSignedClaims (token )
39+ .getPayload ();
40+
41+ String jti = claims .getId ();
42+
43+ // Check if token is denylisted (only if jti exists)
44+ if (jti != null && tokenDenylist .isTokenDenylisted (jti )) {
45+ return null ;
46+ }
47+
48+ return claims ;
4649 } catch (Exception e ) {
4750 return null ; // Handle token parsing/validation errors
4851 }
4952 }
5053
54+ // Invalidate a token by adding it to denylist
55+ public void invalidateToken (String token ) {
56+ try {
57+ Claims claims = extractAllClaims (token );
58+ if (claims != null && claims .getId () != null ) {
59+ // Get remaining time until expiration
60+ long expirationTime = claims .getExpiration ().getTime () - System .currentTimeMillis ();
61+ if (expirationTime > 0 ) {
62+ tokenDenylist .addTokenToDenylist (claims .getId (), expirationTime );
63+ }
64+ }
65+ } catch (Exception e ) {
66+ // Log error but don't throw - token might be invalid already
67+ throw new RuntimeException ("Failed to invalidate token" , e );
68+ }
69+ }
70+
5171 public String extractUsername (String token ) {
5272 return extractClaim (token , Claims ::getSubject );
5373 }
5474
5575 public <T > T extractClaim (String token , Function <Claims , T > claimsResolver ) {
5676 final Claims claims = extractAllClaims (token );
57- return claimsResolver .apply (claims );
77+ return claims != null ? claimsResolver .apply (claims ) : null ;
5878 }
5979
6080 private Claims extractAllClaims (String token ) {
61- return Jwts .parser ().setSigningKey (getSigningKey ()).build ().parseClaimsJws (token ).getBody ();
81+ return Jwts .parser ()
82+ .verifyWith (getSigningKey ())
83+ .build ()
84+ .parseSignedClaims (token )
85+ .getPayload ();
6286 }
6387}
0 commit comments