diff --git a/src/pages/signin/EmailDeliveryFailurePage.tsx b/src/pages/signin/EmailDeliveryFailurePage.tsx
index 0a294e3a6b86..ff16af7dffd9 100644
--- a/src/pages/signin/EmailDeliveryFailurePage.tsx
+++ b/src/pages/signin/EmailDeliveryFailurePage.tsx
@@ -9,7 +9,7 @@ import TextLink from '@components/TextLink';
import useKeyboardState from '@hooks/useKeyboardState';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
-import redirectToSignIn from '@userActions/SignInRedirect';
+import * as Session from '@userActions/Session';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Credentials} from '@src/types/onyx';
@@ -74,7 +74,7 @@ function EmailDeliveryFailurePage({credentials}: EmailDeliveryFailurePageProps)
redirectToSignIn()}
+ onPress={() => Session.clearSignInData()}
role="button"
accessibilityLabel={translate('common.back')}
// disable hover dim for switch
diff --git a/src/pages/signin/SignInModal.tsx b/src/pages/signin/SignInModal.tsx
index 5bce895ab251..bad93b29f8af 100644
--- a/src/pages/signin/SignInModal.tsx
+++ b/src/pages/signin/SignInModal.tsx
@@ -1,4 +1,4 @@
-import React, {useEffect} from 'react';
+import React, {useEffect, useRef} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -12,6 +12,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import SCREENS from '@src/SCREENS';
import type {Session} from '@src/types/onyx';
import SignInPage from './SignInPage';
+import type {SignInPageRef} from './SignInPage';
type SignInModalOnyxProps = {
session: OnyxEntry;
@@ -22,6 +23,7 @@ type SignInModalProps = SignInModalOnyxProps;
function SignInModal({session}: SignInModalProps) {
const theme = useTheme();
const StyleUtils = useStyleUtils();
+ const siginPageRef = useRef(null);
useEffect(() => {
const isAnonymousUser = session?.authTokenType === CONST.AUTH_TOKEN_TYPES.ANONYMOUS;
@@ -40,8 +42,19 @@ function SignInModal({session}: SignInModalProps) {
shouldShowOfflineIndicator={false}
testID={SignInModal.displayName}
>
- Navigation.goBack()} />
-
+ {
+ if (!siginPageRef.current) {
+ Navigation.goBack();
+ return;
+ }
+ siginPageRef.current?.navigateBack();
+ }}
+ />
+
);
}
diff --git a/src/pages/signin/SignInPage.tsx b/src/pages/signin/SignInPage.tsx
index 567612bb1aa6..729faae5e90b 100644
--- a/src/pages/signin/SignInPage.tsx
+++ b/src/pages/signin/SignInPage.tsx
@@ -1,5 +1,6 @@
import {Str} from 'expensify-common';
-import React, {useEffect, useRef, useState} from 'react';
+import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} from 'react';
+import type {ForwardedRef, RefAttributes} from 'react';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import ColorSchemeWrapper from '@components/ColorSchemeWrapper';
@@ -34,6 +35,7 @@ import type {SignInPageLayoutRef} from './SignInPageLayout/types';
import SignUpWelcomeForm from './SignUpWelcomeForm';
import UnlinkLoginForm from './UnlinkLoginForm';
import ValidateCodeForm from './ValidateCodeForm';
+import type {BaseValidateCodeFormRef} from './ValidateCodeForm/BaseValidateCodeForm';
type SignInPageInnerOnyxProps = {
/** The details about the account that the user is signing in with */
@@ -53,6 +55,10 @@ type SignInPageInnerProps = SignInPageInnerOnyxProps & {
shouldEnableMaxHeight?: boolean;
};
+type SignInPageRef = {
+ navigateBack: () => void;
+};
+
type RenderOption = {
shouldShowLoginForm: boolean;
shouldShowEmailDeliveryFailurePage: boolean;
@@ -141,7 +147,7 @@ function getRenderOptions({
};
}
-function SignInPage({credentials, account, activeClients = [], preferredLocale, shouldEnableMaxHeight = true}: SignInPageInnerProps) {
+function SignInPage({credentials, account, activeClients = [], preferredLocale, shouldEnableMaxHeight = true}: SignInPageInnerProps, ref: ForwardedRef) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {translate, formatPhoneNumber} = useLocalize();
@@ -149,6 +155,8 @@ function SignInPage({credentials, account, activeClients = [], preferredLocale,
const safeAreaInsets = useSafeAreaInsets();
const signInPageLayoutRef = useRef(null);
const loginFormRef = useRef(null);
+ const validateCodeFormRef = useRef(null);
+
/** This state is needed to keep track of if user is using recovery code instead of 2fa code,
* and we need it here since welcome text(`welcomeText`) also depends on it */
const [isUsingRecoveryCode, setIsUsingRecoveryCode] = useState(false);
@@ -262,6 +270,25 @@ function SignInPage({credentials, account, activeClients = [], preferredLocale,
loginFormRef.current?.clearDataAndFocus();
};
+ const navigateBack = () => {
+ if (
+ shouldShouldSignUpWelcomeForm ||
+ (!shouldShowAnotherLoginPageOpenedMessage && (shouldShowEmailDeliveryFailurePage || shouldShowUnlinkLoginForm || shouldShowChooseSSOOrMagicCode))
+ ) {
+ Session.clearSignInData();
+ return;
+ }
+
+ if (shouldShowValidateCodeForm) {
+ validateCodeFormRef.current?.clearSignInData();
+ return;
+ }
+
+ Navigation.goBack();
+ };
+ useImperativeHandle(ref, () => ({
+ navigateBack,
+ }));
return (
// Bottom SafeAreaView is removed so that login screen svg displays correctly on mobile.
// The SVG should flow under the Home Indicator on iOS.
@@ -296,6 +323,7 @@ function SignInPage({credentials, account, activeClients = [], preferredLocale,
isVisible={!shouldShowAnotherLoginPageOpenedMessage}
isUsingRecoveryCode={isUsingRecoveryCode}
setIsUsingRecoveryCode={setIsUsingRecoveryCode}
+ ref={validateCodeFormRef}
/>
)}
{!shouldShowAnotherLoginPageOpenedMessage && (
@@ -312,14 +340,16 @@ function SignInPage({credentials, account, activeClients = [], preferredLocale,
type SignInPageProps = SignInPageInnerProps;
type SignInPageOnyxProps = SignInPageInnerOnyxProps;
+const SignInPageWithRef = forwardRef(SignInPage);
-function SignInPageThemeWrapper(props: SignInPageProps) {
+function SignInPageThemeWrapper(props: SignInPageProps, ref: ForwardedRef) {
return (
-
@@ -331,7 +361,7 @@ function SignInPageThemeWrapper(props: SignInPageProps) {
SignInPageThemeWrapper.displayName = 'SignInPage';
-export default withOnyx({
+export default withOnyx, SignInPageOnyxProps>({
account: {key: ONYXKEYS.ACCOUNT},
credentials: {key: ONYXKEYS.CREDENTIALS},
/**
@@ -345,4 +375,6 @@ export default withOnyx({
preferredLocale: {
key: ONYXKEYS.NVP_PREFERRED_LOCALE,
},
-})(SignInPageThemeWrapper);
+})(forwardRef(SignInPageThemeWrapper));
+
+export type {SignInPageRef};
diff --git a/src/pages/signin/SignUpWelcomeForm.tsx b/src/pages/signin/SignUpWelcomeForm.tsx
index 1d8010be14cb..68bb7d10796a 100644
--- a/src/pages/signin/SignUpWelcomeForm.tsx
+++ b/src/pages/signin/SignUpWelcomeForm.tsx
@@ -7,7 +7,6 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Session from '@userActions/Session';
-import redirectToSignIn from '@userActions/SignInRedirect';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Account} from '@src/types/onyx';
import ChangeExpensifyLoginLink from './ChangeExpensifyLoginLink';
@@ -38,11 +37,7 @@ function SignUpWelcomeForm({account}: SignUpWelcomeFormProps) {
pressOnEnter
style={[styles.mb2]}
/>
- {
- redirectToSignIn();
- }}
- />
+ Session.clearSignInData()} />
diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx
index bf0be21adb97..f23b136c76d0 100755
--- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx
+++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.tsx
@@ -1,5 +1,6 @@
import {useIsFocused} from '@react-navigation/native';
-import React, {useCallback, useEffect, useRef, useState} from 'react';
+import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react';
+import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
@@ -51,11 +52,18 @@ type BaseValidateCodeFormProps = WithToggleVisibilityViewProps &
autoComplete: 'sms-otp' | 'one-time-code';
};
+type BaseValidateCodeFormRef = {
+ clearSignInData: () => void;
+};
+
type ValidateCodeFormVariant = 'validateCode' | 'twoFactorAuthCode' | 'recoveryCode';
type FormError = Partial>;
-function BaseValidateCodeForm({account, credentials, session, autoComplete, isUsingRecoveryCode, setIsUsingRecoveryCode, isVisible}: BaseValidateCodeFormProps) {
+function BaseValidateCodeForm(
+ {account, credentials, session, autoComplete, isUsingRecoveryCode, setIsUsingRecoveryCode, isVisible}: BaseValidateCodeFormProps,
+ forwardedRef: ForwardedRef,
+) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
@@ -168,21 +176,25 @@ function BaseValidateCodeForm({account, credentials, session, autoComplete, isUs
/**
* Clear local sign in states
*/
- const clearLocalSignInData = () => {
+ const clearLocalSignInData = useCallback(() => {
setTwoFactorAuthCode('');
setFormError({});
setValidateCode('');
setIsUsingRecoveryCode(false);
setRecoveryCode('');
- };
+ }, [setIsUsingRecoveryCode]);
/**
* Clears local and Onyx sign in states
*/
- const clearSignInData = () => {
+ const clearSignInData = useCallback(() => {
clearLocalSignInData();
SessionActions.clearSignInData();
- };
+ }, [clearLocalSignInData]);
+
+ useImperativeHandle(forwardedRef, () => ({
+ clearSignInData,
+ }));
useEffect(() => {
if (!needToClearError) {
@@ -415,5 +427,7 @@ export default withToggleVisibilityView(
account: {key: ONYXKEYS.ACCOUNT},
credentials: {key: ONYXKEYS.CREDENTIALS},
session: {key: ONYXKEYS.SESSION},
- })(BaseValidateCodeForm),
+ })(forwardRef(BaseValidateCodeForm)),
);
+
+export type {BaseValidateCodeFormRef};
diff --git a/src/pages/signin/ValidateCodeForm/index.android.tsx b/src/pages/signin/ValidateCodeForm/index.android.tsx
index 1edd17517539..1cb05a0470f0 100644
--- a/src/pages/signin/ValidateCodeForm/index.android.tsx
+++ b/src/pages/signin/ValidateCodeForm/index.android.tsx
@@ -1,11 +1,14 @@
-import React from 'react';
+import React, {forwardRef} from 'react';
+import type {ForwardedRef} from 'react';
import BaseValidateCodeForm from './BaseValidateCodeForm';
+import type {BaseValidateCodeFormRef} from './BaseValidateCodeForm';
import type ValidateCodeFormProps from './types';
-function ValidateCodeForm(props: ValidateCodeFormProps) {
+function ValidateCodeForm(props: ValidateCodeFormProps, ref: ForwardedRef) {
return (
@@ -14,4 +17,4 @@ function ValidateCodeForm(props: ValidateCodeFormProps) {
ValidateCodeForm.displayName = 'ValidateCodeForm';
-export default ValidateCodeForm;
+export default forwardRef(ValidateCodeForm);
diff --git a/src/pages/signin/ValidateCodeForm/index.tsx b/src/pages/signin/ValidateCodeForm/index.tsx
index 8c1528ae7409..c656b049345e 100644
--- a/src/pages/signin/ValidateCodeForm/index.tsx
+++ b/src/pages/signin/ValidateCodeForm/index.tsx
@@ -1,11 +1,14 @@
-import React from 'react';
+import React, {forwardRef} from 'react';
+import type {ForwardedRef} from 'react';
import BaseValidateCodeForm from './BaseValidateCodeForm';
+import type {BaseValidateCodeFormRef} from './BaseValidateCodeForm';
import type ValidateCodeFormProps from './types';
-function ValidateCodeForm(props: ValidateCodeFormProps) {
+function ValidateCodeForm(props: ValidateCodeFormProps, ref: ForwardedRef) {
return (
@@ -14,4 +17,4 @@ function ValidateCodeForm(props: ValidateCodeFormProps) {
ValidateCodeForm.displayName = 'ValidateCodeForm';
-export default ValidateCodeForm;
+export default forwardRef(ValidateCodeForm);