From c79844a86f4681d11b6de7dfcc594edaa1888257 Mon Sep 17 00:00:00 2001 From: Adam Wood <1017872+adamwoodnz@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:08:17 +1200 Subject: [PATCH] Auto generate codes on TOTP success --- settings/src/components/backup-codes.js | 13 +++++++++++++ settings/src/components/settings.js | 8 +++++++- settings/src/script.js | 3 +++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/settings/src/components/backup-codes.js b/settings/src/components/backup-codes.js index ef8cc94d..e769f95f 100644 --- a/settings/src/components/backup-codes.js +++ b/settings/src/components/backup-codes.js @@ -25,9 +25,18 @@ import DownloadButton from './download-button'; export default function BackupCodes( { onSuccess = () => {} } ) { const { user: { hasPrimaryProvider }, + shouldAutoGenerateBackupCodes, } = useContext( GlobalContext ); const [ generating, setGenerating ] = useState( false ); + useEffect( () => { + if ( shouldAutoGenerateBackupCodes ) { + setGenerating( true ); + } + // This should only run once on mount. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [] ); + // Prevent users from accessing directly through the URL. if ( ! hasPrimaryProvider ) { return ( @@ -61,6 +70,7 @@ function Setup( { setGenerating, onSuccess } ) { setError, error, setBackupCodesVerified, + setShouldAutoGenerateBackupCodes, } = useContext( GlobalContext ); const [ backupCodes, setBackupCodes ] = useState( [] ); const [ hasPrinted, setHasPrinted ] = useState( false ); @@ -84,6 +94,7 @@ function Setup( { setGenerating, onSuccess } ) { } ); setBackupCodes( response.codes ); + setShouldAutoGenerateBackupCodes( false ); // Update the Account Status screen in case they click `Back` without verifying the codes, but // don't redirect to the Manage screen yet. This is mainly due to the side-effects of @@ -96,6 +107,8 @@ function Setup( { setGenerating, onSuccess } ) { }; generateCodes(); + // This should only run once on mount. + // eslint-disable-next-line react-hooks/exhaustive-deps }, [] ); // Finish the setup process. diff --git a/settings/src/components/settings.js b/settings/src/components/settings.js index 0f763a47..9d8f3ed5 100644 --- a/settings/src/components/settings.js +++ b/settings/src/components/settings.js @@ -20,7 +20,12 @@ import { GlobalContext } from '../script'; * Render the correct component based on the URL. */ export default function Settings() { - const { backupCodesEnabled, navigateToScreen, screen } = useContext( GlobalContext ); + const { + user: { backupCodesEnabled }, + navigateToScreen, + screen, + setShouldAutoGenerateBackupCodes, + } = useContext( GlobalContext ); // The index is the URL slug and the value is the React component. const components = { @@ -31,6 +36,7 @@ export default function Settings() { { if ( ! backupCodesEnabled ) { + setShouldAutoGenerateBackupCodes( true ); navigateToScreen( 'backup-codes' ); } else { navigateToScreen( 'home' ); diff --git a/settings/src/script.js b/settings/src/script.js index 7ee31545..5494a018 100644 --- a/settings/src/script.js +++ b/settings/src/script.js @@ -61,6 +61,7 @@ function Main( { userId, isOnboarding } ) { const [ globalNotice, setGlobalNotice ] = useState( '' ); const [ error, setError ] = useState( '' ); const [ backupCodesVerified, setBackupCodesVerified ] = useState( true ); + const [ shouldAutoGenerateBackupCodes, setShouldAutoGenerateBackupCodes ] = useState( false ); let currentUrl = new URL( document.location.href ); const initialScreen = currentUrl.searchParams.get( 'screen' ); @@ -150,6 +151,8 @@ function Main( { userId, isOnboarding } ) { setBackupCodesVerified, setScreen, screen, + shouldAutoGenerateBackupCodes, + setShouldAutoGenerateBackupCodes, } } >