From 68aca1d82396aa4c17c33e5db50e23a9f6957b89 Mon Sep 17 00:00:00 2001 From: Goran Date: Tue, 20 Jan 2026 19:05:17 +0100 Subject: [PATCH] login & logout --- Endpoints/UserAccess.cs | 81 ++++++++++++++++++++++++++++++++++----- Helpers/PasswordHelper.cs | 16 ++++++++ 2 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 Helpers/PasswordHelper.cs diff --git a/Endpoints/UserAccess.cs b/Endpoints/UserAccess.cs index 02f0878..82cb57f 100644 --- a/Endpoints/UserAccess.cs +++ b/Endpoints/UserAccess.cs @@ -1,5 +1,12 @@ -using Microsoft.AspNetCore.Builder; +using Emberend.Database; +using Emberend.Helpers; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using System.Security.Claims; +using System.Text.Json; namespace Emberend.Endpoints; @@ -7,27 +14,83 @@ public static class UserAccess { public static void MapUserAccessEndpoints(this IEndpointRouteBuilder routes) { - MapGetLogin(routes); + MapPostLogin(routes); + MapPostRegister(routes); + MapPostLogout(routes); + + MapGetUserById(routes); - MapGetRegister(routes); } - private static void MapGetLogin(IEndpointRouteBuilder routes) + private static void MapPostLogin(IEndpointRouteBuilder routes) { - routes.MapGet("/login", async context => + routes.MapPost("/login", async (LoginDto dto, AppDbContext db, HttpContext context) => { - await context.Response.WriteAsync("/login"); + var user = await db.Users + .AsNoTracking() + .FirstOrDefaultAsync(u => u.Email == dto.Email); + + if (user is null) + { + context.Response.StatusCode = 401; + await context.Response.WriteAsync(""); + return; + } + + var hash = PasswordHasher.Hash(dto.Password, user.Salt); + + + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, user.Id), + new Claim(ClaimTypes.Email, user.Email) + }; + + var identity = new ClaimsIdentity(claims, "auth"); + await context.SignInAsync("auth", new ClaimsPrincipal(identity)); + + + var loginResponse = new + { + user.Id, + user.Email, + user.Name, + user.ProfilePicture + }; + + context.Response.ContentType = "application/json"; + context.Response.StatusCode = 200; + + await context.Response.WriteAsync(JsonSerializer.Serialize(loginResponse)); + return; }); } - private static void MapGetRegister(IEndpointRouteBuilder routes) + private static void MapPostRegister(IEndpointRouteBuilder routes) { - routes.MapGet("/register", async context => + routes.MapPost("/logout", async (HttpContext context) => { - await context.Response.WriteAsync("/register"); + await context.SignOutAsync("auth"); + + context.Response.StatusCode = 200; + await context.Response.WriteAsync(""); }); } + + private static void MapPostLogout(IEndpointRouteBuilder routes) + { + routes.MapPost("/logout", async (HttpContext context) => + { + await context.SignOutAsync("auth"); + + context.Response.StatusCode = 200; + await context.Response.WriteAsync(""); + }); + } + + + private static void MapGetUserById(IEndpointRouteBuilder routes) { routes.MapGet("/user/{id}", async context => diff --git a/Helpers/PasswordHelper.cs b/Helpers/PasswordHelper.cs new file mode 100644 index 0000000..be9b803 --- /dev/null +++ b/Helpers/PasswordHelper.cs @@ -0,0 +1,16 @@ +using System.Security.Cryptography; +using System.Text; + +namespace Emberend.Helpers; + +static class PasswordHasher +{ + public static string Hash(string password, string salt) + { + var bytes = Encoding.UTF8.GetBytes(password + salt); + return Convert.ToHexString(SHA256.HashData(bytes)); + } + + public static string NewSalt() => + Convert.ToHexString(RandomNumberGenerator.GetBytes(16)); +}