From f598b96cbe73d9f9a27ef3ec598b53fc8a0cd813 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 09:41:27 -0800 Subject: [PATCH 1/8] fix lint and comment --- .../MultifactorAuthentication/Context/Main.tsx | 13 +++++++++---- .../MultifactorAuthentication/Context/State.tsx | 8 ++++++++ src/libs/actions/MultifactorAuthentication/index.ts | 7 +++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/components/MultifactorAuthentication/Context/Main.tsx b/src/components/MultifactorAuthentication/Context/Main.tsx index 8781ad90591f0..9ef6a77f32bdd 100644 --- a/src/components/MultifactorAuthentication/Context/Main.tsx +++ b/src/components/MultifactorAuthentication/Context/Main.tsx @@ -10,7 +10,7 @@ import {requestValidateCodeAction} from '@libs/actions/User'; import getPlatform from '@libs/getPlatform'; import type {ChallengeType, MultifactorAuthenticationReason, OutcomePaths} from '@libs/MultifactorAuthentication/Biometrics/types'; import Navigation from '@navigation/Navigation'; -import {requestAuthorizationChallenge, requestRegistrationChallenge} from '@userActions/MultifactorAuthentication'; +import {clearLocalMFAPublicKeyList, requestAuthorizationChallenge, requestRegistrationChallenge} from '@userActions/MultifactorAuthentication'; import {processRegistration, processScenario} from '@userActions/MultifactorAuthentication/processing'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -24,9 +24,8 @@ let deviceBiometricsState: OnyxEntry; // Use Onyx.connectWithoutView instead of useOnyx hook to access the device biometrics state. // This is a non-reactive read that allows us to check the current value (hasAcceptedSoftPrompt) -// from within the process() callback without triggering component re-renders or complicating -// the effect's dependency list. Since we only need the latest value at specific points in the -// MFA flow (not reactivity to changes), this is more efficient than using the useOnyx hook. +// from within the process() callback without triggering calling it too many times during the +// fresh registration flow Onyx.connectWithoutView({ key: ONYXKEYS.DEVICE_BIOMETRICS, callback: (data) => { @@ -111,6 +110,12 @@ function MultifactorAuthenticationContextProvider({children}: MultifactorAuthent // 1. Check if there's an error - stop processing if (error) { + if (error.reason === CONST.MULTIFACTOR_AUTHENTICATION.REASON.BACKEND.REGISTRATION_REQUIRED) { + clearLocalMFAPublicKeyList(); + dispatch({type: 'REREGISTER'}); + return; + } + Navigation.navigate(ROUTES.MULTIFACTOR_AUTHENTICATION_OUTCOME.getRoute(paths.failureOutcome), {forceReplace: true}); dispatch({type: 'SET_FLOW_COMPLETE', payload: true}); return; diff --git a/src/components/MultifactorAuthentication/Context/State.tsx b/src/components/MultifactorAuthentication/Context/State.tsx index 5846ea3354e5a..9a52a4dead3e6 100644 --- a/src/components/MultifactorAuthentication/Context/State.tsx +++ b/src/components/MultifactorAuthentication/Context/State.tsx @@ -93,6 +93,7 @@ type Action = | {type: 'SET_FLOW_COMPLETE'; payload: boolean} | {type: 'SET_AUTHENTICATION_METHOD'; payload: AuthTypeInfo | undefined} | {type: 'INIT'; payload: InitPayload} + | {type: 'REREGISTER'} | {type: 'RESET'}; /** @@ -153,6 +154,13 @@ function stateReducer(state: MultifactorAuthenticationState, action: Action): Mu }; case 'RESET': return DEFAULT_STATE; + case 'REREGISTER': + return { + ...DEFAULT_STATE, + scenario: state.scenario, + payload: state.payload, + outcomePaths: state.outcomePaths, + }; default: return state; } diff --git a/src/libs/actions/MultifactorAuthentication/index.ts b/src/libs/actions/MultifactorAuthentication/index.ts index 0bd64c8082163..ab72dd3a14d6a 100644 --- a/src/libs/actions/MultifactorAuthentication/index.ts +++ b/src/libs/actions/MultifactorAuthentication/index.ts @@ -193,6 +193,12 @@ function markHasAcceptedSoftPrompt() { }); } +function clearLocalMFAPublicKeyList() { + Onyx.merge(ONYXKEYS.ACCOUNT, { + multifactorAuthenticationPublicKeyIDs: null, + }); +} + export { registerAuthenticationKey, requestRegistrationChallenge, @@ -200,4 +206,5 @@ export { troubleshootMultifactorAuthentication, revokeMultifactorAuthenticationCredentials, markHasAcceptedSoftPrompt, + clearLocalMFAPublicKeyList, }; From eb60c6856c3a35999d4c787742379b29b097c58f Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 10:00:11 -0800 Subject: [PATCH 2/8] Fix usePromptContent jank --- .../Context/usePromptContent.ts | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/components/MultifactorAuthentication/Context/usePromptContent.ts b/src/components/MultifactorAuthentication/Context/usePromptContent.ts index e98831fb569f6..6b33938ee04ad 100644 --- a/src/components/MultifactorAuthentication/Context/usePromptContent.ts +++ b/src/components/MultifactorAuthentication/Context/usePromptContent.ts @@ -1,3 +1,4 @@ +import { useEffect, useRef } from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import type DotLottieAnimation from '@components/LottieAnimations/types'; import {MULTIFACTOR_AUTHENTICATION_PROMPT_UI} from '@components/MultifactorAuthentication/config'; @@ -39,11 +40,27 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom const [serverHasCredentials = false] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true, selector: serverHasRegisteredCredentials}); const [deviceBiometricsState] = useOnyx(ONYXKEYS.DEVICE_BIOMETRICS, {canBeMissing: true}); const hasEverAcceptedSoftPrompt = deviceBiometricsState?.hasAcceptedSoftPrompt ?? false; + + // This one's a real doozy. There's an edge case with the MFA flows where the user's keys were revoked + // server-side, but the client missed the onyx update clearing them, so the client launches into the authenticate + // flow, shows the user this screen with the "Let's authenticate you" message, + // then finds out mid-flow (after requesting the authentication challenge) that we actually need to restart + // the whole flow and re-register. This ref is used to prevent UI jank after we clear the relevant state + // but haven't yet navigated to the beginning of the registration flow (magic code input) + // Functionally, it acts as a latch for isReturningUser, so that once it becomes true, it'll never become false + const wasPreviouslyRegisteredRef = useRef(false); const contentData = MULTIFACTOR_AUTHENTICATION_PROMPT_UI[promptType]; // Returning user: server has credentials, but user hasn't approved soft prompt yet - const isReturningUser = hasEverAcceptedSoftPrompt && serverHasCredentials && !state.softPromptApproved; + const isReturningUser = wasPreviouslyRegisteredRef.current || (hasEverAcceptedSoftPrompt && serverHasCredentials && !state.softPromptApproved); + + useEffect(() => { + if (!isReturningUser) { + return; + } + wasPreviouslyRegisteredRef.current = isReturningUser; + }, [isReturningUser]); let title: TranslationPaths = contentData.title; let subtitle: TranslationPaths | undefined = contentData.subtitle; @@ -64,7 +81,7 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom // Display confirm button only for new users during their first biometric registration. // Hide it for: users who already approved the soft prompt, users who finished registration, // or returning users with existing server credentials. The button prompts users to enable biometrics. - const shouldDisplayConfirmButton = !hasEverAcceptedSoftPrompt || (!state.softPromptApproved && !state.isRegistrationComplete && !serverHasCredentials); + const shouldDisplayConfirmButton = !hasEverAcceptedSoftPrompt || (!state.softPromptApproved && !state.isRegistrationComplete && !serverHasCredentials && !wasPreviouslyRegisteredRef.current); return { animation: contentData.animation, From 92c8d823a5de778f432197014046218ee0f7b4f9 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 12:00:52 -0800 Subject: [PATCH 3/8] Fix prettier --- src/components/MultifactorAuthentication/Context/Main.tsx | 2 +- .../MultifactorAuthentication/Context/usePromptContent.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/MultifactorAuthentication/Context/Main.tsx b/src/components/MultifactorAuthentication/Context/Main.tsx index 9ef6a77f32bdd..928fca4cf9c8c 100644 --- a/src/components/MultifactorAuthentication/Context/Main.tsx +++ b/src/components/MultifactorAuthentication/Context/Main.tsx @@ -24,7 +24,7 @@ let deviceBiometricsState: OnyxEntry; // Use Onyx.connectWithoutView instead of useOnyx hook to access the device biometrics state. // This is a non-reactive read that allows us to check the current value (hasAcceptedSoftPrompt) -// from within the process() callback without triggering calling it too many times during the +// from within the process() callback without triggering calling it too many times during the // fresh registration flow Onyx.connectWithoutView({ key: ONYXKEYS.DEVICE_BIOMETRICS, diff --git a/src/components/MultifactorAuthentication/Context/usePromptContent.ts b/src/components/MultifactorAuthentication/Context/usePromptContent.ts index 6b33938ee04ad..445547cf07803 100644 --- a/src/components/MultifactorAuthentication/Context/usePromptContent.ts +++ b/src/components/MultifactorAuthentication/Context/usePromptContent.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef } from 'react'; +import {useEffect, useRef} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import type DotLottieAnimation from '@components/LottieAnimations/types'; import {MULTIFACTOR_AUTHENTICATION_PROMPT_UI} from '@components/MultifactorAuthentication/config'; @@ -40,7 +40,7 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom const [serverHasCredentials = false] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: true, selector: serverHasRegisteredCredentials}); const [deviceBiometricsState] = useOnyx(ONYXKEYS.DEVICE_BIOMETRICS, {canBeMissing: true}); const hasEverAcceptedSoftPrompt = deviceBiometricsState?.hasAcceptedSoftPrompt ?? false; - + // This one's a real doozy. There's an edge case with the MFA flows where the user's keys were revoked // server-side, but the client missed the onyx update clearing them, so the client launches into the authenticate // flow, shows the user this screen with the "Let's authenticate you" message, @@ -81,7 +81,8 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom // Display confirm button only for new users during their first biometric registration. // Hide it for: users who already approved the soft prompt, users who finished registration, // or returning users with existing server credentials. The button prompts users to enable biometrics. - const shouldDisplayConfirmButton = !hasEverAcceptedSoftPrompt || (!state.softPromptApproved && !state.isRegistrationComplete && !serverHasCredentials && !wasPreviouslyRegisteredRef.current); + const shouldDisplayConfirmButton = + !hasEverAcceptedSoftPrompt || (!state.softPromptApproved && !state.isRegistrationComplete && !serverHasCredentials && !wasPreviouslyRegisteredRef.current); return { animation: contentData.animation, From 78e6db41190b96123cbedbcfda9a2b8448ad39b7 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 13:42:20 -0800 Subject: [PATCH 4/8] Apply suggestions from code review Co-authored-by: Rafe Colton <1058475+rafecolton@users.noreply.github.com> --- .../Context/usePromptContent.ts | 15 +++++++++------ .../actions/MultifactorAuthentication/index.ts | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/components/MultifactorAuthentication/Context/usePromptContent.ts b/src/components/MultifactorAuthentication/Context/usePromptContent.ts index 445547cf07803..ceeb06797adfd 100644 --- a/src/components/MultifactorAuthentication/Context/usePromptContent.ts +++ b/src/components/MultifactorAuthentication/Context/usePromptContent.ts @@ -42,12 +42,15 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom const hasEverAcceptedSoftPrompt = deviceBiometricsState?.hasAcceptedSoftPrompt ?? false; // This one's a real doozy. There's an edge case with the MFA flows where the user's keys were revoked - // server-side, but the client missed the onyx update clearing them, so the client launches into the authenticate - // flow, shows the user this screen with the "Let's authenticate you" message, - // then finds out mid-flow (after requesting the authentication challenge) that we actually need to restart - // the whole flow and re-register. This ref is used to prevent UI jank after we clear the relevant state - // but haven't yet navigated to the beginning of the registration flow (magic code input) - // Functionally, it acts as a latch for isReturningUser, so that once it becomes true, it'll never become false + // server-side, but the client missed the Onyx update to clear them locally. When the client launches the MFA + // flow, it thinks it is already registered, so it goes directly to authentication. When it requests an + // authentication challenge from the server, the server throws "400 Registration required", so we need to + // restart the whole flow. The registration flow clears a relevant state, which causes the prompt page to + // change from the authentication version to the registration version briefly before we navigate away from the + // page. Since there is no legitimate case for the prompt page to transition from authentication => + // registration during a single flow, only the other way around, this ref prevents that from happening. + // Functionally, it acts as a latch for isReturningUser, so that once it becomes true, it'll never become + // false for the duration of the flow. const wasPreviouslyRegisteredRef = useRef(false); const contentData = MULTIFACTOR_AUTHENTICATION_PROMPT_UI[promptType]; diff --git a/src/libs/actions/MultifactorAuthentication/index.ts b/src/libs/actions/MultifactorAuthentication/index.ts index ab72dd3a14d6a..4d634574b4951 100644 --- a/src/libs/actions/MultifactorAuthentication/index.ts +++ b/src/libs/actions/MultifactorAuthentication/index.ts @@ -195,7 +195,7 @@ function markHasAcceptedSoftPrompt() { function clearLocalMFAPublicKeyList() { Onyx.merge(ONYXKEYS.ACCOUNT, { - multifactorAuthenticationPublicKeyIDs: null, + multifactorAuthenticationPublicKeyIDs: [], }); } From 917e8e06ef5fd597b4122c8d208122719a2c5a90 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 13:42:58 -0800 Subject: [PATCH 5/8] Minor comment clarification --- .../MultifactorAuthentication/Context/usePromptContent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MultifactorAuthentication/Context/usePromptContent.ts b/src/components/MultifactorAuthentication/Context/usePromptContent.ts index ceeb06797adfd..52db4d085408f 100644 --- a/src/components/MultifactorAuthentication/Context/usePromptContent.ts +++ b/src/components/MultifactorAuthentication/Context/usePromptContent.ts @@ -50,7 +50,7 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom // page. Since there is no legitimate case for the prompt page to transition from authentication => // registration during a single flow, only the other way around, this ref prevents that from happening. // Functionally, it acts as a latch for isReturningUser, so that once it becomes true, it'll never become - // false for the duration of the flow. + // false until we navigate to a different page const wasPreviouslyRegisteredRef = useRef(false); const contentData = MULTIFACTOR_AUTHENTICATION_PROMPT_UI[promptType]; From 92e971280864e985b446cae71e42042edd86bbf4 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 14:10:58 -0800 Subject: [PATCH 6/8] Add constants for special meaningful values of multifactorAuthenticationPublicKeyIDs --- .../MultifactorAuthentication/Context/usePromptContent.ts | 4 ++-- src/libs/MultifactorAuthentication/Biometrics/VALUES.ts | 8 ++++++++ src/libs/actions/MultifactorAuthentication/index.ts | 2 +- src/pages/settings/Security/SecuritySettingsPage.tsx | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/MultifactorAuthentication/Context/usePromptContent.ts b/src/components/MultifactorAuthentication/Context/usePromptContent.ts index 52db4d085408f..383eae5e8f28e 100644 --- a/src/components/MultifactorAuthentication/Context/usePromptContent.ts +++ b/src/components/MultifactorAuthentication/Context/usePromptContent.ts @@ -48,9 +48,9 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom // restart the whole flow. The registration flow clears a relevant state, which causes the prompt page to // change from the authentication version to the registration version briefly before we navigate away from the // page. Since there is no legitimate case for the prompt page to transition from authentication => - // registration during a single flow, only the other way around, this ref prevents that from happening. + // registration, only the other way around, this ref prevents that from happening. // Functionally, it acts as a latch for isReturningUser, so that once it becomes true, it'll never become - // false until we navigate to a different page + // false until this screen unmounts const wasPreviouslyRegisteredRef = useRef(false); const contentData = MULTIFACTOR_AUTHENTICATION_PROMPT_UI[promptType]; diff --git a/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts b/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts index 1e8278f720254..990022359a4dd 100644 --- a/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts +++ b/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts @@ -205,6 +205,14 @@ const MULTIFACTOR_AUTHENTICATION_VALUES = { }, API_RESPONSE_MAP, REASON, + /** + * Specifically meaningful values for `multifactorAuthenticationPublicKeyIDs` in the `account` Onyx key + * casting `[] as string[]` is necessary to allow us to actually store the value in Onyx. Otherwise the + * `as const` would mean `[]` becomes `readonly []` (readonly empty array), which is more precise, + * but isn't allowed to be assigned to a `string[]` field + */ + PUBLIC_KEYS_PREVIOUSLY_BUT_NOT_CURRENTLY_REGISTERED: [] as string[], + PUBLIC_KEYS_AUTHENTICATION_NEVER_REGISTERED: undefined } as const; export {MultifactorAuthenticationCallbacks}; diff --git a/src/libs/actions/MultifactorAuthentication/index.ts b/src/libs/actions/MultifactorAuthentication/index.ts index 4d634574b4951..cc9edfac2237c 100644 --- a/src/libs/actions/MultifactorAuthentication/index.ts +++ b/src/libs/actions/MultifactorAuthentication/index.ts @@ -195,7 +195,7 @@ function markHasAcceptedSoftPrompt() { function clearLocalMFAPublicKeyList() { Onyx.merge(ONYXKEYS.ACCOUNT, { - multifactorAuthenticationPublicKeyIDs: [], + multifactorAuthenticationPublicKeyIDs: CONST.MULTIFACTOR_AUTHENTICATION.PUBLIC_KEYS_PREVIOUSLY_BUT_NOT_CURRENTLY_REGISTERED }); } diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index 80d68dc72270e..cb5059d4c1c23 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -91,7 +91,7 @@ function SecuritySettingsPage() { const hasDelegates = delegates.length > 0; const hasDelegators = delegators.length > 0; - const hasEverRegisteredForMultifactorAuthentication = account?.multifactorAuthenticationPublicKeyIDs !== undefined; + const hasEverRegisteredForMultifactorAuthentication = account?.multifactorAuthenticationPublicKeyIDs !== CONST.MULTIFACTOR_AUTHENTICATION.PUBLIC_KEYS_AUTHENTICATION_NEVER_REGISTERED; const setMenuPosition = useCallback(() => { if (!delegateButtonRef.current) { From a6d5648b463dbbcb962acec9943377db2d8faf78 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 14:17:16 -0800 Subject: [PATCH 7/8] Fix prettier --- src/libs/MultifactorAuthentication/Biometrics/VALUES.ts | 2 +- src/libs/actions/MultifactorAuthentication/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts b/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts index 990022359a4dd..549ad0c24463d 100644 --- a/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts +++ b/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts @@ -212,7 +212,7 @@ const MULTIFACTOR_AUTHENTICATION_VALUES = { * but isn't allowed to be assigned to a `string[]` field */ PUBLIC_KEYS_PREVIOUSLY_BUT_NOT_CURRENTLY_REGISTERED: [] as string[], - PUBLIC_KEYS_AUTHENTICATION_NEVER_REGISTERED: undefined + PUBLIC_KEYS_AUTHENTICATION_NEVER_REGISTERED: undefined, } as const; export {MultifactorAuthenticationCallbacks}; diff --git a/src/libs/actions/MultifactorAuthentication/index.ts b/src/libs/actions/MultifactorAuthentication/index.ts index cc9edfac2237c..42ffe56fb8551 100644 --- a/src/libs/actions/MultifactorAuthentication/index.ts +++ b/src/libs/actions/MultifactorAuthentication/index.ts @@ -195,7 +195,7 @@ function markHasAcceptedSoftPrompt() { function clearLocalMFAPublicKeyList() { Onyx.merge(ONYXKEYS.ACCOUNT, { - multifactorAuthenticationPublicKeyIDs: CONST.MULTIFACTOR_AUTHENTICATION.PUBLIC_KEYS_PREVIOUSLY_BUT_NOT_CURRENTLY_REGISTERED + multifactorAuthenticationPublicKeyIDs: CONST.MULTIFACTOR_AUTHENTICATION.PUBLIC_KEYS_PREVIOUSLY_BUT_NOT_CURRENTLY_REGISTERED, }); } From dc7d20f1ca6b51d0af8628d1cc0623e36100c294 Mon Sep 17 00:00:00 2001 From: Chuck Dries Date: Fri, 6 Feb 2026 14:37:14 -0800 Subject: [PATCH 8/8] Apply suggestions from code review Co-authored-by: Rafe Colton <1058475+rafecolton@users.noreply.github.com> --- .../MultifactorAuthentication/Context/usePromptContent.ts | 6 +++--- src/libs/MultifactorAuthentication/Biometrics/VALUES.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/MultifactorAuthentication/Context/usePromptContent.ts b/src/components/MultifactorAuthentication/Context/usePromptContent.ts index 383eae5e8f28e..85898f8d7322b 100644 --- a/src/components/MultifactorAuthentication/Context/usePromptContent.ts +++ b/src/components/MultifactorAuthentication/Context/usePromptContent.ts @@ -48,9 +48,9 @@ function usePromptContent(promptType: MultifactorAuthenticationPromptType): Prom // restart the whole flow. The registration flow clears a relevant state, which causes the prompt page to // change from the authentication version to the registration version briefly before we navigate away from the // page. Since there is no legitimate case for the prompt page to transition from authentication => - // registration, only the other way around, this ref prevents that from happening. - // Functionally, it acts as a latch for isReturningUser, so that once it becomes true, it'll never become - // false until this screen unmounts + // registration, only the other way around, this ref prevents that from happening. Functionally, it acts as a + // latch for isReturningUser, so that once it becomes true, it'll never become false until this screen + // unmounts. const wasPreviouslyRegisteredRef = useRef(false); const contentData = MULTIFACTOR_AUTHENTICATION_PROMPT_UI[promptType]; diff --git a/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts b/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts index 549ad0c24463d..2ddcf2f6f1e32 100644 --- a/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts +++ b/src/libs/MultifactorAuthentication/Biometrics/VALUES.ts @@ -206,10 +206,10 @@ const MULTIFACTOR_AUTHENTICATION_VALUES = { API_RESPONSE_MAP, REASON, /** - * Specifically meaningful values for `multifactorAuthenticationPublicKeyIDs` in the `account` Onyx key - * casting `[] as string[]` is necessary to allow us to actually store the value in Onyx. Otherwise the + * Specifically meaningful values for `multifactorAuthenticationPublicKeyIDs` in the `account` Onyx key. + * Casting `[] as string[]` is necessary to allow us to actually store the value in Onyx. Otherwise the * `as const` would mean `[]` becomes `readonly []` (readonly empty array), which is more precise, - * but isn't allowed to be assigned to a `string[]` field + * but isn't allowed to be assigned to a `string[]` field. */ PUBLIC_KEYS_PREVIOUSLY_BUT_NOT_CURRENTLY_REGISTERED: [] as string[], PUBLIC_KEYS_AUTHENTICATION_NEVER_REGISTERED: undefined,