11package com .iemr .inventory .utils ;
22
3- import java .security .Key ;
4- import java .util .Date ;
53import java .util .function .Function ;
4+ import javax .crypto .SecretKey ;
65
6+ import org .springframework .beans .factory .annotation .Autowired ;
77import org .springframework .beans .factory .annotation .Value ;
88import org .springframework .stereotype .Component ;
99
1010import io .jsonwebtoken .Claims ;
1111import io .jsonwebtoken .Jwts ;
12- import io .jsonwebtoken .SignatureAlgorithm ;
1312import io .jsonwebtoken .security .Keys ;
1413
1514@ Component
@@ -18,31 +17,51 @@ public class JwtUtil {
1817 @ Value ("${jwt.secret}" )
1918 private String SECRET_KEY ;
2019
21- private static final long EXPIRATION_TIME = 24L * 60 * 60 * 1000 ; // 1 day in milliseconds
20+ @ Autowired
21+ private TokenDenylist tokenDenylist ;
2222
2323 // Generate a key using the secret
24- private Key getSigningKey () {
24+ private SecretKey getSigningKey () {
2525 if (SECRET_KEY == null || SECRET_KEY .isEmpty ()) {
2626 throw new IllegalStateException ("JWT secret key is not set in application.properties" );
2727 }
2828 return Keys .hmacShaKeyFor (SECRET_KEY .getBytes ());
2929 }
3030
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 ();
31+ // Invalidate a token by adding it to denylist
32+ public void invalidateToken (String token ) {
33+ try {
34+ Claims claims = extractAllClaims (token );
35+ if (claims != null && claims .getId () != null ) {
36+ // Get remaining time until expiration
37+ long expirationTime = claims .getExpiration ().getTime () - System .currentTimeMillis ();
38+ if (expirationTime > 0 ) {
39+ tokenDenylist .addTokenToDenylist (claims .getId (), expirationTime );
40+ }
41+ }
42+ } catch (Exception e ) {
43+ // Log error but don't throw - token might be invalid already
44+ throw new RuntimeException ("Failed to invalidate token" , e );
45+ }
4046 }
4147
4248 // Validate and parse JWT Token
4349 public Claims validateToken (String token ) {
4450 try {
45- return Jwts .parser ().setSigningKey (getSigningKey ()).build ().parseClaimsJws (token ).getBody ();
51+ Claims claims = Jwts .parser ()
52+ .verifyWith (getSigningKey ())
53+ .build ()
54+ .parseSignedClaims (token )
55+ .getPayload ();
56+
57+ String jti = claims .getId ();
58+
59+ // Check if token is denylisted (only if jti exists)
60+ if (jti != null && tokenDenylist .isTokenDenylisted (jti )) {
61+ return null ;
62+ }
63+
64+ return claims ;
4665 } catch (Exception e ) {
4766 return null ; // Handle token parsing/validation errors
4867 }
@@ -54,10 +73,14 @@ public String extractUsername(String token) {
5473
5574 public <T > T extractClaim (String token , Function <Claims , T > claimsResolver ) {
5675 final Claims claims = extractAllClaims (token );
57- return claimsResolver .apply (claims );
76+ return claims != null ? claimsResolver .apply (claims ) : null ;
5877 }
5978
6079 private Claims extractAllClaims (String token ) {
61- return Jwts .parser ().setSigningKey (getSigningKey ()).build ().parseClaimsJws (token ).getBody ();
80+ return Jwts .parser ()
81+ .verifyWith (getSigningKey ())
82+ .build ()
83+ .parseSignedClaims (token )
84+ .getPayload ();
6285 }
6386}
0 commit comments