diff --git a/src/libs/LoginUtils.js b/src/libs/LoginUtils.js index c6f47566719..4c7e8a7d3d4 100644 --- a/src/libs/LoginUtils.js +++ b/src/libs/LoginUtils.js @@ -1,4 +1,3 @@ -import _ from 'underscore'; import CONST from '../CONST'; /** @@ -21,28 +20,7 @@ function getPhoneNumberWithoutUSCountryCodeAndSpecialChars(phone) { return getPhoneNumberWithoutSpecialChars(phone.replace(/^\+1/, '')); } -/** - * Filter out all non-Expensify partners from login list - * - * @param {Object} loginList - * @returns {Object} - */ -function keepExpensifyPartners(loginList = {}) { - return _.pick(loginList, login => login.partnerName === CONST.EXPENSIFY_PARTNER_NAME); -} - -/** - * Cleans login list that came from the server by only keeping logins with Expensify partner name - * - * @param {Object} loginList - * @returns {Object} - */ -function cleanLoginListServerResponse(loginList = {}) { - return keepExpensifyPartners(loginList); -} - export { getPhoneNumberWithoutSpecialChars, getPhoneNumberWithoutUSCountryCodeAndSpecialChars, - cleanLoginListServerResponse, }; diff --git a/src/libs/Network/NetworkStore.js b/src/libs/Network/NetworkStore.js index 6d4a9dd8856..f4e5364fff7 100644 --- a/src/libs/Network/NetworkStore.js +++ b/src/libs/Network/NetworkStore.js @@ -61,7 +61,7 @@ Onyx.connect({ Onyx.connect({ key: ONYXKEYS.CREDENTIALS, callback: (val) => { - credentials = val || null; + credentials = val || {}; checkRequiredData(); }, }); diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 1e3afedb356..874b45f1fc5 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -15,6 +15,7 @@ import Navigation from '../Navigation/Navigation'; import ROUTES from '../../ROUTES'; import * as SessionUtils from '../SessionUtils'; import getCurrentUrl from '../Navigation/currentUrl'; +import * as Session from './Session'; let currentUserAccountID; let currentUserEmail = ''; @@ -203,8 +204,14 @@ function setUpPoliciesAndNavigate(session) { const makeMeAdmin = url.searchParams.get('makeMeAdmin'); const policyName = url.searchParams.get('policyName'); + // Sign out the current user if we're transitioning from oldDot with a different user + const isTransitioningFromOldDot = Str.startsWith(url.pathname, Str.normalizeUrl(ROUTES.TRANSITION_FROM_OLD_DOT)); + if (isLoggingInAsNewUser && isTransitioningFromOldDot) { + Session.signOut(); + } + const shouldCreateFreePolicy = !isLoggingInAsNewUser - && Str.startsWith(url.pathname, Str.normalizeUrl(ROUTES.TRANSITION_FROM_OLD_DOT)) + && isTransitioningFromOldDot && exitTo === ROUTES.WORKSPACE_NEW; if (shouldCreateFreePolicy) { Policy.createWorkspace(ownerEmail, makeMeAdmin, policyName, true); diff --git a/src/libs/actions/ReimbursementAccount/store.js b/src/libs/actions/ReimbursementAccount/store.js index 34edd34a6a2..1034b655b2b 100644 --- a/src/libs/actions/ReimbursementAccount/store.js +++ b/src/libs/actions/ReimbursementAccount/store.js @@ -31,7 +31,7 @@ let credentials; Onyx.connect({ key: ONYXKEYS.CREDENTIALS, callback: (val) => { - credentials = val; + credentials = val || {}; }, }); diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 7b015e299b1..fd72ef0dac1 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -1,10 +1,8 @@ import Onyx from 'react-native-onyx'; -import Str from 'expensify-common/lib/str'; import _ from 'underscore'; import lodashGet from 'lodash/get'; import ONYXKEYS from '../../../ONYXKEYS'; import redirectToSignIn from '../SignInRedirect'; -import * as DeprecatedAPI from '../../deprecatedAPI'; import CONFIG from '../../../CONFIG'; import Log from '../../Log'; import PushNotification from '../../Notification/PushNotification'; @@ -14,7 +12,6 @@ import * as Localize from '../../Localize'; import UnreadIndicatorUpdater from '../../UnreadIndicatorUpdater'; import Timers from '../../Timers'; import * as Pusher from '../../Pusher/pusher'; -import * as User from '../User'; import * as Authentication from '../../Authentication'; import * as Welcome from '../Welcome'; import * as API from '../../API'; @@ -24,26 +21,9 @@ import DateUtils from '../../DateUtils'; let credentials = {}; Onyx.connect({ key: ONYXKEYS.CREDENTIALS, - callback: val => credentials = val, + callback: val => credentials = val || {}, }); -/** - * Sets API data in the store when we make a successful "Authenticate"/"CreateLogin" request - * - * @param {Object} data - * @param {String} data.accountID - * @param {String} data.authToken - * @param {String} data.email - */ -function setSuccessfulSignInData(data) { - PushNotification.register(data.accountID); - Onyx.merge(ONYXKEYS.SESSION, { - errors: null, - ..._.pick(data, 'authToken', 'accountID', 'email', 'encryptedAuthToken'), - }); - Onyx.set(ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT, true); -} - /** * Clears the Onyx store and redirects user to the sign in page */ @@ -59,7 +39,7 @@ function signOut() { { onyxMethod: CONST.ONYX.METHOD.SET, key: ONYXKEYS.CREDENTIALS, - value: null, + value: {}, }, ]; API.write('LogOut', { @@ -159,64 +139,48 @@ function beginSignIn(login) { } /** - * * Will create a temporary login for the user in the passed authenticate response which is used when * re-authenticating after an authToken expires. * - * @param {String} authToken * @param {String} email - * @return {Promise} + * @param {String} authToken */ -function createTemporaryLogin(authToken, email) { - const autoGeneratedLogin = Str.guid('expensify.cash-'); - const autoGeneratedPassword = Str.guid(); +function signInWithShortLivedAuthToken(email, authToken) { + const optimisticData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: ONYXKEYS.ACCOUNT, + value: { + ...CONST.DEFAULT_ACCOUNT_DATA, + isLoading: true, + }, + }, + ]; - return DeprecatedAPI.CreateLogin({ - authToken, - partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, - partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, - partnerUserID: autoGeneratedLogin, - partnerUserSecret: autoGeneratedPassword, - shouldRetry: false, - forceNetworkRequest: true, - email, - includeEncryptedAuthToken: true, - }) - .then((createLoginResponse) => { - if (createLoginResponse.jsonCode !== 200) { - Onyx.merge(ONYXKEYS.ACCOUNT, {errors: {[DateUtils.getMicroseconds()]: Localize.translate('createLoginResponse.message')}}); - return createLoginResponse; - } - - setSuccessfulSignInData(createLoginResponse); - - // If we have an old generated login for some reason - // we should delete it before storing the new details - if (credentials && credentials.autoGeneratedLogin) { - DeprecatedAPI.DeleteLogin({ - partnerUserID: credentials.autoGeneratedLogin, - partnerName: CONFIG.EXPENSIFY.PARTNER_NAME, - partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD, - shouldRetry: false, - }) - .then((response) => { - if (response.jsonCode === CONST.JSON_CODE.SUCCESS) { - return; - } - - Log.hmmm('[Session] Unable to delete login', false, {message: response.message, jsonCode: response.jsonCode}); - }); - } - - Onyx.merge(ONYXKEYS.CREDENTIALS, { - autoGeneratedLogin, - autoGeneratedPassword, - }); - return createLoginResponse; - }) - .finally(() => { - Onyx.merge(ONYXKEYS.ACCOUNT, {isLoading: false}); - }); + const successData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: ONYXKEYS.ACCOUNT, + value: { + isLoading: false, + }, + }, + ]; + + const failureData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: ONYXKEYS.ACCOUNT, + value: { + isLoading: false, + }, + }, + ]; + + // If the user is transitioning to newDot from a different account on oldDot the credentials may be tied to + // the old account. If so, should not pass the auto-generated login as it is not tied to the account being signed in + const oldPartnerUserID = credentials.login === email ? credentials.autoGeneratedLogin : ''; + API.write('SignInWithShortLivedAuthToken', {authToken, oldPartnerUserID}, {optimisticData, successData, failureData}); } /** @@ -262,29 +226,6 @@ function signIn(password, twoFactorAuthCode) { API.write('SigninUser', {email: credentials.login, password, twoFactorAuthCode}, {optimisticData, successData, failureData}); } -/** - * Uses a short lived authToken to continue a user's session from OldDot - * - * @param {String} email - * @param {String} shortLivedAuthToken - * @param {String} exitTo - */ -function signInWithShortLivedAuthToken(email, shortLivedAuthToken) { - Onyx.merge(ONYXKEYS.ACCOUNT, {...CONST.DEFAULT_ACCOUNT_DATA, isLoading: true}); - - createTemporaryLogin(shortLivedAuthToken, email) - .then((response) => { - if (response.jsonCode !== CONST.JSON_CODE.SUCCESS) { - return; - } - - User.getUserDetails(); - Onyx.merge(ONYXKEYS.ACCOUNT, {success: true}); - }).finally(() => { - Onyx.merge(ONYXKEYS.ACCOUNT, {isLoading: false}); - }); -} - /** * User forgot the password so let's send them the link to reset their password */ @@ -361,7 +302,7 @@ function invalidateAuthToken() { function clearSignInData() { Onyx.multiSet({ [ONYXKEYS.ACCOUNT]: null, - [ONYXKEYS.CREDENTIALS]: null, + [ONYXKEYS.CREDENTIALS]: {}, }); } diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 6a4a0775fb4..234fc9c1e0a 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -15,10 +15,8 @@ import NetworkConnection from '../NetworkConnection'; import Growl from '../Growl'; import * as Localize from '../Localize'; import * as Link from './Link'; -import getSkinToneEmojiFromIndex from '../../components/EmojiPicker/getSkinToneEmojiFromIndex'; import * as SequentialQueue from '../Network/SequentialQueue'; import PusherUtils from '../PusherUtils'; -import * as LoginUtils from '../LoginUtils'; let currentUserAccountID = ''; Onyx.connect({ @@ -89,46 +87,6 @@ function closeAccount(message) { }); } -/** - * Fetches the data needed for user settings - */ -function getUserDetails() { - DeprecatedAPI.Get({ - returnValueList: 'account, loginList, nameValuePairs', - nvpNames: [ - CONST.NVP.PAYPAL_ME_ADDRESS, - CONST.NVP.PREFERRED_EMOJI_SKIN_TONE, - CONST.NVP.FREQUENTLY_USED_EMOJIS, - CONST.NVP.BLOCKED_FROM_CONCIERGE, - ].join(','), - }) - .then((response) => { - // Update the User onyx key - const isSubscribedToNewsletter = lodashGet(response, 'account.subscribed', true); - const validatedStatus = lodashGet(response, 'account.validated', false); - Onyx.merge(ONYXKEYS.USER, {isSubscribedToNewsletter: !!isSubscribedToNewsletter, validated: !!validatedStatus}); - - // Update login list - const loginList = LoginUtils.cleanLoginListServerResponse(response.loginList); - Onyx.set(ONYXKEYS.LOGIN_LIST, loginList); - - // Update the nvp_payPalMeAddress NVP - const payPalMeAddress = lodashGet(response, `nameValuePairs.${CONST.NVP.PAYPAL_ME_ADDRESS}`, ''); - Onyx.merge(ONYXKEYS.NVP_PAYPAL_ME_ADDRESS, payPalMeAddress); - - // Update the blockedFromConcierge NVP - const blockedFromConcierge = lodashGet(response, `nameValuePairs.${CONST.NVP.BLOCKED_FROM_CONCIERGE}`, {}); - Onyx.merge(ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE, blockedFromConcierge); - - const preferredSkinTone = lodashGet(response, `nameValuePairs.${CONST.NVP.PREFERRED_EMOJI_SKIN_TONE}`, {}); - Onyx.merge(ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE, - getSkinToneEmojiFromIndex(preferredSkinTone).skinTone); - - const frequentlyUsedEmojis = lodashGet(response, `nameValuePairs.${CONST.NVP.FREQUENTLY_USED_EMOJIS}`, []); - Onyx.set(ONYXKEYS.FREQUENTLY_USED_EMOJIS, frequentlyUsedEmojis); - }); -} - /** * Resends a validation link to a given login * @@ -179,8 +137,7 @@ function setSecondaryLoginAndNavigate(login, password) { password, }).then((response) => { if (response.jsonCode === 200) { - const loginList = LoginUtils.cleanLoginListServerResponse(response.loginList); - Onyx.set(ONYXKEYS.LOGIN_LIST, loginList); + Onyx.set(ONYXKEYS.LOGIN_LIST, response.loginList); Navigation.navigate(ROUTES.SETTINGS_PROFILE); return; } @@ -481,7 +438,6 @@ function generateStatementPDF(period) { export { updatePassword, closeAccount, - getUserDetails, resendValidateCode, updateNewsletterSubscription, setSecondaryLoginAndNavigate, diff --git a/tests/actions/SessionTest.js b/tests/actions/SessionTest.js index 41f1e3379a6..86e288104ba 100644 --- a/tests/actions/SessionTest.js +++ b/tests/actions/SessionTest.js @@ -28,7 +28,7 @@ test('Authenticate is called with saved credentials when a session expires', () let credentials; Onyx.connect({ key: ONYXKEYS.CREDENTIALS, - callback: val => credentials = val, + callback: val => credentials = val || {}, }); let session; diff --git a/tests/unit/NetworkTest.js b/tests/unit/NetworkTest.js index f0cb04f7cd5..1586e1a10c7 100644 --- a/tests/unit/NetworkTest.js +++ b/tests/unit/NetworkTest.js @@ -703,7 +703,7 @@ describe('NetworkTests', () => { // Given a simulated a condition where the credentials have not yet been read from storage and we are offline return Onyx.multiSet({ [ONYXKEYS.NETWORK]: {isOffline: true}, - [ONYXKEYS.CREDENTIALS]: null, + [ONYXKEYS.CREDENTIALS]: {}, [ONYXKEYS.SESSION]: null, }) .then(() => {