package de.towerdefence.server.session; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.WeakKeyException; import jakarta.annotation.PostConstruct; import org.springframework.stereotype.Service; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Optional; @Service public class JwtService { private final SecretKey secretKey; public JwtService(JwtServiceConfig config) throws WeakKeyException { this.secretKey = Keys.hmacShaKeyFor(config.getSecret().getBytes(StandardCharsets.UTF_8)); } public String generateToken(String username, Channel channel, long ttl) { long now = System.currentTimeMillis(); Date issueDate = new Date(now); Date expirationDate = new Date(now + ttl * 1000); return Jwts.builder() .subject(username) .claim("channel", channel.getJsonName()) .issuedAt(issueDate) .expiration(expirationDate) .signWith(secretKey) .compact(); } public Optional verifyToken(String token, Channel channel) { Claims claims = Jwts.parser() .verifyWith(secretKey) .build() .parseSignedClaims(token) .getPayload(); if (claims.getExpiration().before(new Date())) { return Optional.empty(); } Channel tokenChannel; try { tokenChannel = Channel.fromJsonName(claims.get("channel", String.class)); } catch (IllegalArgumentException ignored) { return Optional.empty(); } if(!channel.equals(tokenChannel)) { return Optional.empty(); } return Optional.of(claims.getSubject()); } }