JwtService.java

package com.archiweb.security;

import com.archiweb.model.User;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class JwtService {

    // 🔐 ClĂ© secrĂšte unique pour signer les tokens
    private final SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    // ⏱ Expiration du token : 24 heures
    private final long EXPIRATION = 86_400_000; // 24h en ms

    /**
     * ✅ GĂ©nĂšre un token JWT Ă  partir d’un utilisateur.
     */
    public String generateToken(User user) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("role", user.getRole().getName());

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(user.getEmail()) // email = username
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .signWith(secretKey, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * ✅ GĂ©nĂšre un token Ă  partir d’un email et d’un rĂŽle (utile pour le refresh).
     */
    public String generateToken(String email, String role) {
        return Jwts.builder()
                .setSubject(email)
                .claim("role", role)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .signWith(secretKey, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * ✅ Extrait l’email (subject) du token.
     */
    public String extractEmail(String token) {
        return getClaims(token).getSubject();
    }

    /**
     * ✅ Extrait le rîle du token.
     */
    public String extractRole(String token) {
        Object roleObj = getClaims(token).get("role");
        return (roleObj != null) ? roleObj.toString() : "ROLE_USER";
    }

    /**
     * ✅ VĂ©rifie si le token est valide et non expirĂ©.
     */
    public boolean validateToken(String token) {
        try {
            Claims claims = getClaims(token);
            return !claims.getExpiration().before(new Date());
        } catch (JwtException | IllegalArgumentException e) {
            return false;
        }
    }

    /**
     * ✅ RafraĂźchit un token valide (nouveau token avec mĂȘme email + rĂŽle).
     */
    public String refreshToken(String oldToken) {
        if (!validateToken(oldToken)) {
            throw new RuntimeException("Invalid or expired refresh token");
        }

        String email = extractEmail(oldToken);
        String role = extractRole(oldToken);

        return generateToken(email, role);
    }

    /**
     * 🔐 RĂ©cupĂšre les Claims d’un JWT.
     */
    private Claims getClaims(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(secretKey)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
}