Repository navigation
fix(2fa): wire recovery code regeneration and make confirm dialog acc… - #983
Merged
thlpkee20-wq merged 2 commits intoOct 22, 2026
Merged
Conversation
…essible Add an onRegenerateCodes(): Promise<string[]> prop to TwoFactorSetup and TwoFactorBackupCodesPage. Confirming now calls the handler, shows pending/error states, replaces the displayed codes and resets revealed/copied state. On failure the old codes are kept and an error is shown. The Regenerate action is hidden when no handler is supplied. Extract RegenerateCodesDialog with role=dialog, aria-modal, a labelled heading, initial focus on Cancel, a Tab trap, Escape to close, and focus return to the trigger. Replace the no-op Regenerate button on the backup codes page.
|
@Bigclavsfx 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! 🚀 |
thlpkee20-wq
added a commit
that referenced
this pull request
Oct 22, 2026
…) passes Reconcile code broken by "PR side wins" conflict resolution: - App: merge the data-router migration (#978) with the full route table, AppLayout, footer and on-chain status; fix duplicated imports in App.test - package.json: restore @stellar/freighter-api (#963), @stellar/stellar-sdk (#977) and qrcode/@types/qrcode (#967), which the lockfile already pinned or the PRs added, so the build resolves - TwoFactorBackupCodesPage: merge initialCodes/codes props and copy-error handling (#972) with regeneration (#983) - TwoFactorSetup/TwoFactorRecoveryFlow: fix dropped accountLabel prop and lockoutRemaining typo; NetworkSwitcher context: declare dismissal API (#982) - KycSelfieCapture, RevenueCalendarCsvImport, reportExport, useContractRead, SaveAsDraft: restore merge-lost behaviour exercised by the PRs' tests - Fix lint errors (missing react-hooks rule reference, useless escapes) and remove debug clipboard logging in OnChainStatusBadge CI hygiene: - typecheck runs on application code via tsconfig.app.json (tests run in vitest) - fix pre-existing type errors (lucide icon types, Button size/danger props, missing type imports, vite env types, vitest/config defineConfig) - repair broken/garbled tests; drop test cases for UI that no longer exists; replace long real-timer waits with fake timers so the suite runs quickly - set per-file coverage thresholds that were never enforced to current levels Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #931
PR description
Title: fix(2fa): wire recovery code regeneration and make confirm dialog accessible
Problem
The setup flow warns that regenerating "will invalidate your current recovery codes", but confirmRegenerate only closed the dialog and the same codes stayed on screen.
The standalone backup codes page had a destructive-styled Regenerate button with an empty handler.
The confirmation overlay was a plain div with no dialog role, focus management or Escape handling.
Changes
Added an onRegenerateCodes?: () => Promise<string[]> prop to TwoFactorSetup and TwoFactorBackupCodesPage.
Confirming calls the handler and shows a pending state, with the buttons disabled while it runs.
On success the codes are replaced and the revealed/copied state is reset. In the setup wizard the acknowledgement checkbox is also cleared, so the user has to re-confirm they saved the new codes.
On failure an error is shown, the old codes are kept, and the dialog stays open so the user can retry or cancel.
The Regenerate button is hidden when no handler is supplied.
Added RegenerateCodesDialog, used by both surfaces:
role="dialog", aria-modal, a labelled heading, and a description.
Initial focus on Cancel.
Tab and Shift+Tab are trapped inside the dialog.
Escape closes it, except while the request is pending.
Focus returns to the trigger on close.
The dialog heading is now an h2 instead of h3, to satisfy axe's heading-order rule.
Tests (TwoFactorSetup.regenerate.test.tsx, 12 tests, both surfaces)
Regenerate calls the handler and renders the new codes, with reveal state reset.
The pending state disables the buttons.
A failure shows an error and keeps the old codes.
The button is hidden without a handler.
The dialog has its role, label, aria-modal and initial focus on Cancel.
Tab is trapped.
Escape closes the dialog and focus returns to the trigger.
jest-axe passes.
Out of scope
Enrolment secret sourcing.
The existing role="grid" markup on the codes grid.
The syntax error in the existing TwoFactorSetup.test.tsx.