0052725b88
- Created UserViewSheet component to display user details including username, full name, role, status, and timestamps. - Created RoleViewSheet component to display role details including name, level, status, creation date, and associated permissions. - Introduced permissions configuration in a new permissions.ts file, defining categories and permission codes for better management. - Implemented middleware for authentication, ensuring access control for protected routes.
101 lines
3.4 KiB
C#
101 lines
3.4 KiB
C#
using System.IdentityModel.Tokens.Jwt;
|
|
using Distribution.Features.User;
|
|
using Distribution.Infra.Authorization;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace Distribution.Features.Auth;
|
|
|
|
[ApiController]
|
|
[Route("api/auth")]
|
|
public class AuthController(AuthService service, ICurrentUserService currentUser, IUserRepository userRepo) : ControllerBase
|
|
{
|
|
private static IActionResult ToActionResult(AuthHexResponse result) =>
|
|
result.Success ? new OkObjectResult(result) : new ObjectResult(result) { StatusCode = result.StatusCode is >= 400 and < 600 ? result.StatusCode : 401 };
|
|
|
|
[HttpPost("login")]
|
|
[AllowAnonymous]
|
|
public async Task<IActionResult> Login(LoginRequest request, CancellationToken ct)
|
|
{
|
|
var result = await service.LoginAsync(request, ct);
|
|
|
|
if (!result.Success || result.Data is not { } data)
|
|
return ToActionResult(result);
|
|
|
|
string? token = null;
|
|
TimeSpan maxAge = TimeSpan.FromHours(1);
|
|
|
|
if (data.TryGetProperty("accessToken", out var tokenEl))
|
|
token = tokenEl.GetString();
|
|
|
|
if (data.TryGetProperty("expiresIn", out var expEl))
|
|
maxAge = TimeSpan.FromSeconds(expEl.GetInt32());
|
|
|
|
if (!string.IsNullOrEmpty(token))
|
|
{
|
|
Response.Cookies.Append("access-token", token, new CookieOptions
|
|
{
|
|
HttpOnly = true,
|
|
SameSite = SameSiteMode.Lax,
|
|
Path = "/",
|
|
MaxAge = maxAge,
|
|
Secure = Request.IsHttps,
|
|
});
|
|
}
|
|
|
|
MeResponse? profile = null;
|
|
if (!string.IsNullOrEmpty(token))
|
|
{
|
|
var jwt = new JwtSecurityTokenHandler().ReadJwtToken(token);
|
|
var userIdStr = jwt.Claims.FirstOrDefault(c => c.Type == "UserId")?.Value;
|
|
if (Guid.TryParse(userIdStr, out var userId))
|
|
{
|
|
var user = await userRepo.GetByIdAsync(userId);
|
|
if (user is not null)
|
|
profile = new MeResponse(
|
|
user.Id,
|
|
user.Username,
|
|
user.FK_RoleId,
|
|
user.Role?.Name ?? string.Empty,
|
|
user.Role?.Level ?? 0);
|
|
}
|
|
}
|
|
|
|
return Ok(new { result.StatusCode, result.Success, result.Message, result.Data, profile });
|
|
}
|
|
|
|
[HttpPost("register")]
|
|
[AllowAnonymous]
|
|
public async Task<IActionResult> Register(RegisterRequest request, CancellationToken ct) =>
|
|
ToActionResult(await service.RegisterAsync(request, ct));
|
|
|
|
[HttpGet("me")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Me()
|
|
{
|
|
if (currentUser.UserId is null) return Unauthorized();
|
|
var user = await userRepo.GetByIdAsync(currentUser.UserId.Value);
|
|
if (user is null) return Unauthorized();
|
|
return Ok(new MeResponse(
|
|
user.Id,
|
|
user.Username,
|
|
user.FK_RoleId,
|
|
user.Role?.Name ?? string.Empty,
|
|
user.Role?.Level ?? 0));
|
|
}
|
|
|
|
[HttpPost("logout")]
|
|
[AllowAnonymous]
|
|
public IActionResult Logout()
|
|
{
|
|
Response.Cookies.Delete("access-token", new CookieOptions
|
|
{
|
|
HttpOnly = true,
|
|
SameSite = SameSiteMode.Lax,
|
|
Path = "/",
|
|
Secure = Request.IsHttps,
|
|
});
|
|
return Ok(new { success = true });
|
|
}
|
|
}
|