| # | Old Function / Logic | Old File | New Equivalent | Status | Gap Details |
| 1 | AUTHENTICATELOGIN: OTP verify via SP RESUME_AUTHENTICATE_USER_OTP_PASS (decrypts OTP, validates against DB) |
LoginRepository.cs:118-509 |
OtpVerificationService.VerifyOtpAsync() |
PRESENT |
New code validates OTP via Redis IOtpStore (plaintext comparison). Old code decrypted password then validated via SP. Equivalent business logic. |
| 2 | OTP max wrong attempts (ISMAXATTEMPT flag from SP) - returns MaximumLimitErrorMessage |
LoginRepository.cs:325,487 |
OtpVerificationService.HandleWrongOtpAsync() (MaxWrongAttempts=5) |
PRESENT |
Both enforce max wrong attempts and lock OTP. New code transitions to DROPPED state with DropCode; old code returned error message only. |
| 3 | OTP resend via GENERATEOTP: calls SEND_RESUME_OTP SP, SMS via SendSMS_To_Client |
LoginRepository.cs:1528-1608, LoginController.cs:521-558 |
OtpVerificationService.ResendOtpAsync() |
PRESENT |
Both support OTP resend with limits. New code: MaxResendCount=3, 30s cooldown. Old code delegated limit enforcement to SP. |
| 4 | Suspicious phone check via Usp_GetSuspiciousPhoneOrEMailId before GENERATEOTP |
LoginController.cs:536-548 |
Stage 1: RegistrationService.SignupAsync() blocks suspicious mobiles |
N/A — COVERED AT STAGE 1 |
Suspicious mobile check runs at Stage 1 signup and BLOCKS with MOBILE_SUSPICIOUS. Mobile cannot change between stages, so re-checking at OTP resend is redundant. No gap. |
| 5 | Dangerous string check (SQL injection blacklist) on UserId before AuthenticateLogin |
LoginController.cs:480-487, Validation.cs:92-118 |
EF Core parameterized queries + .NET model binding |
N/A — ARCHITECTURE CHANGE |
Old code manually checked for SQL keywords (truncate, script, drop). New code uses EF Core parameterized queries (no SQL injection possible) and ASP.NET model binding (no raw string inputs). XSS is handled by default output encoding. No gap. |
| 6 | Check_Direct_Offline_Client before OTP verify (branch offline client block) |
LoginRepository.cs:163-182 |
Stage 1: RegistrationService.SignupAsync() calls CheckOfflineClientAsync() |
N/A — COVERED AT STAGE 1 |
Offline client check runs at Stage 1 signup, before lead creation. A blocked offline client never reaches Stage 2. Re-checking at OTP verify is redundant. No gap. |
| 7 | Multiple user check (CHECK_MULTIPLE_USER_EXISTS) after OTP success |
LoginRepository.cs:402-414 |
Stage 1: RegistrationService.ArchiveOlderDuplicateLeadsAsync() |
N/A — COVERED AT STAGE 1 |
Multiple lead resolution runs at Stage 1 signup via CountActiveLeadsAsync + ArchiveOlderDuplicateLeadsAsync. Older duplicates are auto-archived before OTP. Old code showed a picker UI; new code auto-resolves. Different UX, same outcome. No gap. |
| 8 | PerformLogin: post-OTP session setup (JWT, segment check, email-on-login) |
LoginRepository.cs:545-610+ |
OtpVerificationService.HandleCorrectOtpAsync() + NotifyAgentOnLoginAsync() |
PRESENT |
JWT handled by ASP.NET auth middleware. Segment check is not needed (new code doesn't branch by segment at login). Agent email-on-login: FIXED via NotifyAgentOnLoginAsync (fire-and-forget, sends HTML email to RM + TL). Downstream events cover CLEVERTAP/ZOHO/CDP. |
| 9 | CallPanValidateAPIInBackground (Zintlr phone-to-PAN) after OTP success |
LoginRepository.cs:511-543 |
BackgroundCheckService.RunZintlrPhoneToPanAsync() |
PRESENT |
Both fire Zintlr lookup async after OTP verify. New code has full pipeline: Zintlr -> Hyperverge -> NSDL/UTI -> CVL KRA -> C-safe. Old code just called DIYPanValidate endpoint. |
| 10 | TrueCaller flow: istruecaller=1 bypasses OTP, logs via TRUECALLER_EKYC_LOG |
LoginRepository.cs:190-202, MobileAPI.cs |
N/A |
N/A — EXCLUDED |
TrueCaller integration not required per product decision. IsTrueCaller flag is stored on Lead for analytics but no OTP bypass. No gap. |
| 11 | OTP bypass for specific campaigns/channels via USP_INSERT_UPDATE_MOBILE_EMAIL_OTP_BYPASS_SJET |
LoginRepository.cs:2290-2304, SP: USP_INSERT_UPDATE_MOBILE_EMAIL_OTP_BYPASS_SJET |
DuplicateBypassWhitelist entity + BackOfficeCheckService.CheckBypassEligibilityAsync() |
PRESENT (different mechanism) |
Old code inserted bypass records for franchisee/branch users at email OTP. New code uses DuplicateBypassWhitelist table checked via CheckBypassEligibilityAsync at both Stage 1 (mobile dedupe) and Stage 3 (email dedupe). Different table name, same intent. Email OTP is also skipped for IIBL campaigns via HandlePartnerAutoVerifyAsync. |
| 12 | Max OTP generation limit per day via USP_VALIDATEMAXOTPLIMIT_SJET (>5 OTPs/mobile/day blocked) |
SP: USP_VALIDATEMAXOTPLIMIT_SJET |
OtpVerificationService (MaxDailyOtpGenerationsPerMobile=5) |
FIXED |
Daily OTP limit implemented: MaxDailyOtpGenerationsPerMobile=5. Counts OTP records for the lead today + current resend count. Blocks with “Daily OTP limit reached”. |
| 13 | SuperApp-specific OTP SMS template (SUPERAPPOTP, SUPERAPPOTP_RESUME_OTP) |
LoginRepository.cs:1560-1571 |
Stage 1: RegistrationService.SendOtpViaSmsAsync() + SmsTemplateService |
PRESENT |
Stage 1 RegistrationService checks lead.IsSuperApp and selects SUPERAPP_OTP template (vs SIGNUP_OTP). SmsTemplateService has both templates with distinct content (“Team MORISE” vs “MOFSL”). No gap. |
| 14 | NRI phone validation (allows + prefix) via chk_PhoneNo_NRI |
Validation.cs:243-291 |
Stage 1: RegistrationService.ValidateInput() with NriMobileRegex |
FIXED |
NRI phone validation implemented at Stage 1: NriMobileRegex (^\+?\d{7,15}$) allows international format with optional + prefix. Applied when command.IsNri is true. No gap. |
| 15 | Encrypted OTP comparison: OTP decrypted from password field before SP validation |
LoginRepository.cs:183 (Decrypt call) |
OtpVerificationService (plaintext compare via Redis) |
IMPROVED |
Old code accepted encrypted OTP in password field, decrypted server-side, then compared. New code stores OTP in Redis, compares plaintext. More secure (no OTP in transit as password). |
| 16 | Post-OTP Zoho lead creation (createLeadId_Zoho) for DIRECT non-NRI users |
LoginRepository.cs:226-317 |
OtpVerificationService.PublishOtpVerifiedDownstreamEventsAsync() — ZOHO_CRM target |
PRESENT (async event pattern) |
Old code called Zoho API synchronously with 40+ fields. New code publishes ZOHO_CRM downstream event with lead payload. The actual Zoho API call happens asynchronously via the downstream event processor. Different pattern (async vs sync), same outcome. LSQ is out of scope. |
| 17 | RM-assisted (BRBA) login: BranchEmpCode + AppLoginId determines IsBRBALogin flag |
LoginRepository.cs:149-156 |
Stage 1: RegistrationService (IsRmResumeBypass) + Stage 2: OtpVerificationService (bypasses OTP) |
PRESENT (improved) |
Old code set IsBRBALogin flag from BranchEmpCode. New code: RM resume detected at Stage 1 (Source=ZOHO_RM_RESUME or IsRmResume), sets IsRmResumeBypass on Lead, Stage 2 OTP verify detects the flag and skips OTP entirely. Cleaner and more explicit. |
| # | Old Function / Logic | Old File | New Equivalent | Status | Gap Details |
| 18 | IIBL customer email skip: ISUSER_IIBL_CUSTOMER check - if IIBL + email not modified, skip OTP entirely |
LoginRepository.cs:861-901 |
EmailVerificationService.HandlePartnerAutoVerifyAsync() for IIBL campaigns |
FIXED |
IIBL email auto-skip implemented: if lead.CampaignName is INDUSIND/IIBLMICROSITE/IIBL AND email domain is NOT @motilaloswal.com, auto-verifies via HandlePartnerAutoVerifyAsync without OTP. |
| 19 | Email regex validation (CALLEMAILREGEX flag from GET_EMAILVALIDATION_FLAG) |
LoginRepository.cs:912-927 |
EmailVerificationService.InitiateEmailVerificationAsync() (IsValidEmail extension) |
PRESENT |
Old code conditionally applies regex via CALLEMAILREGEX config flag. New code always validates via IsValidEmail() extension. Both use standard email regex. |
| 20 | Restricted email domain check via USP_RESTRICT_EMAIL_DOMAIN_SJET |
LoginRepository.cs:930-947, EmailAPI.cs:116-139 |
EmailVerificationService (RestrictedEmailDomain entity check) |
PRESENT |
Both check domain against restricted list. Old code calls SP via EmailAPI.CHECK_RESTRICTED_DOMAIN. New code queries RestrictedEmailDomain table via EF Core. |
| 21 | Allowed email domain whitelist via USP_ALLOW_EMAIL_SJET (skip extended validation for known domains) |
EmailAPI.cs:166-200 (inside KARZA_EMAIL_VALIDATION) |
EmailVerificationService (AllowedEmailDomain entity check) |
PRESENT |
Both have domain whitelist. Old code checked USP_ALLOW_EMAIL_SJET inside Karza validation. New code checks AllowedEmailDomain table and skips format + restricted checks if whitelisted. |
| 22 | Real-time email validation via Cybridge API (REALTIME_EMAIL_VALIDATION) |
LoginRepository.cs:966-972, EmailAPI.cs:371+ |
N/A |
N/A — EXCLUDED |
Cybridge email validation not required per product decision. Email quality is enforced via format check + restricted domain list + suspicious contact block. |
| 23 | Karza email validation API (KARZA_EMAIL_VALIDATION) - checks disposable/webmail/SMTP/MX |
LoginRepository.cs:973-979, EmailAPI.cs:166-267 |
N/A |
N/A — EXCLUDED |
Karza email validation not required per product decision. Disposable domains handled by restricted_email_domains table. |
| 24 | Custom email validation (USP_CUSTOM_EMAIL_VALIDATION_SJET) - forbidden patterns, domain-starts-with-digit |
EmailAPI.cs:52-82, SP: USP_CUSTOM_EMAIL_VALIDATION_SJET |
EmailVerificationService.ValidateEmailFormat() |
PRESENT |
Both reject notprovided/noemail/xyz patterns, multiple @, domain starts with digit. New code implements in C# method. Old code implemented in SP. Equivalent logic. |
| 25 | Email dedupe against back-office (USP_BYPASS_MOBILE_EMAIL_PAN_SJET for existing client email) |
LoginRepository.cs:1006-1016, 2062-2072 |
EmailVerificationService (emailDuplicate check + BackOfficeCheckService.CheckBypassEligibilityAsync) |
PRESENT |
Both check for duplicate emails and allow bypass for INACTIVE/PMS/OWNER_BRANCH/WHITELIST. New code checks against post-eSign leads. Equivalent. |
| 26 | Suspicious email check via Usp_GetSuspiciousPhoneOrEMailId |
LoginController.cs:331-351 (GENERATEEMAILOTP), LoginRepository.cs:1939-1956 (ValidateOTPEmail) |
EmailVerificationService — now BLOCKS with EMAIL_SUSPICIOUS |
FIXED |
Suspicious email check now BLOCKS (returns EMAIL_SUSPICIOUS error) matching old code behavior. Changed from log-only to hard block. |
| 27 | Email OTP send+verify flow (USP_SEND_RESUME_EMAILOTP_SJET, USP_VALIDATE_UPDATE_OTP_EMAIL_SJET) |
LoginRepository.cs:1017-1094, 2074-2086 |
EmailVerificationService.HandleManualOtpInitiationAsync() + VerifyEmailOtpAsync() |
PRESENT |
Both generate email OTP, store, send via email service, and validate. New code uses Redis for OTP storage. Equivalent flow. |
| 28 | Email template selection (BA_EMAILOTP / BRANCH_EMAILOTP / DIRECT_EMAILOTP based on ApplicationType) |
LoginRepository.cs:1049-1060 |
EmailVerificationService.SendEmailOtpAsync() → INotificationService |
PARTIAL — OK FOR NOW |
Old code selected email template by ApplicationType (PP/CRM/DIRECT). New code delegates to INotificationService which uses a single OTP email template. Template per ApplicationType can be added to the notification service when needed. Low priority — OTP content is the same regardless of channel. |
| 29 | Netcore vs SMTP email send toggle (NetcoreEmailService flag) |
LoginRepository.cs:1062-1084 |
INotificationService abstraction (EmailNotificationService impl) |
N/A — ARCHITECTURE CHANGE |
New code abstracts email delivery behind INotificationService interface. The concrete implementation (EmailNotificationService) can be swapped for any provider. Provider toggle is a deployment concern, not business logic. No gap. |
| 30 | NRI separate email flow (GENERATEEMAILOTP_NRI / VALIDATEOTPEMAIL_NRI) |
LoginController.cs:367-445, LoginRepository.cs:1179-1526 |
EmailVerificationService: CheckNriEmailDedupeAsync + forced MANUAL_OTP |
FIXED |
NRI email flow implemented: (1) CheckNriEmailDedupeAsync checks email+InterestedIn against leads + client_master, (2) NRI always forced to manual OTP (no KRA/Google shortcuts), (3) suspicious email block already applies. Same endpoint, IsNri flag on Lead drives the branching. |
| 31 | Email validation flags from DB (GET_EMAILVALIDATION_FLAG SP returns CALLEMAILREGEX, CALLEMAILVALIDATION, ISREALTIMEVALIDATEEMAIL, etc.) |
LoginRepository.cs:856-859, 1960-1967 |
EmailVerificationService.IsConfigEnabledAsync() reads application_config |
PRESENT (simplified) |
New code uses application_config with keys like ENABLE_WHITELIST_CHECK, ENABLE_CUSTOM_FORMAT_CHECK, ENABLE_RESTRICTED_DOMAIN_CHECK. Old 5 flags are collapsed to 3 config toggles since Cybridge/Karza are excluded. Equivalent coverage for active features. |
| 32 | ISAUTOFETCH flow: auto-fetch email skips OTP, but accept_all from Karza forces OTP fallback |
LoginRepository.cs:2014-2022 |
EmailVerificationService: KRA_PREFILL + GOOGLE_OAUTH auto-verify paths |
PRESENT (improved) |
Old ISAUTOFETCH had accept_all fallback because Karza sometimes returned ambiguous results. New code: KRA_PREFILL and GOOGLE_OAUTH auto-verify cleanly. No accept_all fallback needed since Karza is excluded. NRI leads are forced to OTP regardless. |
| 33 | DirectSalesAgent check: ISDirectSalesAgent restricts email OTP send for DSA-login users |
LoginRepository.cs:2279-2285 |
N/A |
OPEN — LOW PRIORITY |
Old code blocked email OTP for Direct Sales Agent logins. New code has no DSA-specific restriction. DSA concept exists in BackOfficeCheckService but is not wired to email flow. Low priority — DSA users are branch-assisted and typically don’t self-serve email verification. |
| 34 | Post email-verify: SuperApp client code generation + OtpKycDetails push (SEND_CLOUD_FLAG) |
LoginRepository.cs:2114-2248 |
EmailVerificationService publishes downstream events to CLEVERTAP, ZOHO_CRM, CDP, DATALAKE |
N/A — ARCHITECTURE CHANGE |
Old code generated client code + pushed to SuperApp API at email stage. New architecture: client code is generated at Stage 14 (AccountCreation). SuperApp reads data via downstream events, not direct API push. SEND_CLOUD_FLAG concept replaced by event-driven architecture. No gap. |
| 35 | @motilaloswal.com domain forces isEmailOTPRequired=1 (internal emails always require OTP) |
LoginRepository.cs:2267-2270 |
EmailVerificationService: MoslInternalDomain const excluded from IIBL auto-skip |
FIXED |
@motilaloswal.com is defined as MoslInternalDomain constant. IIBL auto-skip explicitly excludes this domain, forcing OTP. Compliance rule enforced. |
| 36 | Email hash storage in DB after verification |
SP-level (USP_VALIDATE_UPDATE_OTP_EMAIL_SJET stores hashed email) |
EmailVerificationService (EmailVerification.EmailHash) |
PRESENT |
Both store email hash. New code stores via EmailVerification entity. Equivalent. |
| 37 | Stage transition: INSERTUPDATE_STAGEDETAILS for OTPEMAIL stage |
LoginRepository.cs:2111 |
EmailVerificationService (lead.CurrentState=EMAIL_VERIFIED, JourneyTracker records) |
PRESENT |
Both record stage completion. New code is more structured with state machine transitions and audit trail. |
| 38 | Email OTP resend with max limit enforcement |
SP: USP_SEND_RESUME_EMAILOTP_SJET (handles resend internally) |
EmailVerificationService.ResendEmailOtpAsync() (MaxResends=3, 30s cooldown) |
PRESENT |
Both enforce email OTP resend limits. New code has explicit cooldown via Redis. Equivalent logic. |
| 39 | AccountType/HolderType (JOINT, FH, SH, TH) passed through email OTP flow |
LoginController.cs:338-345,399-406, LoginRepository.cs (AccountType/HolderType params) |
N/A |
N/A — ARCHITECTURE CHANGE |
Old code threaded AccountType/HolderType through every SP call. New architecture: each Lead represents a single account holder. Joint/minor holders are separate Lead entities created at Stage 9 (PersonalDetails/Nominee). No need to pass holder type through email OTP — each holder verifies independently. No gap. |
| 40 | GET_EMAIL_DETAILS_SJET: retrieve pre-filled email details for the user |
LoginRepository.cs:1791-1817, LoginController.cs:143-181 |
EmailVerificationService.GetEmailDetailsAsync() |
PRESENT |
Old code calls SP to get existing email for the user. New code checks KRA prefill email. Both provide pre-fill capability. |
| 41 | Mobile+Email configuration details (USP_GET_MOBILE_EMAIL_CONFIGURATION_DETAILS_SJET) |
SP: USP_GET_MOBILE_EMAIL_CONFIGURATION_DETAILS_SJET |
application_config table + IsConfigEnabledAsync() |
PRESENT (simplified) |
Old SP returned per-channel validation config. New code uses application_config with feature-toggle keys (ENABLE_WHITELIST_CHECK, ENABLE_CUSTOM_FORMAT_CHECK, etc). Per-channel granularity can be added by using channel-prefixed keys (e.g. DAD_ENABLE_WHITELIST_CHECK) if needed. Current single-config approach works for DAD vertical. |
| 42 | Google OAuth email verification (auto-verify without OTP) |
N/A |
EmailVerificationService.HandleGoogleOAuthVerificationAsync() |
IMPROVED |
New code adds Google OAuth as an email verification path (auto-verify without OTP). Old code did not have Google OAuth integration. |
| 43 | KRA prefill email verification (auto-verify without OTP) |
N/A |
EmailVerificationService.HandleKraPrefillVerificationAsync() |
IMPROVED |
New code adds KRA prefill as an email verification path (auto-verify). Old code did not have this - KRA email was handled at PAN stage, not email stage. |