229 lines
9.3 KiB
C#
229 lines
9.3 KiB
C#
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<IdentityUser> _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<IdentityUser> 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<IActionResult> 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<object>.SuccessResponse(new { token = token, refreshToken = refreshToken }, "User logged in successfully.", 200));
|
|
}
|
|
|
|
[HttpPost("logout")]
|
|
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<object>.SuccessResponse(new { token = newJwtToken, refreshToken = newRefreshToken }, "User refresh token generated successfully.", 200));
|
|
}
|
|
|
|
[HttpPost("forgot-password")]
|
|
public async Task<IActionResult> 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<object>.SuccessResponse(true, "Password reset link sent.", 200));
|
|
}
|
|
|
|
[HttpPost("reset-password")]
|
|
public async Task<IActionResult> 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<ApplicationUser>.ResetPasswordTokenPurpose, model.ResetCode);
|
|
var isTokenValid = await _userManager.VerifyUserTokenAsync(
|
|
user,
|
|
TokenOptions.DefaultProvider, // This is the token provider
|
|
UserManager<ApplicationUser>.ResetPasswordTokenPurpose,
|
|
WebUtility.UrlDecode( model.Token)
|
|
);
|
|
string token = "";
|
|
|
|
if (!isTokenValid)
|
|
{
|
|
var isDecodedTokenValid = await _userManager.VerifyUserTokenAsync(
|
|
user,
|
|
TokenOptions.DefaultProvider, // This is the token provider
|
|
UserManager<ApplicationUser>.ResetPasswordTokenPurpose,
|
|
model.Token
|
|
);
|
|
if(!isDecodedTokenValid)
|
|
return BadRequest("Invalid or expired token.");
|
|
|
|
token = model.Token;
|
|
}
|
|
else
|
|
{
|
|
token = WebUtility.UrlDecode(model.Token);
|
|
}
|
|
|
|
|
|
var result = await _userManager.ResetPasswordAsync(user, token, model.NewPassword);
|
|
if (!result.Succeeded)
|
|
return BadRequest(result.Errors);
|
|
|
|
return Ok(ApiResponse<object>.SuccessResponse(result.Succeeded, "Password reset successfully.", 200));
|
|
}
|
|
|
|
|
|
|
|
[HttpPost("sendmail")]
|
|
public async Task<IActionResult> 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.");
|
|
}
|
|
}
|
|
}
|