diff --git a/src/libs/Middleware/HandleDeletedAccount.ts b/src/libs/Middleware/HandleDeletedAccount.ts index ec5532baa230d..0a7be16a1b90e 100644 --- a/src/libs/Middleware/HandleDeletedAccount.ts +++ b/src/libs/Middleware/HandleDeletedAccount.ts @@ -12,7 +12,7 @@ const handleDeletedAccount: Middleware = (requestResponse) => if (response?.jsonCode !== 408 || !response?.message?.includes('The account you are trying to use is deleted.')) { return response; } - signOutAndRedirectToSignIn(true, false, true, true); + signOutAndRedirectToSignIn(true, false, false, true); }); export default handleDeletedAccount; diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index c705be863c1c3..54e2f9875de96 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -113,6 +113,14 @@ Onyx.connect({ callback: (val) => (preferredLocale = val ?? null), }); +let activePolicyID: OnyxEntry; +Onyx.connect({ + key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, + callback: (newActivePolicyID) => { + activePolicyID = newActivePolicyID; + }, +}); + function isSupportAuthToken(): boolean { return session.authTokenType === CONST.AUTH_TOKEN_TYPES.SUPPORT; } @@ -228,7 +236,7 @@ function isExpiredSession(sessionCreationDate: number): boolean { return new Date().getTime() - sessionCreationDate >= CONST.SESSION_EXPIRATION_TIME_MS; } -function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSession?: boolean, killHybridApp = true, shouldForceUseStashedSession?: boolean) { +function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSession?: boolean, shouldKillHybridApp = true, shouldForceUseStashedSession?: boolean) { Log.info('Redirecting to Sign In because signOut() was called'); hideContextMenu(false); @@ -249,15 +257,18 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess } // In the HybridApp, we want the Old Dot to handle the sign out process - if (CONFIG.IS_HYBRID_APP && killHybridApp) { + if (CONFIG.IS_HYBRID_APP && shouldKillHybridApp) { HybridAppModule.closeReactNativeApp({shouldSignOut: true, shouldSetNVP: false}); return; } - // We'll only call signOut if we're not stashing the session and this is not a supportal session, + + const isSupportal = isSupportAuthToken(); + const shouldRestoreStashedSession = isSupportal || shouldForceUseStashedSession; + + // We'll only call signOut if we're not stashing the session and not restoring a stashed session, // otherwise we'll call the API to invalidate the autogenerated credentials used for infinite // session. - const isSupportal = isSupportAuthToken(); - const signOutPromise: Promise = !isSupportal && !shouldStashSession ? signOut() : Promise.resolve(); + const signOutPromise: Promise = !shouldRestoreStashedSession && !shouldStashSession ? signOut() : Promise.resolve(); // The function redirectToSignIn will clear the whole storage, so let's create our onyx params // updates for the credentials before we call it @@ -272,6 +283,7 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess [ONYXKEYS.STASHED_SESSION]: session, }; } + // If this is a supportal token, and we've received the parameters to stashSession as true, and // we already have a stashedSession, that means we are supportaled, currently supportaling // into another account and we want to keep the stashed data from the original account. @@ -282,16 +294,26 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess }; } - // Now if this is a supportal access or force use stashed session, we do not want to stash the current session and we have a - // stashed session, then we need to restore the stashed session instead of completely logging out - if ((isSupportal || shouldForceUseStashedSession) && !shouldStashSession && hasStashedSession()) { + // If we should restore the stashed session, and we do not want to stash the current session, and we have a + // stashed session, then switch the account instead of completely logging out. + if (shouldRestoreStashedSession && !shouldStashSession && hasStashedSession()) { + if (CONFIG.IS_HYBRID_APP) { + HybridAppModule.switchAccount({ + newDotCurrentAccountEmail: stashedSession.email ?? '', + authToken: stashedSession.authToken ?? '', + // eslint-disable-next-line rulesdir/no-default-id-values + policyID: activePolicyID ?? '', + accountID: session.accountID ? String(session.accountID) : '', + }); + } + onyxSetParams = { [ONYXKEYS.CREDENTIALS]: stashedCredentials, [ONYXKEYS.SESSION]: stashedSession, }; } - if (isSupportal && !shouldStashSession && !hasStashedSession()) { - Log.info('No stashed session found for supportal access, clearing the session'); + if (shouldRestoreStashedSession && !shouldStashSession && !hasStashedSession()) { + Log.info('No stashed session found, clearing the session'); } // Wait for signOut (if called), then redirect and update Onyx. @@ -548,6 +570,8 @@ type HybridAppSettings = { encryptedAuthToken: string; nudgeMigrationTimestamp?: string; oldDotOriginalAccountEmail?: string; + stashedAuthToken?: string; + stashedAccountID?: string; requiresTwoFactorAuth: boolean; needsTwoFactorAuthSetup: boolean; }; @@ -566,6 +590,8 @@ function signInAfterTransitionFromOldDot(hybridAppSettings: string) { isSingleNewDotEntry, primaryLogin, oldDotOriginalAccountEmail, + stashedAuthToken, + stashedAccountID, requiresTwoFactorAuth, needsTwoFactorAuthSetup, } = JSON.parse(hybridAppSettings) as HybridAppSettings; @@ -583,7 +609,15 @@ function signInAfterTransitionFromOldDot(hybridAppSettings: string) { // This section controls copilot changes const currentUserEmail = getCurrentUserEmail(); - // If ND and OD account are the same - do nothing + // If OD is in copilot, stash the original account data + if (oldDotOriginalAccountEmail && oldDotOriginalAccountEmail !== email) { + return Onyx.multiSet({ + [ONYXKEYS.STASHED_SESSION]: {email: oldDotOriginalAccountEmail, authToken: stashedAuthToken, accountID: Number(stashedAccountID)}, + [ONYXKEYS.STASHED_CREDENTIALS]: {autoGeneratedLogin, autoGeneratedPassword}, + }); + } + + // If OD and ND account are the same - do nothing if (email === currentUserEmail) { return; }