2026-04-14 13:28:10 -03:00
|
|
|
using SIGCM2.Application.Abstractions;
|
|
|
|
|
using SIGCM2.Application.Abstractions.Persistence;
|
2026-04-16 13:59:27 -03:00
|
|
|
using SIGCM2.Application.Audit;
|
2026-04-14 13:28:10 -03:00
|
|
|
|
|
|
|
|
namespace SIGCM2.Application.Auth.Logout;
|
|
|
|
|
|
|
|
|
|
public sealed class LogoutCommandHandler : ICommandHandler<LogoutCommand, LogoutResponseDto>
|
|
|
|
|
{
|
|
|
|
|
private readonly IRefreshTokenRepository _refreshRepo;
|
2026-04-16 13:59:27 -03:00
|
|
|
private readonly ISecurityEventLogger _security;
|
2026-04-18 10:12:17 -03:00
|
|
|
private readonly TimeProvider _timeProvider;
|
2026-04-14 13:28:10 -03:00
|
|
|
|
2026-04-18 10:12:17 -03:00
|
|
|
public LogoutCommandHandler(
|
|
|
|
|
IRefreshTokenRepository refreshRepo,
|
|
|
|
|
ISecurityEventLogger security,
|
|
|
|
|
TimeProvider timeProvider)
|
2026-04-14 13:28:10 -03:00
|
|
|
{
|
|
|
|
|
_refreshRepo = refreshRepo;
|
2026-04-16 13:59:27 -03:00
|
|
|
_security = security;
|
2026-04-18 10:12:17 -03:00
|
|
|
_timeProvider = timeProvider;
|
2026-04-14 13:28:10 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<LogoutResponseDto> Handle(LogoutCommand command)
|
|
|
|
|
{
|
|
|
|
|
// Revoke all active tokens for the user across all families.
|
|
|
|
|
// Idempotent: 0 rows affected is not an error.
|
2026-04-18 10:12:17 -03:00
|
|
|
var now = _timeProvider.GetUtcNow().UtcDateTime;
|
|
|
|
|
await _refreshRepo.RevokeAllActiveForUserAsync(command.UsuarioId, now);
|
2026-04-16 13:59:27 -03:00
|
|
|
await _security.LogAsync("logout", "success", actorUserId: command.UsuarioId);
|
2026-04-14 13:28:10 -03:00
|
|
|
return new LogoutResponseDto(true, "Sesión cerrada correctamente");
|
|
|
|
|
}
|
|
|
|
|
}
|