From 8bbd2b6f2a49457414a3695885f573c4bc2b5997 Mon Sep 17 00:00:00 2001 From: dmolinari Date: Tue, 14 Apr 2026 13:28:16 -0300 Subject: [PATCH] feat(app): update LoginCommandHandler to persist hashed refresh token on login --- .../Persistence/IUsuarioRepository.cs | 1 + .../SIGCM2.Application/Auth/AuthOptions.cs | 12 +++++++ .../Auth/Login/LoginCommandHandler.cs | 31 ++++++++++++++++--- 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/api/SIGCM2.Application/Auth/AuthOptions.cs diff --git a/src/api/SIGCM2.Application/Abstractions/Persistence/IUsuarioRepository.cs b/src/api/SIGCM2.Application/Abstractions/Persistence/IUsuarioRepository.cs index 3167507..9d31a53 100644 --- a/src/api/SIGCM2.Application/Abstractions/Persistence/IUsuarioRepository.cs +++ b/src/api/SIGCM2.Application/Abstractions/Persistence/IUsuarioRepository.cs @@ -5,4 +5,5 @@ namespace SIGCM2.Application.Abstractions.Persistence; public interface IUsuarioRepository { Task GetByUsernameAsync(string username); + Task GetByIdAsync(int id, CancellationToken ct = default); } diff --git a/src/api/SIGCM2.Application/Auth/AuthOptions.cs b/src/api/SIGCM2.Application/Auth/AuthOptions.cs new file mode 100644 index 0000000..b6c0d59 --- /dev/null +++ b/src/api/SIGCM2.Application/Auth/AuthOptions.cs @@ -0,0 +1,12 @@ +namespace SIGCM2.Application.Auth; + +/// +/// Configuration values for authentication token generation. +/// Populated from the "Jwt" configuration section via IOptions in the Infrastructure layer. +/// Lives in Application to avoid circular dependency with Infrastructure. +/// +public sealed class AuthOptions +{ + public int AccessTokenMinutes { get; set; } = 60; + public int RefreshTokenDays { get; set; } = 7; +} diff --git a/src/api/SIGCM2.Application/Auth/Login/LoginCommandHandler.cs b/src/api/SIGCM2.Application/Auth/Login/LoginCommandHandler.cs index f584cea..a7f12c8 100644 --- a/src/api/SIGCM2.Application/Auth/Login/LoginCommandHandler.cs +++ b/src/api/SIGCM2.Application/Auth/Login/LoginCommandHandler.cs @@ -2,7 +2,9 @@ using System.Text.Json; using SIGCM2.Application.Abstractions; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Application.Abstractions.Security; +using SIGCM2.Domain.Entities; using SIGCM2.Domain.Exceptions; +using SIGCM2.Domain.Security; namespace SIGCM2.Application.Auth.Login; @@ -11,15 +13,27 @@ public sealed class LoginCommandHandler : ICommandHandler Handle(LoginCommand command) @@ -34,15 +48,24 @@ public sealed class LoginCommandHandler : ICommandHandler(usuario.PermisosJson) ?? Array.Empty(); return new LoginResponseDto( AccessToken: accessToken, - RefreshToken: refreshToken, - ExpiresIn: 3600, + RefreshToken: rawRefresh, // raw to client — never stored + ExpiresIn: _authOptions.AccessTokenMinutes * 60, Usuario: new UsuarioDto( Id: usuario.Id, Nombre: $"{usuario.Nombre} {usuario.Apellido}".Trim(),