using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Project.Application.DTOs.Auth; using Project.Application.DTOs.TwoFactorAuth; using Project.Application.Interfaces; using System.Security.Claims; namespace Project.Web.Controllers { [ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { // FIELDS FOR CTOR private readonly IUserService _userService; private readonly IAuthService _authService; private readonly ITwoFactorAuthService _twoFactorAuthService; // CTOR public AuthController(IUserService userService, IAuthService authService, ITwoFactorAuthService twoFactorAuthService) { _userService = userService; _authService = authService; _twoFactorAuthService = twoFactorAuthService; } // LOGIN [AllowAnonymous] [HttpPost("login")] public async Task Login([FromBody] LoginDto loginDto) { // Validate login credentials bool isValid = await _authService.ValidateAsync(loginDto.Email, loginDto.Password); if (!isValid) { return Unauthorized(); } // Validate user var user = await _userService.GetByEmailAsync(loginDto.Email); if (user == null) { return Unauthorized(user); } // Check if 2FA is required var secretKey = await _twoFactorAuthService.GetSecretKeyAsync(loginDto.Email); if (!string.IsNullOrEmpty(secretKey)) { // Promt for 2FA return Ok(new { RequiresTwoFactor = true }); } // Create claims based on the user information var claims = new List { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Name, user.Email), new Claim(ClaimTypes.Surname, user.LastName ?? ""), new Claim(ClaimTypes.GivenName, user.FirstName ?? ""), new Claim(ClaimTypes.Role, user?.Role?.Name.ToString() ?? "") // role is important for authorization }; // Create a ClaimsIdentity based on the created claims var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); // Set the authentication properties var authProperties = new AuthenticationProperties { IsPersistent = true, AllowRefresh = true, ExpiresUtc = DateTime.UtcNow.AddMinutes(60) }; // Sign in user using cookie-based authentication await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties ); return Ok(); } [AllowAnonymous] [HttpPost("verify2fa")] public async Task Verify2Fa([FromBody] TwoFactorVerificationDto verifyDto) { var isValid = await _twoFactorAuthService.ValidateCodeAsync(verifyDto.Email, verifyDto.Code); if (!isValid) { return Unauthorized(); } var user = await _userService.GetByEmailAsync(verifyDto.Email); if (user == null) { return Unauthorized(); } var claims = new List { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Email, user.Email), new Claim(ClaimTypes.Surname, user.LastName ?? ""), new Claim(ClaimTypes.GivenName, user.FirstName ?? ""), new Claim(ClaimTypes.Role, user?.Role?.Name ?? "") }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var authProperties = new AuthenticationProperties { IsPersistent = true, AllowRefresh = true, ExpiresUtc = DateTime.UtcNow.AddMinutes(60) }; await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties ); return Ok(); } // LOGOUT [HttpPost("logout")] public async Task Logout() { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Ok(); } //// SETUP 2FA //[AllowAnonymous] //[HttpPost("setup-2fa")] //public async Task SetupTwoFactorAuth([FromBody] SetupTwoFactorDto setupDto) //{ // var result = await _twoFactorAuthService.GenerateSetupCodeAsync(setupDto.Email); // return Ok(result); //} } }