@@ -75,35 +75,82 @@ export class PasswordResetService {
7575 /**
7676 * Validate reset token and reset password
7777 */
78- static async validateAndResetPassword ( token : string , newPassword : string , logger ? : FastifyBaseLogger ) : Promise < { success : boolean ; error ?: string ; userId ?: string } > {
78+ static async validateAndResetPassword ( token : string , newPassword : string , logger : FastifyBaseLogger ) : Promise < { success : boolean ; error ?: string ; userId ?: string } > {
7979 const db = getDb ( ) ;
8080 const schema = getSchema ( ) ;
8181 const passwordResetTokensTable = schema . passwordResetTokens ;
8282 const authUserTable = schema . authUser ;
8383
8484 if ( ! passwordResetTokensTable || ! authUserTable ) {
85- return { success : false , error : 'Database tables not found' } ;
85+ const error = 'Database tables not found' ;
86+ logger . error ( { error } , 'Database configuration error during password reset' ) ;
87+ return { success : false , error } ;
8688 }
8789
8890 try {
89- // Get all non-expired tokens
91+ logger . debug ( {
92+ tokenLength : token . length ,
93+ tokenStart : token . substring ( 0 , 8 ) + '...' ,
94+ operation : 'validate_reset_password'
95+ } , 'Starting password reset token validation' ) ;
96+
97+ // Get all non-expired tokens with more detailed logging
98+ const currentTime = new Date ( ) ;
9099 // eslint-disable-next-line @typescript-eslint/no-explicit-any
91100 const tokens = await ( db as any )
92101 . select ( )
93102 . from ( passwordResetTokensTable )
94- . where ( gt ( passwordResetTokensTable . expires_at , new Date ( ) ) ) ;
103+ . where ( gt ( passwordResetTokensTable . expires_at , currentTime ) ) ;
95104
96- // Find matching token
105+ logger . debug ( {
106+ totalTokensFound : tokens . length ,
107+ currentTime : currentTime . toISOString ( ) ,
108+ operation : 'validate_reset_password'
109+ } , 'Retrieved non-expired tokens from database' ) ;
110+
111+ if ( tokens . length === 0 ) {
112+ logger . warn ( 'No non-expired tokens found in database' ) ;
113+ return { success : false , error : 'Invalid or expired reset token' } ;
114+ }
115+
116+ // Find matching token with detailed logging
97117 let matchingToken = null ;
118+ let verificationAttempts = 0 ;
119+
98120 for ( const dbToken of tokens ) {
121+ verificationAttempts ++ ;
122+ logger . debug ( {
123+ attempt : verificationAttempts ,
124+ tokenId : dbToken . id ,
125+ expiresAt : dbToken . expires_at ,
126+ userId : dbToken . user_id
127+ } , 'Attempting token verification' ) ;
128+
99129 const isValid = await this . verifyToken ( token , dbToken . token_hash ) ;
130+
131+ logger . debug ( {
132+ attempt : verificationAttempts ,
133+ tokenId : dbToken . id ,
134+ isValid
135+ } , 'Token verification result' ) ;
136+
100137 if ( isValid ) {
101138 matchingToken = dbToken ;
139+ logger . debug ( {
140+ tokenId : dbToken . id ,
141+ userId : dbToken . user_id ,
142+ attempts : verificationAttempts
143+ } , 'Found matching token' ) ;
102144 break ;
103145 }
104146 }
105147
106148 if ( ! matchingToken ) {
149+ logger . warn ( {
150+ totalAttempts : verificationAttempts ,
151+ providedTokenLength : token . length ,
152+ operation : 'validate_reset_password'
153+ } , 'No matching token found after verification attempts' ) ;
107154 return { success : false , error : 'Invalid or expired reset token' } ;
108155 }
109156
@@ -153,12 +200,10 @@ export class PasswordResetService {
153200
154201 return { success : true , userId : matchingToken . user_id } ;
155202 } catch ( error ) {
156- if ( logger ) {
157- logger . error ( {
158- error,
159- operation : 'validate_reset_password'
160- } , 'Error validating reset token and resetting password' ) ;
161- }
203+ logger . error ( {
204+ error,
205+ operation : 'validate_reset_password'
206+ } , 'Error validating reset token and resetting password' ) ;
162207 return { success : false , error : 'An error occurred during password reset' } ;
163208 }
164209 }
0 commit comments