From cd70f54266d708867a1eb35870bc755bc5b2df32 Mon Sep 17 00:00:00 2001 From: ivar Date: Wed, 3 Dec 2025 21:49:20 +0100 Subject: Refactor db --- api/WhatApi/Endpoints/LoginEndpoint.cs | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 api/WhatApi/Endpoints/LoginEndpoint.cs (limited to 'api/WhatApi/Endpoints/LoginEndpoint.cs') diff --git a/api/WhatApi/Endpoints/LoginEndpoint.cs b/api/WhatApi/Endpoints/LoginEndpoint.cs new file mode 100644 index 0000000..ee697ef --- /dev/null +++ b/api/WhatApi/Endpoints/LoginEndpoint.cs @@ -0,0 +1,52 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Microsoft.AspNetCore.Identity; +using Microsoft.IdentityModel.Tokens; + +namespace WhatApi.Endpoints; + +public class LoginEndpoint(AppDatabase db, IConfiguration configuration) : BaseEndpoint +{ + public class LoginRequest + { + public required string Username { get; set; } + public required string Password { get; set; } + } + + [HttpPost("~/login")] + public async Task HandleAsync(LoginRequest login, CancellationToken ct = default) { + var user = await db.Users.FirstOrDefaultAsync(c => c.Name == login.Username, ct); + if (user?.PasswordHash is null) return Unauthorized(); + + var verificationResult = PasswordHasher.VerifyHashedPassword(user.PasswordHash, login.Password); + if (verificationResult == PasswordVerificationResult.Failed) return Unauthorized(); + + var tokenEntropy = configuration.GetValue(Constants.Env.TokenEntropy); + + ArgumentException.ThrowIfNullOrWhiteSpace(tokenEntropy); + + var key = Encoding.ASCII.GetBytes(tokenEntropy); + var tokenIssuer = configuration.GetValue(Constants.Env.TokenIssuer); + var tokenAudience = configuration.GetValue(Constants.Env.TokenAudience); + var tokenHandler = new JwtSecurityTokenHandler(); + + var tokenDescriptor = new SecurityTokenDescriptor { + Subject = new ClaimsIdentity([ + new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), + new Claim(ClaimTypes.Name, user.Name) + ]), + Expires = DateTime.UtcNow.AddMinutes(60), + Issuer = tokenIssuer, + Audience = tokenAudience, + SigningCredentials = new SigningCredentials( + new SymmetricSecurityKey(key), + SecurityAlgorithms.HmacSha256Signature) + }; + + var token = tokenHandler.CreateToken(tokenDescriptor); + var tokenString = tokenHandler.WriteToken(token); + user.SetLastSeen(); + await db.SaveChangesAsync(ct); + return Ok(tokenString); + } +} \ No newline at end of file -- cgit v1.3