feat: enhance OTP verification logic to support master code bypass and improve error handling
This commit is contained in:
+24
-16
@@ -26,26 +26,27 @@ public class VerifyOtpTokenCommandHandler : IRequestHandler<VerifyOtpTokenComman
|
||||
var purpose = request.Purpose?.ToLowerInvariant() ?? "login";
|
||||
var now = DateTime.Now;
|
||||
|
||||
var otpToken = await _context.OtpTokens
|
||||
.Where(x => x.Mobile == mobile && x.Purpose == purpose && !x.IsUsed && x.ExpiresAt > now)
|
||||
.OrderByDescending(x => x.Id)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (otpToken == null)
|
||||
return new VerifyOtpTokenResponseDto { Success = false, Message = "کد تایید منقضی شده یا وجود ندارد. لطفاً کد جدید دریافت کنید." };
|
||||
|
||||
// بررسی تعداد تلاش
|
||||
if (otpToken.Attempts >= MaxAttempts)
|
||||
return new VerifyOtpTokenResponseDto { Success = false, Message = "تعداد تلاشها زیاد است. لطفاً کد جدید دریافت کنید." };
|
||||
|
||||
// بررسی کد مستر (فقط برای لاگین)
|
||||
// ── بررسی کد مستر (فقط برای لاگین، بدون نیاز به OTP در DB) ──
|
||||
var masterCode = _cfg["Otp:MasterCode"];
|
||||
var isMasterCode = purpose == "login"
|
||||
&& !string.IsNullOrWhiteSpace(masterCode)
|
||||
&& request.Code == masterCode;
|
||||
|
||||
OtpToken? otpToken = null;
|
||||
if (!isMasterCode)
|
||||
{
|
||||
otpToken = await _context.OtpTokens
|
||||
.Where(x => x.Mobile == mobile && x.Purpose == purpose && !x.IsUsed && x.ExpiresAt > now)
|
||||
.OrderByDescending(x => x.Id)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (otpToken == null)
|
||||
return new VerifyOtpTokenResponseDto { Success = false, Message = "کد تایید منقضی شده یا وجود ندارد. لطفاً کد جدید دریافت کنید." };
|
||||
|
||||
// بررسی تعداد تلاش
|
||||
if (otpToken.Attempts >= MaxAttempts)
|
||||
return new VerifyOtpTokenResponseDto { Success = false, Message = "تعداد تلاشها زیاد است. لطفاً کد جدید دریافت کنید." };
|
||||
|
||||
otpToken.Attempts++;
|
||||
|
||||
// Verify using HMAC-SHA256
|
||||
@@ -73,9 +74,13 @@ public class VerifyOtpTokenCommandHandler : IRequestHandler<VerifyOtpTokenComman
|
||||
.Where(x => x.Mobile == mobile)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
// ── کاربر وجود ندارد → ثبتنام جدید ──
|
||||
// ── کاربر وجود ندارد → ثبتنام جدید (فقط برای OTP عادی) ──
|
||||
if (user == null)
|
||||
{
|
||||
// با کد مستر، ثبتنام جدید مجاز نیست
|
||||
if (isMasterCode)
|
||||
return new VerifyOtpTokenResponseDto { Success = false, Message = "کاربری با این شماره موبایل وجود ندارد." };
|
||||
|
||||
// کد معرف الزامی است
|
||||
if (string.IsNullOrWhiteSpace(request.ParentReferralCode))
|
||||
return new VerifyOtpTokenResponseDto { Success = false, Message = "کد معرف الزامی است." };
|
||||
@@ -156,8 +161,11 @@ public class VerifyOtpTokenCommandHandler : IRequestHandler<VerifyOtpTokenComman
|
||||
user.MobileVerifiedAt ??= now;
|
||||
}
|
||||
|
||||
// Mark OTP as used
|
||||
otpToken.IsUsed = true;
|
||||
// Mark OTP as used (only for non-master-code flows)
|
||||
if (otpToken != null)
|
||||
{
|
||||
otpToken.IsUsed = true;
|
||||
}
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// Generate JWT token
|
||||
|
||||
Reference in New Issue
Block a user