using Femto.Api.Auth; using Femto.Api.Sessions; using Femto.Common; using Femto.Modules.Auth.Application; using Femto.Modules.Auth.Application.Dto; using Femto.Modules.Auth.Application.Interface.CreateSignupCode; using Femto.Modules.Auth.Application.Interface.GetSignupCodesQuery; using Femto.Modules.Auth.Application.Interface.Login; using Femto.Modules.Auth.Application.Interface.RefreshUserSession; using Femto.Modules.Auth.Application.Interface.Register; using Femto.Modules.Auth.Contracts; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; namespace Femto.Api.Controllers.Auth; [ApiController] [Route("auth")] public class AuthController( IAuthModule authModule, IOptions cookieSettings, ICurrentUserContext currentUserContext, ILogger logger ) : ControllerBase { [HttpPost("login")] public async Task> Login([FromBody] LoginRequest request) { var result = await authModule.Command(new LoginCommand(request.Username, request.Password)); HttpContext.SetSession(result.SessionDto, result.User, logger); return new LoginResponse( result.User.Id, result.User.Username, result.User.Roles.Any(r => r == Role.SuperUser) ); } [HttpPost("register")] public async Task> Register([FromBody] RegisterRequest request) { var result = await authModule.Command( new RegisterCommand(request.Username, request.Password, request.SignupCode) ); HttpContext.SetSession(result.SessionDto, result.User, logger); return new RegisterResponse( result.User.Id, result.User.Username, result.User.Roles.Any(r => r == Role.SuperUser) ); } [HttpDelete("session")] public async Task DeleteSession() { var currentUser = currentUserContext.CurrentUser; if (currentUser != null) await authModule.Command(new DeauthenticateCommand(currentUser.Id, currentUser.SessionId, currentUser.RememberMeToken)); HttpContext.DeleteSession(); return Ok(new { }); } [HttpGet("user/{userId}")] [Authorize] public async Task> RefreshUser( Guid userId, CancellationToken cancellationToken ) { var currentUser = currentUserContext.CurrentUser!; try { var result = await authModule.Command( new RefreshUserCommand(userId, currentUser), cancellationToken ); return new RefreshUserResult( result.User.Id, result.User.Username, result.User.Roles.Any(r => r == Role.SuperUser) ); } catch (Exception) { HttpContext.DeleteSession(); return this.Forbid(); } } [HttpPost("signup-codes")] [Authorize(Roles = "SuperUser")] public async Task CreateSignupCode( [FromBody] CreateSignupCodeRequest request, CancellationToken cancellationToken ) { await authModule.Command( new CreateSignupCodeCommand(request.Code, request.Email, request.Name), cancellationToken ); return Ok(new { }); } [HttpGet("signup-codes")] [Authorize(Roles = "SuperUser")] public async Task> ListSignupCodes( CancellationToken cancellationToken ) { var codes = await authModule.Query(new GetSignupCodesQuery(), cancellationToken); return new ListSignupCodesResult( codes.Select(c => new SignupCodeDto( c.Code, c.Email, c.Name, c.RedeemedByUserId, c.RedeemedByUsername, c.ExpiresOn )) ); } }