Skip to content

Commit

Permalink
Merge pull request #49375 from Expensify/jasper-fixDelegateDisconnect…
Browse files Browse the repository at this point in the history
…Reauth

Fixes to delegate access reauthentication
  • Loading branch information
jasperhuangg authored Oct 4, 2024
2 parents 6969103 + af22fa1 commit c986119
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
9 changes: 9 additions & 0 deletions src/libs/Authentication.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import type Response from '@src/types/onyx/Response';
import * as Delegate from './actions/Delegate';
import updateSessionAuthTokens from './actions/Session/updateSessionAuthTokens';
import redirectToSignIn from './actions/SignInRedirect';
import * as ErrorUtils from './ErrorUtils';
Expand Down Expand Up @@ -84,6 +85,14 @@ function reauthenticate(command = ''): Promise<void> {
return;
}

// If we reauthenticated due to an expired delegate token, restore the delegate's original account.
// This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as.
if (Delegate.isConnectedAsDelegate()) {
Log.info('Reauthenticated while connected as a delegate. Restoring original account.');
Delegate.restoreDelegateSession(response);
return;
}

// Update authToken in Onyx and in our local variables so that API requests will use the new authToken
updateSessionAuthTokens(response.authToken, response.encryptedAuthToken);

Expand Down
34 changes: 32 additions & 2 deletions src/libs/actions/Delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import * as SequentialQueue from '@libs/Network/SequentialQueue';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Delegate, DelegatedAccess, DelegateRole} from '@src/types/onyx/Account';
import type Response from '@src/types/onyx/Response';
import {confirmReadyToOpenApp, openApp} from './App';
import updateSessionAuthTokens from './Session/updateSessionAuthTokens';
import updateSessionUser from './Session/updateSessionUser';

let delegatedAccess: DelegatedAccess;
Onyx.connect({
Expand All @@ -21,7 +23,18 @@ Onyx.connect({
},
});

const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [ONYXKEYS.NVP_TRY_FOCUS_MODE, ONYXKEYS.PREFERRED_THEME, ONYXKEYS.NVP_PREFERRED_LOCALE, ONYXKEYS.SESSION, ONYXKEYS.IS_LOADING_APP];
const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [
ONYXKEYS.NVP_TRY_FOCUS_MODE,
ONYXKEYS.PREFERRED_THEME,
ONYXKEYS.NVP_PREFERRED_LOCALE,
ONYXKEYS.SESSION,
ONYXKEYS.IS_LOADING_APP,
ONYXKEYS.CREDENTIALS,

// We need to preserve the sidebar loaded state since we never unrender the sidebar when connecting as a delegate
// This allows the report screen to load correctly when the delegate token expires and the delegate is returned to their original account.
ONYXKEYS.IS_SIDEBAR_LOADED,
];

function connect(email: string) {
if (!delegatedAccess?.delegators) {
Expand Down Expand Up @@ -313,6 +326,10 @@ function clearAddDelegateErrors(email: string, fieldName: string) {
});
}

function isConnectedAsDelegate() {
return !!delegatedAccess?.delegate;
}

function removePendingDelegate(email: string) {
if (!delegatedAccess?.delegates) {
return;
Expand All @@ -325,4 +342,17 @@ function removePendingDelegate(email: string) {
});
}

export {connect, disconnect, clearDelegatorErrors, addDelegate, requestValidationCode, clearAddDelegateErrors, removePendingDelegate};
function restoreDelegateSession(authenticateResponse: Response) {
Onyx.clear(KEYS_TO_PRESERVE_DELEGATE_ACCESS).then(() => {
updateSessionAuthTokens(authenticateResponse?.authToken, authenticateResponse?.encryptedAuthToken);
updateSessionUser(authenticateResponse?.accountID, authenticateResponse?.email);

NetworkStore.setAuthToken(authenticateResponse.authToken ?? null);
NetworkStore.setIsAuthenticating(false);

confirmReadyToOpenApp();
openApp();
});
}

export {connect, disconnect, clearDelegatorErrors, addDelegate, requestValidationCode, clearAddDelegateErrors, removePendingDelegate, restoreDelegateSession, isConnectedAsDelegate};
6 changes: 6 additions & 0 deletions src/libs/actions/Session/updateSessionUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Onyx from 'react-native-onyx';
import ONYXKEYS from '@src/ONYXKEYS';

export default function updateSessionUser(accountID?: number, email?: string) {
Onyx.merge(ONYXKEYS.SESSION, {accountID, email});
}
6 changes: 6 additions & 0 deletions src/types/onyx/Response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ type Response = {
/** Base64 key to decrypt messages from Pusher encrypted channels */
// eslint-disable-next-line @typescript-eslint/naming-convention
shared_secret?: string;

/** The accountID of the user */
accountID?: number;

/** The email of the user */
email?: string;
};

export default Response;

0 comments on commit c986119

Please sign in to comment.