using System.Security.Claims; using Microsoft.IdentityModel.Tokens; using ir23.Data; using System.IdentityModel.Tokens.Jwt; using Microsoft.EntityFrameworkCore; namespace ir23.VerificationModels { public class JwtService { private string jwtkey = "CHANGE_ME_PLEASE!! CHANGE TO A RANDOM UUID"; private readonly AppDbContext _db; public JwtService(AppDbContext db) { _db = db; } public string GenerateToken(long userId) { var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(jwtkey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()) }; var token = new JwtSecurityToken( claims: claims, expires: DateTime.UtcNow.AddHours(1), signingCredentials: creds ); return new JwtSecurityTokenHandler().WriteToken(token); } public long VerifyToken(string token) { try { if (token.StartsWith("Bearer ")) { token = token.Substring("Bearer ".Length); } var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(jwtkey)); var tokenHandler = new JwtSecurityTokenHandler(); tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = key, ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true }, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; var userId = jwtToken.Claims.First(x => x.Type == JwtRegisteredClaimNames.Sub).Value; return long.Parse(userId); } catch { return -1; } } public async Task GenerateRefreshToken(long accountId) { var existingToken = await _db.refreshtables .FirstOrDefaultAsync(r => r.AccountId == accountId && r.ExpiryTime > DateTime.UtcNow); if (existingToken != null) { return existingToken.RefreshToken; } var expiredTokens = await _db.refreshtables .Where(r => r.AccountId == accountId) .ToListAsync(); _db.refreshtables.RemoveRange(expiredTokens); await _db.SaveChangesAsync(); var refreshToken = Convert.ToBase64String(System.Security.Cryptography.RandomNumberGenerator.GetBytes(64)); var refreshTokenRecord = new refreshtable { RefreshToken = refreshToken, ExpiryTime = DateTime.UtcNow.AddDays(7), AccountId = accountId }; _db.refreshtables.Add(refreshTokenRecord); await _db.SaveChangesAsync(); return refreshToken; } public async Task ValidateRefreshToken(string refreshToken) { var token = await _db.refreshtables .FirstOrDefaultAsync(r => r.RefreshToken == refreshToken); if (token == null || token.ExpiryTime < DateTime.UtcNow) return null; return token.AccountId; } public async Task RevokeRefreshToken(string refreshToken) { var token = await _db.refreshtables .FirstOrDefaultAsync(r => r.RefreshToken == refreshToken); if (token != null) { _db.refreshtables.Remove(token); await _db.SaveChangesAsync(); } } } }