From 2bdcdfa499810f6877f9addd33aae8c67bfa1ed2 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Thu, 20 Feb 2025 10:25:52 -0800 Subject: [PATCH 1/6] Show 2fa warning modal for backend error --- src/libs/actions/Session/index.ts | 5 +++++ .../settings/Security/TwoFactorAuth/DisablePage.tsx | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 093208cbc2a73..c98641b738c53 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -1074,6 +1074,10 @@ function toggleTwoFactorAuth(enable: boolean, twoFactorAuthCode = '') { API.write(WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH, params, {optimisticData, successData, failureData}); } +function clearDisableTwoFactorAuthErrors() { + Onyx.merge(ONYXKEYS.ACCOUNT, {errorFields: {disableTwoFactorAuth: null}}); +} + function updateAuthTokenAndOpenApp(authToken?: string, encryptedAuthToken?: string) { // Update authToken in Onyx and in our local variables so that API requests will use the new authToken updateSessionAuthTokens(authToken, encryptedAuthToken); @@ -1333,4 +1337,5 @@ export { validateUserAndGetAccessiblePolicies, isUserOnPrivateDomain, resetSMSDeliveryFailureStatus, + clearDisableTwoFactorAuthErrors, }; diff --git a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx index 7ff3d7893965c..20767aa36c4de 100644 --- a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx +++ b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx @@ -1,12 +1,15 @@ +import isEmpty from 'lodash/isEmpty'; import React, {useEffect, useRef} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; +import ConfirmModal from '@components/ConfirmModal'; import FixedFooter from '@components/FixedFooter'; import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import {clearDisableTwoFactorAuthErrors} from '@libs/actions/Session'; import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -60,6 +63,16 @@ function DisablePage() { }} /> + ); } From 8148a0492c63fe57381130c1e0be7dd17a1b7811 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Thu, 20 Feb 2025 12:38:02 -0800 Subject: [PATCH 2/6] Navigate back after closing error confirmation modal --- .../settings/Security/TwoFactorAuth/DisablePage.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx index 20767aa36c4de..debbd1ab313cd 100644 --- a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx +++ b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx @@ -1,5 +1,5 @@ import isEmpty from 'lodash/isEmpty'; -import React, {useEffect, useRef} from 'react'; +import React, {useCallback, useEffect, useRef} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; @@ -33,6 +33,11 @@ function DisablePage() { Navigation.navigate(ROUTES.SETTINGS_2FA_DISABLED); }, [account?.requiresTwoFactorAuth]); + const closeModal = useCallback(() => { + clearDisableTwoFactorAuthErrors(); + Navigation.goBack(); + }, []); + return ( From c2e78daf9dd52d96bc3d8dc6ed8fdcfc6377e639 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Thu, 20 Feb 2025 12:38:35 -0800 Subject: [PATCH 3/6] Prevent stray auto complete Enter event from closing modal --- src/components/Button/validateSubmitShortcut/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Button/validateSubmitShortcut/index.ts b/src/components/Button/validateSubmitShortcut/index.ts index 29ba071c25f2f..9bbcf16634f81 100644 --- a/src/components/Button/validateSubmitShortcut/index.ts +++ b/src/components/Button/validateSubmitShortcut/index.ts @@ -11,7 +11,9 @@ import type ValidateSubmitShortcut from './types'; const validateSubmitShortcut: ValidateSubmitShortcut = (isDisabled, isLoading, event) => { const eventTarget = event?.target as HTMLElement; - if (isDisabled || isLoading || eventTarget.nodeName === 'TEXTAREA' || (eventTarget?.contentEditable === 'true' && eventTarget.ariaMultiLine)) { + + // If the event target node is for an input, such as when there's a stray "Enter" event from an autocomplete input, then ignore it because it's not meant for this button + if (isDisabled || isLoading || eventTarget.nodeName === 'TEXTAREA' || eventTarget.nodeName === 'INPUT' || (eventTarget?.contentEditable === 'true' && eventTarget.ariaMultiLine)) { return false; } From 561cc94bd2d12fdebb1a6229a39d5d291809099c Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Thu, 20 Feb 2025 14:14:14 -0800 Subject: [PATCH 4/6] Add errorFields to Account type and use actual field name --- src/libs/actions/Session/index.ts | 2 +- src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx | 2 +- src/types/onyx/Account.ts | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index c98641b738c53..d60335e2b9380 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -1075,7 +1075,7 @@ function toggleTwoFactorAuth(enable: boolean, twoFactorAuthCode = '') { } function clearDisableTwoFactorAuthErrors() { - Onyx.merge(ONYXKEYS.ACCOUNT, {errorFields: {disableTwoFactorAuth: null}}); + Onyx.merge(ONYXKEYS.ACCOUNT, {errorFields: {requiresTwoFactorAuth: null}}); } function updateAuthTokenAndOpenApp(authToken?: string, encryptedAuthToken?: string) { diff --git a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx index debbd1ab313cd..a120f02a4b576 100644 --- a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx +++ b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx @@ -76,7 +76,7 @@ function DisablePage() { shouldShowCancelButton={false} onBackdropPress={closeModal} onCancel={closeModal} - isVisible={!isEmpty(account?.errorFields?.disableTwoFactorAuth ?? {})} + isVisible={!isEmpty(account?.errorFields?.requiresTwoFactorAuth ?? {})} /> ); diff --git a/src/types/onyx/Account.ts b/src/types/onyx/Account.ts index 97fa83dc86702..e095815771839 100644 --- a/src/types/onyx/Account.ts +++ b/src/types/onyx/Account.ts @@ -137,6 +137,9 @@ type Account = { /** Authentication failure errors */ errors?: OnyxCommon.Errors | null; + /** Errors related to specific account fields */ + errorFields?: OnyxCommon.ErrorFields; + /** Authentication success message */ success?: string; From b754a5088ac26b549373f701e81325ed4326a2a7 Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Tue, 4 Mar 2025 13:26:42 -0800 Subject: [PATCH 5/6] Use constant for node names per feedback --- src/components/Button/validateSubmitShortcut/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Button/validateSubmitShortcut/index.ts b/src/components/Button/validateSubmitShortcut/index.ts index 9bbcf16634f81..58995252c20a6 100644 --- a/src/components/Button/validateSubmitShortcut/index.ts +++ b/src/components/Button/validateSubmitShortcut/index.ts @@ -1,5 +1,7 @@ import type ValidateSubmitShortcut from './types'; +const IGNORED_NODE_NAMES = ['TEXTAREA', 'INPUT']; + /** * Validate if the submit shortcut should be triggered depending on the button state * @@ -13,7 +15,7 @@ const validateSubmitShortcut: ValidateSubmitShortcut = (isDisabled, isLoading, e const eventTarget = event?.target as HTMLElement; // If the event target node is for an input, such as when there's a stray "Enter" event from an autocomplete input, then ignore it because it's not meant for this button - if (isDisabled || isLoading || eventTarget.nodeName === 'TEXTAREA' || eventTarget.nodeName === 'INPUT' || (eventTarget?.contentEditable === 'true' && eventTarget.ariaMultiLine)) { + if (isDisabled || isLoading || IGNORED_NODE_NAMES.includes(eventTarget.nodeName) || (eventTarget?.contentEditable === 'true' && eventTarget.ariaMultiLine)) { return false; } From 60d4e6dd2f969648b5db0f78907b442a8cdbe43d Mon Sep 17 00:00:00 2001 From: neil-marcellini Date: Wed, 5 Mar 2025 06:33:14 -0800 Subject: [PATCH 6/6] Explain navigation --- src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx index 0f45b1163c14a..322e1f83b5726 100644 --- a/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx +++ b/src/pages/settings/Security/TwoFactorAuth/DisablePage.tsx @@ -35,6 +35,8 @@ function DisablePage() { const closeModal = useCallback(() => { clearDisableTwoFactorAuthErrors(); + + // Go back to the previous page because the user can't disable 2FA and this page is no longer relevant Navigation.goBack(); }, []);