using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Application.Interfaces; using Domain.Entities; using Domain.Interface; using Infrastructure.Utilities; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; namespace Application.Services; public class JwtService( IConfiguration configuration, IUserRepository userRepository, IUnitOfWork unitOfWork) : IJwtService { public async Task GenerateTokenAsync(User user) { var secretKey = configuration["Jwt:Key"]; var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey!)); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var roles = await userRepository.GetUserRolesByEmailAsync(user.Email); var claims = new List { new(ClaimTypes.Email, user.Email), new("UserId", user.Id.ToString()), new("username", user.Username) }; claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role))); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddDays(1), // set a token expiration time SigningCredentials = credentials, Issuer = configuration["Jwt:Issuer"], Audience = configuration["Jwt:Audience"] }; var tokenHandler = new JwtSecurityTokenHandler(); var securityToken = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(securityToken); } public async Task GenerateAndSaveRefreshTokenAsync(User user) { var refreshToken = GenerateRefreshTokenHelper.GenerateRefreshToken(); user.RefreshToken = refreshToken; user.RefreshTokenExpiryTime = DateTime.UtcNow.AddDays(5); userRepository.Update(user); await unitOfWork.CommitAsync(); return refreshToken; } public async Task ValidateRefreshTokenAsync(int userId, string refreshToken) { var user = await userRepository.GetUserByIdAsync(userId); if (user is null || user.RefreshToken != refreshToken || user.RefreshTokenExpiryTime <= DateTime.UtcNow) return null; return user; } }