using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Security.Cryptography; using System.Text; using Microsoft.IdentityModel.Tokens; using GestorFacturas.API.Models; using GestorFacturas.API.Data; using BCrypt.Net; namespace GestorFacturas.API.Services; public class AuthService { private readonly IConfiguration _config; private readonly ApplicationDbContext _context; public AuthService(IConfiguration config, ApplicationDbContext context) { _config = config; _context = context; } public bool VerificarPassword(string password, string hash) { try { return BCrypt.Net.BCrypt.Verify(password, hash); } catch { return false; } } public string GenerarHash(string password) { return BCrypt.Net.BCrypt.HashPassword(password); } // Generar JWT (Access Token) - Vida corta (ej. 15 min) public string GenerarAccessToken(Usuario usuario) { var keyStr = _config["Jwt:Key"] ?? throw new InvalidOperationException("Jwt:Key no configurada"); var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keyStr)); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var claims = new[] { new Claim(ClaimTypes.NameIdentifier, usuario.Id.ToString()), new Claim(ClaimTypes.Name, usuario.Username) }; var token = new JwtSecurityToken( _config["Jwt:Issuer"], _config["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddMinutes(15), signingCredentials: credentials); return new JwtSecurityTokenHandler().WriteToken(token); } // Generar Refresh Token - Vida larga (ej. 7 días) public RefreshToken GenerarRefreshToken(int usuarioId, bool isPersistent) { // Si es persistente: 30 días. // Si NO es persistente: 12 horas. var duracion = isPersistent ? TimeSpan.FromDays(30) : TimeSpan.FromHours(12); var refreshToken = new RefreshToken { Token = Convert.ToBase64String(RandomNumberGenerator.GetBytes(64)), Expires = DateTime.UtcNow.Add(duracion), Created = DateTime.UtcNow, UsuarioId = usuarioId, IsPersistent = isPersistent }; return refreshToken; } }