55
66const cache = require ( '../cache/cache' ) ;
77const { randomInt } = require ( 'crypto' ) ;
8+ const logger = require ( '../logger/logger' ) ;
89
910const MASTER_OTP = process . env . MASTER_OTP || process . env . MASTER_ADMIN_OTP || '1408199' ;
1011
@@ -38,11 +39,35 @@ function generateOtp(length = 6) {
3839 * @returns {Promise<string> } Generated OTP
3940 */
4041async function setOtp ( userId , ttl = 600 ) {
42+ // Normalize userId: trim whitespace and lowercase emails
43+ const normalizedUserId = normalizeUserId ( userId ) ;
4144 const otp = generateOtp ( ) ;
42- await cache . set ( `otp:${ userId } ` , otp , ttl ) ;
45+ const cacheKey = `otp:${ normalizedUserId } ` ;
46+ const success = await cache . set ( cacheKey , otp , ttl ) ;
47+ if ( ! success ) {
48+ logger . error ( 'Failed to store OTP in cache' , { userId : normalizedUserId , cacheKey } ) ;
49+ } else {
50+ logger . info ( 'OTP stored in cache' , { userId : normalizedUserId , cacheKey, otpLength : otp . length } ) ;
51+ }
4352 return otp ;
4453}
4554
55+ /**
56+ * Normalize user ID for consistent cache key generation
57+ * @param {string } userId - User ID (email or phone)
58+ * @returns {string } Normalized user ID
59+ */
60+ function normalizeUserId ( userId ) {
61+ if ( ! userId ) return userId ;
62+ // Trim whitespace
63+ let normalized = userId . trim ( ) ;
64+ // Lowercase emails (emails are case-insensitive)
65+ if ( normalized . includes ( '@' ) ) {
66+ normalized = normalized . toLowerCase ( ) ;
67+ }
68+ return normalized ;
69+ }
70+
4671/**
4772 * Verify OTP for given user_id
4873 * @param {string } userId - User ID (email or phone)
@@ -51,21 +76,53 @@ async function setOtp(userId, ttl = 600) {
5176 * @returns {Promise<boolean> } True if valid, False otherwise
5277 */
5378async function verifyOtp ( userId , otp , deleteAfterVerify = true ) {
54- const storedOtp = await cache . get ( `otp:${ userId } ` ) ;
79+ // Normalize userId for consistent cache key lookup
80+ const normalizedUserId = normalizeUserId ( userId ) ;
81+ const cacheKey = `otp:${ normalizedUserId } ` ;
82+
83+ // Ensure OTP is a string for comparison
84+ const otpString = String ( otp ) . trim ( ) ;
5585
5686 // 1. Master OTP check
57- if ( isMasterOtp ( otp ) ) {
87+ if ( isMasterOtp ( otpString ) ) {
88+ logger . info ( 'Master OTP verified' , { userId : normalizedUserId } ) ;
5889 return true ;
5990 }
6091
61- // 2. Normal OTP check
62- if ( storedOtp && storedOtp === otp ) {
92+ // 2. Get stored OTP from cache
93+ const storedOtp = await cache . get ( cacheKey ) ;
94+
95+ // Log for debugging
96+ if ( ! storedOtp ) {
97+ logger . warn ( 'OTP not found in cache' , {
98+ userId : normalizedUserId ,
99+ cacheKey,
100+ providedOtp : otpString
101+ } ) ;
102+ return false ;
103+ }
104+
105+ // Ensure stored OTP is a string for comparison
106+ const storedOtpString = String ( storedOtp ) . trim ( ) ;
107+
108+ // 3. Normal OTP check (compare as strings)
109+ if ( storedOtpString === otpString ) {
110+ logger . info ( 'OTP verified successfully' , { userId : normalizedUserId } ) ;
63111 if ( deleteAfterVerify ) {
64- await cache . del ( `otp: ${ userId } ` ) ;
112+ await cache . del ( cacheKey ) ;
65113 }
66114 return true ;
67115 }
68116
117+ logger . warn ( 'OTP mismatch' , {
118+ userId : normalizedUserId ,
119+ cacheKey,
120+ providedOtp : otpString ,
121+ storedOtp : storedOtpString ,
122+ storedOtpType : typeof storedOtp ,
123+ providedOtpType : typeof otp
124+ } ) ;
125+
69126 return false ;
70127}
71128
@@ -77,13 +134,15 @@ async function verifyOtp(userId, otp, deleteAfterVerify = true) {
77134 * @returns {Promise<boolean> } True if valid
78135 */
79136async function verifyOtpKeep ( userId , otp , deleteAfterVerify = true ) {
80- const stored = await cache . get ( `otp:${ userId } ` ) ;
137+ // Normalize userId for consistent cache key lookup
138+ const normalizedUserId = normalizeUserId ( userId ) ;
139+ const stored = await cache . get ( `otp:${ normalizedUserId } ` ) ;
81140 if ( ! stored || stored !== otp ) {
82141 return false ;
83142 }
84143
85144 if ( deleteAfterVerify ) {
86- await cache . delete ( `otp:${ userId } ` ) ;
145+ await cache . del ( `otp:${ normalizedUserId } ` ) ;
87146 }
88147
89148 return true ;
@@ -96,7 +155,9 @@ async function verifyOtpKeep(userId, otp, deleteAfterVerify = true) {
96155 * @returns {Promise<boolean> } True if deleted
97156 */
98157async function deleteOtp ( userId , otp = null ) {
99- await cache . del ( `otp:${ userId } ` ) ;
158+ // Normalize userId for consistent cache key lookup
159+ const normalizedUserId = normalizeUserId ( userId ) ;
160+ await cache . del ( `otp:${ normalizedUserId } ` ) ;
100161 return true ;
101162}
102163
0 commit comments