using Marco.Pms.Model.Authentication; using Marco.Pms.Model.Dtos; using Marco.Pms.Model.Dtos.Util; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Employee; using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.Data; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Net; namespace MarcoBMS.Services.Controllers { [ApiController] [Route("api/[controller]")] public class AuthController : ControllerBase { private readonly UserManager _userManager; private readonly JwtSettings _jwtSettings; private readonly RefreshTokenService _refreshTokenService; private readonly IEmailSender _emailSender; private readonly IConfiguration _configuration; private readonly EmployeeHelper _employeeHelper; //string tenentId = "1"; public AuthController(UserManager userManager, JwtSettings jwtSettings, RefreshTokenService refreshTokenService, IEmailSender emailSender, IConfiguration configuration, EmployeeHelper employeeHelper) { _userManager = userManager; _jwtSettings = jwtSettings; _refreshTokenService = refreshTokenService; _emailSender = emailSender; _configuration = configuration; _employeeHelper = employeeHelper; } [HttpPost("login")] public async Task Login([FromBody] LoginDto loginDto) { var user = await _userManager.FindByEmailAsync(loginDto.Username); var user1 = await _userManager.Users.FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username); if (user == null || !await _userManager.CheckPasswordAsync(user, loginDto.Password)) { return Unauthorized("Invalid username or password."); } Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id); //var refreshToken = GenerateRefreshToken(); var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId.ToString(), _jwtSettings); var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings); return Ok(ApiResponse.SuccessResponse(new { token = token, refreshToken = refreshToken }, "User logged in successfully.", 200)); } [HttpPost("logout")] public async Task Logout([FromBody] LogoutDto logoutDto) { if (string.IsNullOrEmpty(logoutDto.RefreshToken)) { return BadRequest(new { Message = "Refresh token is required" }); } try { // Revoke the refresh token bool isRevoked = await _refreshTokenService.RevokeRefreshTokenAsync(logoutDto.RefreshToken); if (!isRevoked) return Unauthorized(new { Message = "Invalid or expired refresh token" }); // Optional: Blacklist the access token (JWT) string jwtToken = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", ""); if (!string.IsNullOrEmpty(jwtToken)) { await _refreshTokenService.BlacklistJwtTokenAsync(jwtToken); } return Ok(new { Message = "Logged out successfully" }); } catch (Exception ex) { // _logger.LogError(ex, "Error during logout"); return StatusCode(500, new { Message = "Internal server error" }); } } [HttpPost("register")] public async Task Register([FromBody] RegisterDto registerDto) { var user = new IdentityUser { UserName = registerDto.Username, Email = registerDto.Email }; var result = await _userManager.CreateAsync(user, registerDto.Password); if (!result.Succeeded) { return BadRequest(result.Errors); } return Ok("User registered successfully."); } [HttpPost("refresh-token")] public async Task RefreshToken([FromBody] RefreshTokenDto refreshTokenDto) { var refreshToken = await _refreshTokenService.GetRefreshToken(refreshTokenDto.RefreshToken); if (refreshToken == null || refreshToken.ExpiryDate < DateTime.UtcNow) { return Unauthorized("Invalid or expired refresh token."); } // Mark token as used await _refreshTokenService.MarkRefreshTokenAsUsed(refreshToken); // Generate new JWT token and refresh token var user = await _userManager.FindByIdAsync(refreshToken.UserId); if (user == null) return BadRequest("Invalid request."); Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id); var newJwtToken = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId.ToString(), _jwtSettings); var newRefreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), _jwtSettings); return Ok(ApiResponse.SuccessResponse(new { token = newJwtToken, refreshToken = newRefreshToken }, "User refresh token generated successfully.", 200)); } [HttpPost("forgot-password")] public async Task ForgotPassword([FromBody] ForgotPasswordDto forgotPasswordDto) { var user = await _userManager.FindByEmailAsync(forgotPasswordDto.Email); if (user == null) return NotFound("User not found."); /* SEND USER REGISTRATION MAIL*/ var token = await _userManager.GeneratePasswordResetTokenAsync(user); var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink); return Ok(ApiResponse.SuccessResponse(true, "Password reset link sent.", 200)); } [HttpPost("reset-password")] public async Task ResetPassword([FromBody] ResetPasswordDto model) { var user = await _userManager.FindByEmailAsync(model.Email); if (user == null) return BadRequest("Invalid request."); // var isTokenValid = await _userManager.VerifyUserTokenAsync(user,UserManager.ResetPasswordTokenPurpose, model.ResetCode); var isTokenValid = await _userManager.VerifyUserTokenAsync( user, TokenOptions.DefaultProvider, // This is the token provider UserManager.ResetPasswordTokenPurpose, WebUtility.UrlDecode( model.Token) ); if (!isTokenValid) return BadRequest("Invalid or expired token."); var result = await _userManager.ResetPasswordAsync(user, WebUtility.UrlDecode(model.Token), model.NewPassword); if (!result.Succeeded) return BadRequest(result.Errors); return Ok(ApiResponse.SuccessResponse(result.Succeeded, "Password reset successfully.", 200)); } [HttpPost("sendmail")] public async Task SendEmail([FromBody] EmailDot emailDot) { var user = await _userManager.FindByEmailAsync(emailDot.ToEmail); if (user == null) { return BadRequest("User not found."); } /* New User*/ //var token = await _userManager.GeneratePasswordResetTokenAsync(user); //var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; //await _emailSender.SendResetPasswordEmailOnRegister(emailDot.ToEmail, "Vikas", resetLink); /* Forget password*/ // var token = await _userManager.GeneratePasswordResetTokenAsync(user); var token = await _userManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword"); var isTokenValid = await _userManager.VerifyUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword", token); var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink); return Ok("Password reset link sent."); } } }