diff options
Diffstat (limited to 'api/WhatApi/Endpoints/LoginEndpoint.cs')
| -rw-r--r-- | api/WhatApi/Endpoints/LoginEndpoint.cs | 52 |
1 files changed, 52 insertions, 0 deletions
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<ActionResult> 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<string>(Constants.Env.TokenEntropy); + + ArgumentException.ThrowIfNullOrWhiteSpace(tokenEntropy); + + var key = Encoding.ASCII.GetBytes(tokenEntropy); + var tokenIssuer = configuration.GetValue<string>(Constants.Env.TokenIssuer); + var tokenAudience = configuration.GetValue<string>(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 |
