Skip to content
Merged
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 0 additions & 21 deletions src/Expensify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import DeeplinkWrapper from './components/DeeplinkWrapper';
import EmojiPicker from './components/EmojiPicker/EmojiPicker';
import FocusModeNotification from './components/FocusModeNotification';
import GrowlNotification from './components/GrowlNotification';
import RequireTwoFactorAuthenticationModal from './components/RequireTwoFactorAuthenticationModal';
import AppleAuthWrapper from './components/SignInButtons/AppleAuthWrapper';
import SplashScreenHider from './components/SplashScreenHider';
import TestToolsModal from './components/TestToolsModal';
Expand Down Expand Up @@ -43,7 +42,6 @@ import ONYXKEYS from './ONYXKEYS';
import PopoverReportActionContextMenu from './pages/home/report/ContextMenu/PopoverReportActionContextMenu';
import * as ReportActionContextMenu from './pages/home/report/ContextMenu/ReportActionContextMenu';
import type {Route} from './ROUTES';
import ROUTES from './ROUTES';
import SplashScreenStateContext from './SplashScreenStateContext';
import type {ScreenShareRequest} from './types/onyx';

Expand Down Expand Up @@ -91,7 +89,6 @@ function Expensify() {
const [session] = useOnyx(ONYXKEYS.SESSION);
const [lastRoute] = useOnyx(ONYXKEYS.LAST_ROUTE);
const [userMetadata] = useOnyx(ONYXKEYS.USER_METADATA);
const [shouldShowRequire2FAModal, setShouldShowRequire2FAModal] = useState(false);
const [isCheckingPublicRoom] = useOnyx(ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, {initWithStoredValues: false});
const [updateAvailable] = useOnyx(ONYXKEYS.UPDATE_AVAILABLE, {initWithStoredValues: false});
const [updateRequired] = useOnyx(ONYXKEYS.UPDATE_REQUIRED, {initWithStoredValues: false});
Expand All @@ -102,13 +99,6 @@ function Expensify() {

useDebugShortcut();

useEffect(() => {
if (!account?.needsTwoFactorAuthSetup || account.requiresTwoFactorAuth) {
return;
}
setShouldShowRequire2FAModal(true);
}, [account?.needsTwoFactorAuthSetup, account?.requiresTwoFactorAuth]);

const [initialUrl, setInitialUrl] = useState<string | null>(null);

useEffect(() => {
Expand Down Expand Up @@ -287,16 +277,6 @@ function Expensify() {
/>
) : null}
{focusModeNotification ? <FocusModeNotification /> : null}
{shouldShowRequire2FAModal ? (
<RequireTwoFactorAuthenticationModal
onSubmit={() => {
setShouldShowRequire2FAModal(false);
Navigation.navigate(ROUTES.SETTINGS_2FA_ROOT.getRoute(ROUTES.HOME));
}}
isVisible
description={translate('twoFactorAuth.twoFactorAuthIsRequiredForAdminsDescription')}
/>
) : null}
</>
)}

Expand All @@ -307,7 +287,6 @@ function Expensify() {
authenticated={isAuthenticated}
lastVisitedPath={lastVisitedPath as Route}
initialUrl={initialUrl}
shouldShowRequire2FAModal={shouldShowRequire2FAModal}
/>
)}
{shouldHideSplash && <SplashScreenHider onHide={onSplashHide} />}
Expand Down
1 change: 1 addition & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const ROUTES = {
ENABLE_PAYMENTS: 'enable-payments',
WALLET_STATEMENT_WITH_DATE: 'statements/:yearMonth',
SIGN_IN_MODAL: 'sign-in-modal',
REQUIRE_TWO_FACTOR_AUTH: '2fa-required',

BANK_ACCOUNT: 'bank-account',
BANK_ACCOUNT_NEW: 'bank-account/new',
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ const SCREENS = {
DESKTOP_SIGN_IN_REDIRECT: 'DesktopSignInRedirect',
SAML_SIGN_IN: 'SAMLSignIn',
WORKSPACE_JOIN_USER: 'WorkspaceJoinUser',
REQUIRE_TWO_FACTOR_AUTH: 'RequireTwoFactorAuth',

MONEY_REQUEST: {
CREATE: 'Money_Request_Create',
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Illustrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ import CreditCardEyes from '@assets/images/simple-illustrations/simple-illustrat
import CreditCardsNewGreen from '@assets/images/simple-illustrations/simple-illustration__creditcards--green.svg';
import EmailAddress from '@assets/images/simple-illustrations/simple-illustration__email-address.svg';
import EmptyState from '@assets/images/simple-illustrations/simple-illustration__empty-state.svg';
import Encryption from '@assets/images/simple-illustrations/simple-illustration__encryption.svg';
import EnvelopeReceipt from '@assets/images/simple-illustrations/simple-illustration__envelopereceipt.svg';
import Filters from '@assets/images/simple-illustrations/simple-illustration__filters.svg';
import Flash from '@assets/images/simple-illustrations/simple-illustration__flash.svg';
Expand Down Expand Up @@ -155,6 +156,7 @@ import TurtleInShell from '@assets/images/turtle-in-shell.svg';

export {
Abracadabra,
Encryption,
BankArrowPink,
BankMouseGreen,
BankUserGreen,
Expand Down
4 changes: 3 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,9 @@ const translations = {
enableTwoFactorAuth: 'Enable two-factor authentication',
pleaseEnableTwoFactorAuth: 'Please enable two-factor authentication.',
twoFactorAuthIsRequiredDescription: 'For security purposes, Xero requires two-factor authentication to connect the integration.',
twoFactorAuthIsRequiredForAdminsDescription: 'Two-factor authentication is required for Xero workspace admins. Please enable two-factor authentication to continue.',
twoFactorAuthIsRequiredForAdminsHeader: 'Two-factor authentication required',
twoFactorAuthIsRequiredForAdminsTitle: 'You need to enable two-factor authentication',
twoFactorAuthIsRequiredForAdminsDescription: 'The Xero accounting connection requires the use of two-factor authentication. To continue using Expensify, please enable it.',
Comment on lines +1396 to +1398

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be nice to remove the ForAdmins part of these keys since the text doesn't say anything about admins, what do y'all think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it doesn't mention about admin, but the page will only show in a case where a workspace (connected to Xero) admin without 2FA enabled login.

twoFactorAuthCannotDisable: 'Cannot disable 2FA',
twoFactorAuthRequired: 'Two-factor authentication (2FA) is required for your Xero connection and cannot be disabled.',
},
Expand Down
5 changes: 3 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1392,8 +1392,9 @@ const translations = {
enableTwoFactorAuth: 'Activar la autenticación de dos factores',
pleaseEnableTwoFactorAuth: 'Activa la autenticación de dos factores.',
twoFactorAuthIsRequiredDescription: 'Por razones de seguridad, Xero requiere la autenticación de dos factores para conectar la integración.',
twoFactorAuthIsRequiredForAdminsDescription:
'La autenticación de dos factores es necesaria para los administradores del área de trabajo de Xero. Activa la autenticación de dos factores para continuar.',
twoFactorAuthIsRequiredForAdminsHeader: 'Se requiere autenticación de dos factores',
twoFactorAuthIsRequiredForAdminsTitle: 'Debes habilitar la autenticación de dos factores',
twoFactorAuthIsRequiredForAdminsDescription: 'La conexión contable con Xero requiere el uso de autenticación de dos factores. Para seguir usando Expensify, por favor, habilítala.',
twoFactorAuthCannotDisable: 'No se puede desactivar la autenticación de dos factores (2FA)',
twoFactorAuthRequired: 'La autenticación de dos factores (2FA) es obligatoria para tu conexión a Xero y no se puede desactivar.',
},
Expand Down
43 changes: 40 additions & 3 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {RouteProp} from '@react-navigation/native';
import {findFocusedRoute, useNavigation} from '@react-navigation/native';
import React, {memo, useEffect, useMemo, useRef} from 'react';
import React, {memo, useEffect, useMemo, useRef, useState} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import Onyx, {withOnyx} from 'react-native-onyx';
import Onyx, {useOnyx, withOnyx} from 'react-native-onyx';
import ActiveGuidesEventListener from '@components/ActiveGuidesEventListener';
import ActiveWorkspaceContextProvider from '@components/ActiveWorkspaceProvider';
import ComposeProviders from '@components/ComposeProviders';
Expand Down Expand Up @@ -34,6 +34,7 @@ import PusherConnectionManager from '@libs/PusherConnectionManager';
import * as SessionUtils from '@libs/SessionUtils';
import ConnectionCompletePage from '@pages/ConnectionCompletePage';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import RequireTwoFactorAuthenticationPage from '@pages/RequireTwoFactorAuthenticationPage';
import DesktopSignInRedirectPage from '@pages/signin/DesktopSignInRedirectPage';
import * as App from '@userActions/App';
import * as Download from '@userActions/Download';
Expand Down Expand Up @@ -216,8 +217,10 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
const {toggleSearch} = useSearchRouterContext();

const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const modal = useRef<OnyxTypes.Modal>({});
const {isOnboardingCompleted} = useOnboardingFlowRouter();
const [shouldShowRequire2FAPage, setShouldShowRequire2FAPage] = useState(!!account?.needsTwoFactorAuthSetup && !account.requiresTwoFactorAuth);
const navigation = useNavigation();

useEffect(() => {
Expand All @@ -240,6 +243,20 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
};
}, [theme]);

useEffect(() => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also add a comment here for these 2 new useEffects

if (!account?.needsTwoFactorAuthSetup || !!account.requiresTwoFactorAuth || shouldShowRequire2FAPage) {
return;
}
setShouldShowRequire2FAPage(true);
}, [account?.needsTwoFactorAuthSetup, account?.requiresTwoFactorAuth, shouldShowRequire2FAPage]);

useEffect(() => {
if (!shouldShowRequire2FAPage) {
return;
}
Navigation.navigate(ROUTES.REQUIRE_TWO_FACTOR_AUTH);
}, [shouldShowRequire2FAPage]);

useEffect(() => {
const shortcutsOverviewShortcutConfig = CONST.KEYBOARD_SHORTCUTS.SHORTCUTS;
const searchShortcutConfig = CONST.KEYBOARD_SHORTCUTS.SEARCH;
Expand Down Expand Up @@ -537,7 +554,20 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
name={NAVIGATORS.RIGHT_MODAL_NAVIGATOR}
options={rootNavigatorScreenOptions.rightModalNavigator}
component={RightModalNavigator}
listeners={modalScreenListenersWithCancelSearch}
listeners={{
...modalScreenListenersWithCancelSearch,
beforeRemove: () => {
modalScreenListenersWithCancelSearch.beforeRemove();

// When a 2FA RHP page is closed, if the 2FA require page is visible and the user has now enabled the 2FA, then remove the 2FA require page from the navigator.
const routeParams = navigation.getState()?.routes?.at(-1)?.params;
const screen = routeParams && 'screen' in routeParams ? routeParams.screen : '';
if (!shouldShowRequire2FAPage || !account?.requiresTwoFactorAuth || screen !== SCREENS.RIGHT_MODAL.TWO_FACTOR_AUTH) {
return;
}
setShouldShowRequire2FAPage(false);
},
}}
/>
<RootStack.Screen
name={NAVIGATORS.LEFT_MODAL_NAVIGATOR}
Expand Down Expand Up @@ -584,6 +614,13 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
}}
/>
)}
{shouldShowRequire2FAPage && (
<RootStack.Screen
name={SCREENS.REQUIRE_TWO_FACTOR_AUTH}
options={{...rootNavigatorScreenOptions.fullScreen, gestureEnabled: false}}
component={RequireTwoFactorAuthenticationPage}
/>
)}
<RootStack.Screen
name={SCREENS.WORKSPACE_JOIN_USER}
options={{
Expand Down
6 changes: 6 additions & 0 deletions src/libs/Navigation/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@ function popToTop() {
navigationRef.current?.dispatch(StackActions.popToTop());
}

function popRootToTop() {
const rootState = navigationRef.getRootState();
navigationRef.current?.dispatch({...StackActions.popToTop(), target: rootState.key});
}

function removeScreenFromNavigationState(screen: string) {
isNavigationReady().then(() => {
navigationRef.current?.dispatch((state) => {
Expand Down Expand Up @@ -616,6 +621,7 @@ export default {
setNavigationActionToMicrotaskQueue,
navigateToReportWithPolicyCheck,
popToTop,
popRootToTop,
removeScreenFromNavigationState,
removeScreenByKey,
getReportRouteByID,
Expand Down
Loading