using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using eprintServer.Entities; using eprintServer.Data; // Assuming your User entity is here namespace eprintServer.Services; public class TokenService { private readonly IConfiguration _config; private readonly DataContext _context; public TokenService(IConfiguration config) { _config = config; } public string CreateToken(User user) { var userRole = user.Role.ToString().Replace("ROLE_", ""); var claims = new List { new Claim(ClaimTypes.Name, user.Username), new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Email, user.Email), new Claim(ClaimTypes.Role, userRole) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]!)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.Now.AddDays(7), SigningCredentials = creds, Issuer = _config["Jwt:Issuer"], Audience = _config["Jwt:Audience"] }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } public async Task RevokeTokenAsync(string token) { try { // Option 1: Add to a blacklist/revoked tokens table var revokedToken = new RevokedToken { Token = token, RevokedAt = DateTime.UtcNow, ExpiresAt = GetTokenExpiration(token) // You'd need to extract expiration from token }; await _context.RevokedTokens.AddAsync(revokedToken); await _context.SaveChangesAsync(); // Option 2: If you're using a distributed cache // await _cache.SetStringAsync($"revoked_token:{token}", "revoked", new DistributedCacheEntryOptions // { // AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(7) // }); } catch (Exception ex) { // Log the exception but don't throw - logout should succeed even if token revocation fails Console.WriteLine($"Failed to revoke token: {ex.Message}"); } } private DateTime? GetTokenExpiration(string token) { try { var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler(); var jwtToken = handler.ReadJwtToken(token); return jwtToken.ValidTo; } catch { return DateTime.UtcNow.AddDays(7); // Default expiration } } }