using Femto.Api.Auth; using Femto.Api.Sessions; using Femto.Common; using Femto.Modules.Auth.Application.Interface.CreateSignupCode; using Femto.Modules.Auth.Application.Interface.GetSignupCodesQuery; using Femto.Modules.Auth.Application.Interface.Register; using Femto.Modules.Auth.Application.Services; 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, IAuthService authService ) : ControllerBase { [HttpPost("login")] public async Task> Login( [FromBody] LoginRequest request, CancellationToken cancellationToken ) { var user = await authService.GetUserWithCredentials( request.Username, request.Password, cancellationToken ); if (user is null) return Forbid(); var session = await authService.CreateStrongSession(user.Id); HttpContext.SetSession(session, user); return new LoginResponse(user.Id, user.Username, user.Roles.Any(r => r == Role.SuperUser)); } [HttpPost("register")] public async Task> Register([FromBody] RegisterRequest request) { var user = await authModule.Command( new RegisterCommand(request.Username, request.Password, request.SignupCode) ); var session = await authService.CreateStrongSession(user.Id); HttpContext.SetSession(session, user); return new RegisterResponse( user.Id, user.Username, user.Roles.Any(r => r == Role.SuperUser) ); } [HttpDelete("session")] public async Task DeleteSession() { var sessionId = HttpContext.GetSessionId(); if (sessionId is not null) { await authService.DeleteSession(sessionId); HttpContext.DeleteSession(); } return Ok(new { }); } [HttpGet("user/{userId}")] [Authorize] public async Task> GetUserInfo( Guid userId, CancellationToken cancellationToken ) { var currentUser = currentUserContext.CurrentUser; if (currentUser is null || currentUser.Id != userId) return this.BadRequest(); var user = await authService.GetUserWithId(userId, cancellationToken); if (user is null) return this.BadRequest(); return new GetUserInfoResult( user.Id, user.Username, user.Roles.Any(r => r == Role.SuperUser) ); } [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 )) ); } }