using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using Knot.Contracts.Auth.Application.Abstractions; using Knot.Contracts.Auth.Domain; using DomainUser = Knot.Modules.Auth.Domain.User; namespace Knot.Modules.Auth.Infrastructure.Authentication; internal sealed class JwtTokenProvider : IJwtTokenProvider { private readonly IConfiguration _configuration; public JwtTokenProvider(IConfiguration configuration) { _configuration = configuration; } public string GenerateAccessToken(Guid userId, string username) { var claims = new Claim[] { new(JwtRegisteredClaimNames.Sub, userId.ToString()), new(JwtRegisteredClaimNames.UniqueName, username), new(ClaimTypes.Name, username) }; var secretKey = _configuration["Jwt:Secret"]!; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( _configuration["Jwt:Issuer"], _configuration["Jwt:Audience"], claims, null, DateTime.UtcNow.AddMinutes(double.Parse(_configuration["Jwt:ExpiryInMinutes"] ?? "1440")), credentials); return new JwtSecurityTokenHandler().WriteToken(token); } public string GenerateRefreshToken() { var randomBytes = new byte[32]; using var rng = System.Security.Cryptography.RandomNumberGenerator.Create(); rng.GetBytes(randomBytes); return Convert.ToBase64String(randomBytes); } public DateTime GetRefreshTokenExpiry() { var expiryInDays = int.Parse(_configuration["Jwt:RefreshExpiryInDays"] ?? "30"); return DateTime.UtcNow.AddDays(expiryInDays); } public string Generate(Guid userId, string username, string displayName, string? avatar) { var claims = new Claim[] { new(JwtRegisteredClaimNames.Sub, userId.ToString()), new(JwtRegisteredClaimNames.UniqueName, username), new("name", displayName), new(ClaimTypes.Name, displayName), new("avatar", avatar ?? string.Empty) }; var secretKey = _configuration["Jwt:Secret"]!; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( _configuration["Jwt:Issuer"], _configuration["Jwt:Audience"], claims, null, DateTime.UtcNow.AddMinutes(double.Parse(_configuration["Jwt:ExpiryInMinutes"] ?? "1440")), credentials); return new JwtSecurityTokenHandler().WriteToken(token); } public string Generate(UserContract user) { return Generate(user.Id, user.Username, user.DisplayName, user.Avatar); } }