Add /api/auth/{register,login,logout,me} with first-user-is-admin rule

This commit is contained in:
2026-06-11 18:34:07 +00:00
parent 8a7d01ac9e
commit 2a208e81b2
3 changed files with 116 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace backend.Auth;
public record RegisterRequest(string Email, string Password);
public record LoginRequest(string Email, string Password);
public static class AuthEndpoints
{
public static IEndpointRouteBuilder MapAuthEndpoints(this IEndpointRouteBuilder app)
{
var grp = app.MapGroup("/api/auth");
grp.MapPost("/register", async (
[FromBody] RegisterRequest req,
UserManager<ApplicationUser> users,
RoleManager<IdentityRole<Guid>> roles) =>
{
var user = new ApplicationUser { UserName = req.Email, Email = req.Email };
var create = await users.CreateAsync(user, req.Password);
if (!create.Succeeded)
return Results.BadRequest(new { errors = create.Errors.Select(e => e.Description) });
var anyAdmin = await users.GetUsersInRoleAsync(Roles.Admin);
var role = anyAdmin.Count == 0 ? Roles.Admin : Roles.User;
await users.AddToRoleAsync(user, role);
return Results.Ok(new { id = user.Id, email = user.Email, role });
});
grp.MapPost("/login", async (
[FromBody] LoginRequest req,
SignInManager<ApplicationUser> signIn) =>
{
var res = await signIn.PasswordSignInAsync(req.Email, req.Password,
isPersistent: true, lockoutOnFailure: false);
return res.Succeeded ? Results.Ok() : Results.Unauthorized();
});
grp.MapPost("/logout", async (SignInManager<ApplicationUser> signIn) =>
{
await signIn.SignOutAsync();
return Results.Ok();
}).RequireAuthorization();
grp.MapGet("/me", async (
UserManager<ApplicationUser> users,
HttpContext http) =>
{
var user = await users.GetUserAsync(http.User);
if (user is null) return Results.Unauthorized();
var rolesList = await users.GetRolesAsync(user);
return Results.Ok(new
{
id = user.Id,
email = user.Email,
isAdmin = rolesList.Contains(Roles.Admin),
});
}).RequireAuthorization();
return app;
}
}