Vikas Nale b93b581d60 Modify Email Templates
- Remove address and contact number
- Add link to email
- change twitter logo to x
- link x logo to company twitter account

Add new template to inform password change success
- add code to send email on password change success
2025-04-15 12:12:35 +00:00

243 lines
11 KiB
C#

using System.Net;
using Marco.Pms.DataAccess.Data;
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 MarcoBMS.Services.Helpers;
using MarcoBMS.Services.Service;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace MarcoBMS.Services.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
private readonly ApplicationDbContext _context;
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, ApplicationDbContext context, JwtSettings jwtSettings, RefreshTokenService refreshTokenService,
IEmailSender emailSender, IConfiguration configuration, EmployeeHelper employeeHelper)
{
_userManager = userManager;
_jwtSettings = jwtSettings;
_refreshTokenService = refreshTokenService;
_emailSender = emailSender;
_configuration = configuration;
_employeeHelper = employeeHelper;
_context = context;
}
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
{
var user = await _context.ApplicationUsers.FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username);
if (user != null && await _userManager.CheckPasswordAsync(user, loginDto.Password))
{
if (!user.IsActive)
{
return BadRequest(ApiResponse<object>.ErrorResponse("User is In Active", "User is In Active", 400));
}
if (!user.EmailConfirmed)
{
return BadRequest(ApiResponse<object>.ErrorResponse("Your email is not verified, Please verify your email", "Your email is not verified, Please verify your email", 400));
}
Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
//var refreshToken = GenerateRefreshToken();
if (user.UserName == null) return NotFound(ApiResponse<object>.ErrorResponse("UserName Not found", "UserName Not found", 404)); ;
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));
}
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid username or password.", "Invalid username or password.", 401));
}
[HttpPost("logout")]
public async Task<IActionResult> Logout([FromBody] LogoutDto logoutDto)
{
if (string.IsNullOrEmpty(logoutDto.RefreshToken))
{
return BadRequest(ApiResponse<object>.ErrorResponse("Refresh token is required", "Refresh token is required", 400));
}
try
{
// Revoke the refresh token
bool isRevoked = await _refreshTokenService.RevokeRefreshTokenAsync(logoutDto.RefreshToken);
if (!isRevoked)
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid or expired refresh token", "Invalid or expired refresh token", 401));
// 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(ApiResponse<object>.SuccessResponse(new { }, "Logged out successfully", 200));
}
catch (Exception ex)
{
// _logger.LogError(ex, "Error during logout");
return BadRequest(ApiResponse<object>.ErrorResponse("Internal server error", ex.Message, 500));
}
}
[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(ApiResponse<object>.ErrorResponse("Invalid or expired refresh token.", "Invalid or expired refresh token.", 401));
}
// 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(ApiResponse<object>.ErrorResponse("Invalid request.", "Invalid request.", 400));
Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
if (user.UserName == null) return NotFound(ApiResponse<object>.ErrorResponse("UserName Not found", "UserName Not found", 404));
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(ApiResponse<object>.ErrorResponse("User not found.", "User not found.", 404));
/* SEND USER REGISTRATION MAIL*/
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}";
if (user.Email == null) return NotFound(ApiResponse<object>.ErrorResponse("Email Not found", "Email Not found", 404));
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(ApiResponse<object>.ErrorResponse("Invalid request.", "Invalid request.", 400));
// 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(ApiResponse<object>.ErrorResponse("Invalid request.", "Invalid request.", 400));
token = model.Token;
}
else
{
token = WebUtility.UrlDecode(model.Token);
}
var result = await _userManager.ResetPasswordAsync(user, token, model.NewPassword);
if (!result.Succeeded)
{
var errors = result.Errors.Select(e => e.Description).ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Failed to Change password", errors, 400));
}
try
{
Employee emp = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id);
await _emailSender.SendResetPasswordSuccessEmail(user.Email, emp.FirstName + " " + emp.LastName);
}
catch (Exception ex) {
}
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 NotFound(ApiResponse<object>.ErrorResponse("User not found.", "User not found.", 404));
}
/* 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)}";
if (user.Email == null) return NotFound(ApiResponse<object>.ErrorResponse("Email Not found", "Email Not found", 404));
await _emailSender.SendResetPasswordEmail(user.Email, "", resetLink);
return Ok(ApiResponse<object>.SuccessResponse(new { }, "Password reset link sent.", 200));
}
}
}