@@ -18,6 +18,7 @@ pub struct SmsVerificationService {
1818 hasher_argon2id : HasherArgon2id ,
1919 max_verifications_per_week : u32 ,
2020 max_verifications_per_year : u32 ,
21+ max_validation_attempts : u32 ,
2122 limit_whitelist : Vec < PhoneNumber > ,
2223}
2324
@@ -27,6 +28,7 @@ impl SmsVerificationService {
2728 homeserver_admin_api : HomeserverAdminAPI ,
2829 max_verifications_per_week : u32 ,
2930 max_verifications_per_year : u32 ,
31+ max_validation_attempts : u32 ,
3032 limit_whitelist : Vec < PhoneNumber > ,
3133 ) -> Self {
3234 if !limit_whitelist. is_empty ( ) {
@@ -39,6 +41,7 @@ impl SmsVerificationService {
3941 hasher_argon2id : HasherArgon2id :: new ( ) ,
4042 max_verifications_per_week,
4143 max_verifications_per_year,
44+ max_validation_attempts,
4245 limit_whitelist,
4346 }
4447 }
@@ -166,6 +169,23 @@ impl SmsVerificationService {
166169 . await
167170 . map_err ( |_| SmsVerificationError :: NoActiveVerification ) ?;
168171
172+ let attempts =
173+ SmsVerificationRepository :: increment_attempts ( & mut executor, & phone_number_hash)
174+ . await ?;
175+ if attempts > self . max_validation_attempts as i32 {
176+ // Mark as failed since they've exceeded the limit
177+ if let Err ( e) = SmsVerificationRepository :: mark_all_pending_verification_as_failed (
178+ & mut executor,
179+ & phone_number_hash,
180+ "max_validation_attempts_exceeded" ,
181+ )
182+ . await
183+ {
184+ tracing:: error!( "{}" , e) ;
185+ }
186+ return Err ( SmsVerificationError :: MaxValidationAttemptsExceeded ) ;
187+ }
188+
169189 let prelude_response = self
170190 . prelude_api
171191 . check_code ( & request. phone_number , & request. code )
@@ -197,7 +217,7 @@ impl SmsVerificationService {
197217 } )
198218 }
199219 PreludeCheckCodeResponse :: Failure { .. } => {
200- // Wrong code - don't mark as failed, allow retries
220+ // Wrong code - don't mark as failed, allow retries (up to max_validation_attempts)
201221 Ok ( ValidateCodeResponse :: Invalid )
202222 }
203223 PreludeCheckCodeResponse :: ExpiredOrNotFound { .. } => {
0 commit comments