Files
supabase/apps/studio/components/interfaces/Account/TOTPFactors/GenerateRecoveryCodesModal.tsx
Gildas Garcia 314856558b Recovery codes: fix condition to display them (#50716)
## Problem

1. Recovery codes section is displayed even when users don't have any
MFA set up
2. Codes modals are janky while the operation (generate or regenerate)
is pending

## Solution

1. Fix the condition checked to display the section (at least one MFA
set up)
2. Fix loading states handling

## Review instructions

On an account without any MFA set up:
1. Check that the recovery codes section is not displayed on 
2. Add a new MFA and check the modal for recovery codes appearance is
not janky
3. Delete the recovery codes (this button only exists on local and
staging envs)
4. Check that the warning for missing recovery codes is displayed
5. Generate the codes and check the modal appearance is not janky
6. Regenerate the codes and check the modal appearance is not janky

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which references
[WORD_LIST](https://github.com/supabase/supabase/blob/master/apps/docs/WORD_LIST.md)
and the docs
[CONTRIBUTING](https://github.com/supabase/supabase/blob/master/apps/docs/CONTRIBUTING.md)
guide


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Recovery-code dialogs now open only after code generation or
regeneration finishes.
* Generation and regeneration actions display a loading state while
processing.
  * Screen readers are notified when recovery codes are being generated.
* Confirmation actions are disabled while recovery codes are being
generated.
* Recovery-code status and related controls are shown only when a TOTP
factor is configured.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-22 17:10:24 +02:00

43 lines
1.4 KiB
TypeScript

import { useState } from 'react'
import { Button } from 'ui'
import { Admonition } from 'ui-patterns/Admonition'
import { RecoveryCodesModal } from './RecoveryCodesModal'
import { useRecoveryCodesGenerateMutation } from '@/data/recovery-codes/recovery-codes-generate-mutation'
export const GenerateRecoveryCodesModal = () => {
const recoveryCodesGenerateMutation = useRecoveryCodesGenerateMutation({
onSettled: () => setOpen(true),
})
const [open, setOpen] = useState(false)
return (
<Admonition
type="danger"
layout="horizontal"
title="You haven't generated recovery codes yet"
description="Recovery codes are important to ensure you can recover your account if you loose access to your MFA."
actions={
<>
<span aria-live="polite" className="sr-only">
{recoveryCodesGenerateMutation.isPending ? 'Generating your recovery codes...' : ''}
</span>
<Button
onClick={() => {
recoveryCodesGenerateMutation.mutate({})
}}
loading={recoveryCodesGenerateMutation.isPending}
>
Generate recovery codes
</Button>
<RecoveryCodesModal
open={open}
onOpenChange={(open) => setOpen(open)}
mutation={recoveryCodesGenerateMutation}
/>
</>
}
/>
)
}