Compare commits
No commits in common. "2fc44ec4996d8056c597a0e972f94e0c025b27b1" and "baa168ff8f3c403d10606f961c1faa2e4d5f31e4" have entirely different histories.
2fc44ec499
...
baa168ff8f
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Marco.Pms.DataAccess.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class Added_IsUsed_FLag_In_OTPDetails_Table : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "IsUsed",
|
|
||||||
table: "OTPDetails",
|
|
||||||
type: "tinyint(1)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "IsUsed",
|
|
||||||
table: "OTPDetails");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -268,9 +268,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
b.Property<int>("ExpriesInSec")
|
b.Property<int>("ExpriesInSec")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<bool>("IsUsed")
|
|
||||||
.HasColumnType("tinyint(1)");
|
|
||||||
|
|
||||||
b.Property<string>("OTP")
|
b.Property<string>("OTP")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
|
|||||||
@ -8,7 +8,6 @@ namespace Marco.Pms.Model.Authentication
|
|||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
public string OTP { get; set; } = string.Empty;
|
public string OTP { get; set; } = string.Empty;
|
||||||
public int ExpriesInSec { get; set; }
|
public int ExpriesInSec { get; set; }
|
||||||
public bool IsUsed { get; set; } = false;
|
|
||||||
public DateTime TimeStamp { get; set; }
|
public DateTime TimeStamp { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
namespace Marco.Pms.Model.Dtos.Authentication
|
|
||||||
{
|
|
||||||
public class VerifyOTPDto
|
|
||||||
{
|
|
||||||
public string? Email { get; set; }
|
|
||||||
public string? OPT { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -349,97 +349,6 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("login-opt")]
|
|
||||||
public async Task<IActionResult> LoginWithOTP([FromBody] VerifyOTPDto verifyOTP)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Validate input
|
|
||||||
if (string.IsNullOrWhiteSpace(verifyOTP.Email) ||
|
|
||||||
string.IsNullOrWhiteSpace(verifyOTP.OPT) ||
|
|
||||||
verifyOTP.OPT.Length != 4 ||
|
|
||||||
!verifyOTP.OPT.All(char.IsDigit))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("OTP login failed - invalid input provided");
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid input", "Please provide a valid 4-digit OTP and Email", 400));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch employee by email
|
|
||||||
var requestEmployee = await _context.Employees
|
|
||||||
.Include(e => e.ApplicationUser)
|
|
||||||
.FirstOrDefaultAsync(e => e.Email == verifyOTP.Email && e.IsActive);
|
|
||||||
|
|
||||||
if (requestEmployee == null || string.IsNullOrWhiteSpace(requestEmployee.ApplicationUserId))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("OTP login failed - user not found for email {Email}", verifyOTP.Email);
|
|
||||||
return NotFound(ApiResponse<object>.ErrorResponse("User not found", "User not found", 404));
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid userId = Guid.Parse(requestEmployee.ApplicationUserId);
|
|
||||||
|
|
||||||
// Fetch most recent OTP
|
|
||||||
var otpDetails = await _context.OTPDetails
|
|
||||||
.Where(o => o.UserId == userId && o.TenantId == requestEmployee.TenantId)
|
|
||||||
.OrderByDescending(o => o.TimeStamp)
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
if (otpDetails == null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("OTP login failed - no OTP found for user {UserId}", userId);
|
|
||||||
return NotFound(ApiResponse<object>.ErrorResponse("OTP not found", "No OTP was generated for this user", 404));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate OTP expiration
|
|
||||||
var validUntil = otpDetails.TimeStamp.AddSeconds(otpDetails.ExpriesInSec);
|
|
||||||
if (DateTime.UtcNow > validUntil || otpDetails.IsUsed)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("OTP login failed - OTP expired for user {UserId}", userId);
|
|
||||||
return BadRequest(ApiResponse<object>.ErrorResponse("OTP expired", "The OTP has expired, please request a new one", 400));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match OTP
|
|
||||||
if (otpDetails.OTP != verifyOTP.OPT)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("OTP login failed - incorrect OTP entered for user {UserId}", userId);
|
|
||||||
return Unauthorized(ApiResponse<object>.ErrorResponse("Invalid OTP", "OTP did not match", 401));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate access and refresh tokens
|
|
||||||
var accessToken = _refreshTokenService.GenerateJwtToken(
|
|
||||||
requestEmployee.ApplicationUser?.UserName,
|
|
||||||
requestEmployee.TenantId,
|
|
||||||
_jwtSettings
|
|
||||||
);
|
|
||||||
|
|
||||||
var refreshToken = await _refreshTokenService.CreateRefreshToken(
|
|
||||||
requestEmployee.ApplicationUserId,
|
|
||||||
requestEmployee.TenantId.ToString(),
|
|
||||||
_jwtSettings
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fetch MPIN token if exists
|
|
||||||
var mpinDetails = await _context.MPINDetails
|
|
||||||
.FirstOrDefaultAsync(p => p.UserId == userId && p.TenantId == requestEmployee.TenantId);
|
|
||||||
|
|
||||||
// Build and return response
|
|
||||||
var response = new
|
|
||||||
{
|
|
||||||
token = accessToken,
|
|
||||||
refreshToken,
|
|
||||||
mpinToken = mpinDetails?.MPINToken
|
|
||||||
};
|
|
||||||
otpDetails.IsUsed = true;
|
|
||||||
await _context.SaveChangesAsync();
|
|
||||||
_logger.LogInfo("OTP login successful for employee {EmployeeId}", requestEmployee.Id);
|
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(response, "User logged in successfully.", 200));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError("An unexpected error occurred during OTP login for email {Email} : {Error}", verifyOTP.Email ?? string.Empty, ex.Message);
|
|
||||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Unexpected error", ex.Message, 500));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("sendmail")]
|
[HttpPost("sendmail")]
|
||||||
public async Task<IActionResult> SendEmail([FromBody] EmailDot emailDot)
|
public async Task<IActionResult> SendEmail([FromBody] EmailDot emailDot)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user