From 1aeae34f34e40758d60bc8a603ca2e80dbd46593 Mon Sep 17 00:00:00 2001 From: sanchezvem Date: Wed, 3 Dec 2025 11:48:03 +0100 Subject: [PATCH] added refresh endpoint and dto --- .../DTO/Refresh/Request/RefreshTokenDto.cs | 6 ++ .../DTO/Refresh/Response/GetRefreshDto.cs | 6 ++ .../Endpoints/Refresh/RefreshTokenEndpoint.cs | 63 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 ApiEfCoreLibrary/DTO/Refresh/Request/RefreshTokenDto.cs create mode 100644 ApiEfCoreLibrary/DTO/Refresh/Response/GetRefreshDto.cs create mode 100644 ApiEfCoreLibrary/Endpoints/Refresh/RefreshTokenEndpoint.cs diff --git a/ApiEfCoreLibrary/DTO/Refresh/Request/RefreshTokenDto.cs b/ApiEfCoreLibrary/DTO/Refresh/Request/RefreshTokenDto.cs new file mode 100644 index 0000000..6d6f061 --- /dev/null +++ b/ApiEfCoreLibrary/DTO/Refresh/Request/RefreshTokenDto.cs @@ -0,0 +1,6 @@ +namespace ApiEfCoreLibrary.DTO.Refresh.Request; + +public class RefreshTokenDto +{ + public string? Token { get; set; } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/DTO/Refresh/Response/GetRefreshDto.cs b/ApiEfCoreLibrary/DTO/Refresh/Response/GetRefreshDto.cs new file mode 100644 index 0000000..19e44ce --- /dev/null +++ b/ApiEfCoreLibrary/DTO/Refresh/Response/GetRefreshDto.cs @@ -0,0 +1,6 @@ +namespace ApiEfCoreLibrary.DTO.Refresh.Response; + +public class GetRefreshDto +{ + public string? Token { get; set; } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Endpoints/Refresh/RefreshTokenEndpoint.cs b/ApiEfCoreLibrary/Endpoints/Refresh/RefreshTokenEndpoint.cs new file mode 100644 index 0000000..4b7bfb6 --- /dev/null +++ b/ApiEfCoreLibrary/Endpoints/Refresh/RefreshTokenEndpoint.cs @@ -0,0 +1,63 @@ +using System.IdentityModel.Tokens.Jwt; +using ApiEfCoreLibrary.DTO.Login.Response; +using ApiEfCoreLibrary.DTO.Refresh.Request; +using ApiEfCoreLibrary.DTO.Refresh.Response; +using FastEndpoints; +using FastEndpoints.Security; +using Microsoft.EntityFrameworkCore; + +namespace ApiEfCoreLibrary.Endpoints.Refresh; + +public class RefreshTokenEndpoint(LibraryDbContext database) : Endpoint +{ + public override void Configure() + { + Post("/refresh"); + AllowAnonymous(); + } + + public override async Task HandleAsync(RefreshTokenDto req, CancellationToken ct) + { + try + { + JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); + var token = handler.ReadJwtToken(req.Token); + string? username = token.Claims.FirstOrDefault(c => c.Type == "Username")?.Value; + + if (string.IsNullOrWhiteSpace(username)) + { + await Send.UnauthorizedAsync(ct); + return; + } + + var login = await database.Logins.FirstOrDefaultAsync(x => x.Username == username, ct); + if (login == null) + { + await Send.UnauthorizedAsync(ct); + return; + } + + string jwtToken = JwtBearer.CreateToken( + o => + { + o.SigningKey = "ThisIsASuperSecretJwtKeyThatIsAtLeast32CharsLong"; + o.ExpireAt = DateTime.UtcNow.AddMinutes(15); + if (login.Role != null) o.User.Roles.Add(login.Role); + o.User.Claims.Add(("Username", login.Username)!); + o.User.Claims.Add(("FullName", login.FullName)!); + o.User["UserId"] = "001"; + }); + + GetRefreshDto responseDto = new() + { + Token = jwtToken + }; + + await Send.OkAsync(responseDto, ct); + } + catch + { + await Send.UnauthorizedAsync(ct); + } + } +} \ No newline at end of file