Emberend/Endpoints/UserAccess.cs
2026-01-20 19:32:45 +01:00

173 lines
4.6 KiB
C#

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;
public static class UserAccess
{
public static void MapUserAccessEndpoints(this IEndpointRouteBuilder routes)
{
MapPostLogin(routes);
MapPostRegister(routes);
MapPostLogout(routes);
MapGetMe(routes);
MapGetUserById(routes);
}
private static void MapPostLogin(IEndpointRouteBuilder routes)
{
routes.MapPost("/login", async (LoginDto dto, AppDbContext db, HttpContext context) =>
{
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 MapPostRegister(IEndpointRouteBuilder routes)
{
routes.MapPost("/register", async (HttpContext context, RegisterDto dto, AppDbContext db) =>
{
if (dto.Password.Length < 6)
{
context.Response.StatusCode = 400;
return;
}
if (await db.Users.AsNoTracking().AnyAsync(u => u.Email == dto.Email))
{
context.Response.StatusCode = 409;
return;
}
var salt = PasswordHasher.NewSalt();
var hash = PasswordHasher.Hash(dto.Password, salt);
var user = new User
{
Id = Guid.NewGuid().ToString(),
Email = dto.Email,
Name = "",
PasswordHash = hash,
Salt = salt,
ProfilePicture = ""
};
db.Users.Add(user);
await db.SaveChangesAsync();
context.Response.ContentType = "application/json";
context.Response.StatusCode = 200;
return;
});
}
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 MapGetMe(IEndpointRouteBuilder routes)
{
routes.MapGet("/me", async (HttpContext context, ClaimsPrincipal user, AppDbContext db) =>
{
var id = user.FindFirstValue(ClaimTypes.NameIdentifier);
if (id is null)
{
context.Response.StatusCode = 401;
return;
}
var u = await db.Users
.AsNoTracking()
.Where(x => x.Id == id)
.Select(x => new PublicUserDto(
x.Id,
x.Email,
x.Name,
x.ProfilePicture
))
.FirstAsync();
context.Response.StatusCode = 200;
await context.Response.WriteAsync(JsonSerializer.Serialize(u));
}).RequireAuthorization();
}
private static void MapGetUserById(IEndpointRouteBuilder routes)
{
routes.MapGet("/user/{id}", async context =>
{
var id = context.Request.RouteValues["id"];
//Dodaj null check ^
await context.Response.WriteAsync($"User: {id}");
});
}
}
public sealed record PublicUserDto(
string Id,
string Name,
string Description,
string ProfilePicture
);