package com.example.app.services; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Function; import javax.crypto.SecretKey; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Service; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; import lombok.Getter; @Getter @Service public class JwtService { @Value("${SECRET}") private String SECRET; public String generateToken(String username) { Map claims = new HashMap<>(); return generateToken(claims, username); } private String generateToken(Map claims, String username) { return Jwts .builder() .claims(claims) .subject(username) .issuedAt(new Date()) .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 30)) .signWith(getSignKey()) .compact(); } private SecretKey getSignKey() { byte[] keyBytes = Decoders.BASE64.decode(SECRET); return Keys.hmacShaKeyFor(keyBytes); } public Optional extractUsername(String token) { return extractClaim(token, Claims::getSubject); } public Optional extractExpiration(String token) { return extractClaim(token, Claims::getExpiration); } public Optional extractClaim(String token, Function claimResolver) { final Claims claims = extractAllClaims(token); return Optional.ofNullable(claimResolver.apply(claims)); } private Claims extractAllClaims(String token) { return Jwts .parser() .verifyWith(getSignKey()) .build() .parseSignedClaims(token) .getPayload(); } private boolean isTokenExpired(String token) { return extractExpiration(token).map(x -> x.before(new Date())).orElse(false); } public boolean validateToken(String token, UserDetails user) { return extractUsername(token).map(x -> x.equals(user.getUsername())).orElse(false) && !isTokenExpired(token); } }