66use BookStack \Access \Mfa \BackupCodeService ;
77use BookStack \Access \Mfa \MfaSession ;
88use BookStack \Access \Mfa \MfaValue ;
9+ use BookStack \Access \Mfa \MfaVerificationLimiter ;
910use BookStack \Activity \ActivityType ;
1011use BookStack \Exceptions \NotFoundException ;
1112use BookStack \Http \Controller ;
@@ -19,6 +20,11 @@ class MfaBackupCodesController extends Controller
1920
2021 protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-backup-codes ' ;
2122
23+ public function __construct (
24+ protected MfaVerificationLimiter $ limiter ,
25+ ) {
26+ }
27+
2228 /**
2329 * Show a view that generates and displays backup codes.
2430 */
@@ -71,6 +77,12 @@ public function confirm()
7177 public function verify (Request $ request , BackupCodeService $ codeService , MfaSession $ mfaSession , LoginService $ loginService )
7278 {
7379 $ user = $ this ->currentOrLastAttemptedUser ();
80+ $ this ->limiter ->incrementAttempts ($ user , $ request );
81+ if ($ this ->limiter ->hasHitLimit ($ user , $ request )) {
82+ $ this ->clearLastAttemptedUser ();
83+ $ this ->limiter ->throwException ();
84+ }
85+
7486 $ codes = MfaValue::getValueForUser ($ user , MfaValue::METHOD_BACKUP_CODES ) ?? '[] ' ;
7587
7688 $ this ->validate ($ request , [
@@ -89,6 +101,7 @@ function ($attribute, $value, $fail) use ($codeService, $codes) {
89101
90102 $ mfaSession ->markVerifiedForUser ($ user );
91103 $ loginService ->reattemptLoginFor ($ user );
104+ $ this ->limiter ->decrementAttempts ($ user , $ request );
92105
93106 if ($ codeService ->countCodesInSet ($ updatedCodes ) < 5 ) {
94107 $ this ->showWarningNotification (trans ('auth.mfa_backup_codes_usage_limit_warning ' ));
0 commit comments