Skip to content

Commit

Permalink
Backup Codes: Track if codes are verified to show Setup/Manage correctly
Browse files Browse the repository at this point in the history
Without this, generating codes for the first time, then clicking `Back`, then visiting the Backup Codes screen would generate another set of codes. It should instead render the `Manage` component, since the first setup saved the codes to the database.
  • Loading branch information
iandunn committed Sep 25, 2023
1 parent a48876b commit bedf3d6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
16 changes: 15 additions & 1 deletion settings/src/components/backup-codes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import ScreenLink from './screen-link';
export default function BackupCodes() {
const {
user: { backupCodesEnabled, hasPrimaryProvider, backupCodesRemaining },
backupCodesVerified,
} = useContext( GlobalContext );
const [ regenerating, setRegenerating ] = useState( false );

Expand All @@ -37,7 +38,12 @@ export default function BackupCodes() {
);
}

if ( ! backupCodesEnabled || backupCodesRemaining === 0 || regenerating ) {
if (
! backupCodesEnabled ||
backupCodesRemaining === 0 ||
regenerating ||
! backupCodesVerified
) {
return <Setup setRegenerating={ setRegenerating } />;
}

Expand All @@ -56,6 +62,7 @@ function Setup( { setRegenerating } ) {
user: { userRecord },
setError,
error,
setBackupCodesVerified,
} = useContext( GlobalContext );
const [ backupCodes, setBackupCodes ] = useState( [] );
const [ hasPrinted, setHasPrinted ] = useState( false );
Expand All @@ -79,6 +86,12 @@ function Setup( { setRegenerating } ) {
} );

setBackupCodes( response.codes );

// 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
// `two-factor/#507`, so it will need to be modified or maybe removed when that is fixed upstream.
setBackupCodesVerified( false );
await refreshRecord( userRecord );
} catch ( apiFetchError ) {
setError( apiFetchError );
}
Expand All @@ -91,6 +104,7 @@ function Setup( { setRegenerating } ) {
const handleFinished = useCallback( async () => {
// TODO: Add try catch here after https://github.com/WordPress/wporg-two-factor/pull/187/files is merged.
// The codes have already been saved to usermeta, see `generateCodes()` above.
setBackupCodesVerified( true );
await refreshRecord( userRecord ); // This has the intended side-effect of redirecting to the Manage screen.
setGlobalNotice( 'Backup codes have been enabled.' );
setRegenerating( false );
Expand Down
8 changes: 7 additions & 1 deletion settings/src/components/screen-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useCallback, useContext } from '@wordpress/element';
import { GlobalContext } from '../script';

export default function ScreenLink( { screen, anchorText, buttonStyle = false, ariaLabel } ) {
const { navigateToScreen } = useContext( GlobalContext );
const { navigateToScreen, setBackupCodesVerified } = useContext( GlobalContext );
const classes = [];
const screenUrl = new URL( document.location.href );

Expand All @@ -26,6 +26,12 @@ export default function ScreenLink( { screen, anchorText, buttonStyle = false, a
const onClick = useCallback(
( event ) => {
event.preventDefault();

// When generating Backup Codes, they're automatically saved to the database, so clicking `Back` is
// implicitly verifying them, or at least needs to be treated that way. This should be removed once
// `two-factor/#507` is fixed, though.
setBackupCodesVerified( true );

navigateToScreen( screen );
},
[ navigateToScreen ]
Expand Down
11 changes: 10 additions & 1 deletion settings/src/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function Main( { userId } ) {
} = user;
const [ globalNotice, setGlobalNotice ] = useState( '' );
const [ error, setError ] = useState( '' );
const [ backupCodesVerified, setBackupCodesVerified ] = useState( true );

let currentUrl = new URL( document.location.href );
const initialScreen = currentUrl.searchParams.get( 'screen' );
Expand Down Expand Up @@ -161,7 +162,15 @@ function Main( { userId } ) {

return (
<GlobalContext.Provider
value={ { navigateToScreen, user, setGlobalNotice, setError, error } }
value={ {
navigateToScreen,
user,
setGlobalNotice,
setError,
error,
backupCodesVerified,
setBackupCodesVerified,
} }
>
<GlobalNotice notice={ globalNotice } setNotice={ setGlobalNotice } />
{ currentScreenComponent }
Expand Down

0 comments on commit bedf3d6

Please sign in to comment.