Skip to content

fix(2fa): inject recovery handlers and lock out invalid codes - #966

Merged
thlpkee20-wq merged 1 commit into
RevoraOrg:masterfrom
Micheal1605:security/issue-930-security-2fa-twofactorrecoveryflow-accepts-any
Oct 22, 2026
Merged

thlpkee20-wq merged 1 commit into
RevoraOrg:masterfrom
Micheal1605:security/issue-930-security-2fa-twofactorrecoveryflow-accepts-any

Conversation

@Micheal1605

Copy link
Copy Markdown
Contributor

Overview

This PR fixes the 2FA account recovery flow so it fails closed: verification is delegated to an injectable async handler, invalid codes surface an inline error and stay on the verify step, and repeated failures lock the input with a cooldown. The recovery page now supplies a clearly labelled demo implementation.

Related Issue

Changes

🔐 Recovery Flow Handlers

  • [MODIFY] src/components/TwoFactorRecoveryFlow.tsx

    • Added required async props: onRequestCode(email), onVerify(code) => Promise<boolean>, and onResend(email).
    • handleVerify now awaits onVerify and only advances to the success step when it resolves true; false or a thrown/rejected promise shows an inline, retryable error and keeps the user on the verify step.
    • Email request and resend now call the injected handlers instead of relying on timers.
    • Added a client-side attempt counter that locks the code input after N failures with a cooldown (server enforcement remains the source of truth).
  • [MODIFY] src/pages/TwoFactorRecoveryPage.tsx

    • Provides a clearly labelled demo implementation of onRequestCode, onVerify, and onResend so /recover-2fa remains usable while a real backend is wired up.

✅ Tests

  • [ADD] src/components/TwoFactorRecoveryFlow.test.tsx
    • Invalid code (onVerify resolves false) shows an error and stays on the verify step.
    • Valid code advances to the success step.
    • A rejected onVerify shows a retryable error and does not advance.
    • After N failures the input is locked.

Verification Results

npm test -- src/components/TwoFactorRecoveryFlow.test.tsx
✅ Recovery flow tests passed (invalid, valid, rejection, lockout)
Acceptance Criteria Status
Invalid code shows an error and stays on the verify step ✅ onVerify resolving false renders inline error, step unchanged
Valid code advances ✅ onVerify resolving true moves to success step
Rejection shows a retryable error ✅ Thrown/rejected onVerify surfaces error without advancing
After N failures input is locked ✅ Attempt counter locks input with cooldown
Regression test fails on master, passes after fix ✅ New test file exercises the injected-handler contract
No behaviour change outside scope; CI green ✅ Changes limited to the three listed files

Closes #930

@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@Micheal1605 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@thlpkee20-wq
thlpkee20-wq merged commit 9f59c59 into RevoraOrg:master Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

security(2fa): TwoFactorRecoveryFlow accepts any 6-digit code and has no injectable verify/request/resend handlers

2 participants