diff --git a/src/components/SAMLLoadingIndicator.js b/src/components/SAMLLoadingIndicator.js
new file mode 100644
index 000000000000..d00c5a032a72
--- /dev/null
+++ b/src/components/SAMLLoadingIndicator.js
@@ -0,0 +1,42 @@
+import React from 'react';
+import {StyleSheet, View} from 'react-native';
+import useLocalize from '@hooks/useLocalize';
+import styles from '@styles/styles';
+import themeColors from '@styles/themes/default';
+import Icon from './Icon';
+import * as Expensicons from './Icon/Expensicons';
+import * as Illustrations from './Icon/Illustrations';
+import Text from './Text';
+
+function SAMLLoadingIndicator() {
+ const {translate} = useLocalize();
+ return (
+
+
+
+
+
+ {translate('samlSignIn.launching')}
+
+ {translate('samlSignIn.oneMoment')}
+
+
+
+
+
+
+ );
+}
+
+SAMLLoadingIndicator.displayName = 'SAMLLoadingIndicator';
+
+export default SAMLLoadingIndicator;
diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.js b/src/pages/LogInWithShortLivedAuthTokenPage.js
index 8534961b3337..16d0c3909d62 100644
--- a/src/pages/LogInWithShortLivedAuthTokenPage.js
+++ b/src/pages/LogInWithShortLivedAuthTokenPage.js
@@ -125,5 +125,4 @@ LogInWithShortLivedAuthTokenPage.displayName = 'LogInWithShortLivedAuthTokenPage
export default withOnyx({
account: {key: ONYXKEYS.ACCOUNT},
- session: {key: ONYXKEYS.SESSION},
})(LogInWithShortLivedAuthTokenPage);
diff --git a/src/pages/signin/SAMLSignInPage/index.js b/src/pages/signin/SAMLSignInPage/index.js
index b93e05c7a2b1..ec3cc01197bd 100644
--- a/src/pages/signin/SAMLSignInPage/index.js
+++ b/src/pages/signin/SAMLSignInPage/index.js
@@ -1,14 +1,7 @@
import PropTypes from 'prop-types';
import React, {useEffect} from 'react';
-import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
-import Icon from '@components/Icon';
-import * as Expensicons from '@components/Icon/Expensicons';
-import * as Illustrations from '@components/Icon/Illustrations';
-import Text from '@components/Text';
-import useLocalize from '@hooks/useLocalize';
-import useTheme from '@styles/themes/useTheme';
-import useThemeStyles from '@styles/useThemeStyles';
+import SAMLLoadingIndicator from '@components/SAMLLoadingIndicator';
import CONFIG from '@src/CONFIG';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -25,39 +18,11 @@ const defaultProps = {
};
function SAMLSignInPage({credentials}) {
- const theme = useTheme();
- const styles = useThemeStyles();
- const {translate} = useLocalize();
-
useEffect(() => {
window.open(`${CONFIG.EXPENSIFY.SAML_URL}?email=${credentials.login}&referer=${CONFIG.EXPENSIFY.EXPENSIFY_CASH_REFERER}`, '_self');
}, [credentials.login]);
- return (
-
-
-
-
-
- {translate('samlSignIn.launching')}
-
- {translate('samlSignIn.oneMoment')}
-
-
-
-
-
-
- );
+ return ;
}
SAMLSignInPage.propTypes = propTypes;
diff --git a/src/pages/signin/SAMLSignInPage/index.native.js b/src/pages/signin/SAMLSignInPage/index.native.js
new file mode 100644
index 000000000000..502e26e337b9
--- /dev/null
+++ b/src/pages/signin/SAMLSignInPage/index.native.js
@@ -0,0 +1,95 @@
+import PropTypes from 'prop-types';
+import React, {useCallback, useState} from 'react';
+import {withOnyx} from 'react-native-onyx';
+import WebView from 'react-native-webview';
+import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
+import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import SAMLLoadingIndicator from '@components/SAMLLoadingIndicator';
+import ScreenWrapper from '@components/ScreenWrapper';
+import getPlatform from '@libs/getPlatform';
+import Navigation from '@libs/Navigation/Navigation';
+import * as Session from '@userActions/Session';
+import CONFIG from '@src/CONFIG';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
+
+const propTypes = {
+ /** The credentials of the logged in person */
+ credentials: PropTypes.shape({
+ /** The email/phone the user logged in with */
+ login: PropTypes.string,
+ }),
+};
+
+const defaultProps = {
+ credentials: {},
+};
+
+function SAMLSignInPage({credentials}) {
+ const samlLoginURL = `${CONFIG.EXPENSIFY.SAML_URL}?email=${credentials.login}&referer=${CONFIG.EXPENSIFY.EXPENSIFY_CASH_REFERER}&platform=${getPlatform()}`;
+ const [showNavigation, shouldShowNavigation] = useState(true);
+
+ /**
+ * Handles in-app navigation once we get a response back from Expensify
+ *
+ * @param {String} params.url
+ */
+ const handleNavigationStateChange = useCallback(
+ ({url}) => {
+ // If we've gotten a callback then remove the option to navigate back to the sign in page
+ if (url.includes('loginCallback')) {
+ shouldShowNavigation(false);
+ }
+
+ const searchParams = new URLSearchParams(new URL(url).search);
+ if (searchParams.has('shortLivedAuthToken')) {
+ const shortLivedAuthToken = searchParams.get('shortLivedAuthToken');
+ Session.signInWithShortLivedAuthToken(credentials.login, shortLivedAuthToken);
+ }
+
+ // If the login attempt is unsuccessful, set the error message for the account and redirect to sign in page
+ if (searchParams.has('error')) {
+ Session.clearSignInData();
+ Session.setAccountError(searchParams.get('error'));
+ Navigation.navigate(ROUTES.HOME);
+ }
+ },
+ [credentials.login, shouldShowNavigation],
+ );
+
+ return (
+
+ {showNavigation && (
+ {
+ Session.clearSignInData();
+ Navigation.navigate(ROUTES.HOME);
+ }}
+ />
+ )}
+
+ }
+ onNavigationStateChange={handleNavigationStateChange}
+ />
+
+
+ );
+}
+
+SAMLSignInPage.propTypes = propTypes;
+SAMLSignInPage.defaultProps = defaultProps;
+SAMLSignInPage.displayName = 'SAMLSignInPage';
+
+export default withOnyx({
+ credentials: {key: ONYXKEYS.CREDENTIALS},
+})(SAMLSignInPage);
diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js
index 24b16177e6ff..6676dc99b911 100644
--- a/src/pages/signin/SignInPage.js
+++ b/src/pages/signin/SignInPage.js
@@ -10,7 +10,6 @@ import useLocalize from '@hooks/useLocalize';
import useSafeAreaInsets from '@hooks/useSafeAreaInsets';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as ActiveClientManager from '@libs/ActiveClientManager';
-import getPlatform from '@libs/getPlatform';
import * as Localize from '@libs/Localize';
import Log from '@libs/Log';
import Navigation from '@libs/Navigation/Navigation';
@@ -103,15 +102,9 @@ function getRenderOptions({hasLogin, hasValidateCode, account, isPrimaryLogin, i
const isSAMLRequired = Boolean(account.isSAMLRequired);
const hasEmailDeliveryFailure = Boolean(account.hasEmailDeliveryFailure);
- // SAML is temporarily restricted to users on the beta or to users signing in on web and mweb
- let shouldShowChooseSSOOrMagicCode = false;
- let shouldInitiateSAMLLogin = false;
- const platform = getPlatform();
- if (platform === CONST.PLATFORM.WEB || platform === CONST.PLATFORM.DESKTOP) {
- // True if the user has SAML required and we haven't already initiated SAML for their account
- shouldInitiateSAMLLogin = hasAccount && hasLogin && isSAMLRequired && !hasInitiatedSAMLLogin && account.isLoading;
- shouldShowChooseSSOOrMagicCode = hasAccount && hasLogin && isSAMLEnabled && !isSAMLRequired && !isUsingMagicCode;
- }
+ // True if the user has SAML required and we haven't already initiated SAML for their account
+ const shouldInitiateSAMLLogin = hasAccount && hasLogin && isSAMLRequired && !hasInitiatedSAMLLogin && account.isLoading;
+ const shouldShowChooseSSOOrMagicCode = hasAccount && hasLogin && isSAMLEnabled && !isSAMLRequired && !isUsingMagicCode;
// SAML required users may reload the login page after having already entered their login details, in which
// case we want to clear their sign in data so they don't end up in an infinite loop redirecting back to their
@@ -167,6 +160,19 @@ function SignInPageInner({credentials, account, isInModal, activeClients, prefer
}
App.setLocale(Localize.getDevicePreferredLocale());
}, [preferredLocale]);
+ useEffect(() => {
+ if (credentials.login) {
+ return;
+ }
+
+ // If we don't have a login set, reset the user's SAML login preferences
+ if (isUsingMagicCode) {
+ setIsUsingMagicCode(false);
+ }
+ if (hasInitiatedSAMLLogin) {
+ setHasInitiatedSAMLLogin(false);
+ }
+ }, [credentials.login, isUsingMagicCode, setIsUsingMagicCode, hasInitiatedSAMLLogin, setHasInitiatedSAMLLogin]);
const {
shouldShowLoginForm,
@@ -231,7 +237,7 @@ function SignInPageInner({credentials, account, isInModal, activeClients, prefer
if (shouldShowEmailDeliveryFailurePage || shouldShowChooseSSOOrMagicCode) {
welcomeText = '';
}
- } else if (!shouldInitiateSAMLLogin) {
+ } else if (!shouldInitiateSAMLLogin && !hasInitiatedSAMLLogin) {
Log.warn('SignInPage in unexpected state!');
}
@@ -261,7 +267,6 @@ function SignInPageInner({credentials, account, isInModal, activeClients, prefer
)}
{shouldShowUnlinkLoginForm && }
diff --git a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js
index e409836005c4..7c48d557cd16 100755
--- a/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js
+++ b/src/pages/signin/ValidateCodeForm/BaseValidateCodeForm.js
@@ -70,9 +70,6 @@ const propTypes = {
/** Function to change `isUsingRecoveryCode` state when user toggles between 2fa code and recovery code */
setIsUsingRecoveryCode: PropTypes.func.isRequired,
- /** Function to change `isUsingMagicCode` state when the user goes back to the login page */
- setIsUsingMagicCode: PropTypes.func.isRequired,
-
...withLocalizePropTypes,
};
@@ -210,8 +207,6 @@ function BaseValidateCodeForm(props) {
* Clears local and Onyx sign in states
*/
const clearSignInData = () => {
- // Reset the user's preference for signing in with SAML versus magic codes
- props.setIsUsingMagicCode(false);
clearLocalSignInData();
Session.clearSignInData();
};