Skip to content

Commit 8b62aa4

Browse files
authored
Merge pull request Expensify#63773 from callstack-internal/pac-guerreiro/fix/missing-credentials-during-reauthentication
fix: missing credentials during reauthentication
2 parents d7d809d + 436d998 commit 8b62aa4

1 file changed

Lines changed: 69 additions & 42 deletions

File tree

src/libs/Authentication.ts

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import redirectToSignIn from './actions/SignInRedirect';
99
import {getAuthenticateErrorMessage} from './ErrorUtils';
1010
import Log from './Log';
1111
import {post} from './Network';
12-
import {getCredentials, setAuthToken, setIsAuthenticating} from './Network/NetworkStore';
12+
import {getCredentials, hasReadRequiredDataFromStorage, setAuthToken, setIsAuthenticating} from './Network/NetworkStore';
1313
import requireParameters from './requireParameters';
1414

1515
type Parameters = {
@@ -71,58 +71,85 @@ function Authenticate(parameters: Parameters): Promise<Response> | undefined {
7171
* @param [command] command name for logging purposes
7272
*/
7373
function reauthenticate(command = ''): Promise<void> | undefined {
74+
Log.hmmm('Reauthenticate - Attempting re-authentication', {
75+
command,
76+
});
77+
7478
// Prevent re-authentication if authentication with shortLiveToken is in progress
7579
if (isAuthenticatingWithShortLivedToken) {
80+
Log.hmmm('Reauthenticate - Authentication with shortLiveToken is in progress. Re-authentication aborted.', {
81+
command,
82+
});
7683
return;
7784
}
7885

7986
// Prevent any more requests from being processed while authentication happens
8087
setIsAuthenticating(true);
8188

82-
const credentials = getCredentials();
83-
return Authenticate({
84-
useExpensifyLogin: false,
85-
partnerName: CONFIG.EXPENSIFY.PARTNER_NAME,
86-
partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD,
87-
partnerUserID: credentials?.autoGeneratedLogin,
88-
partnerUserSecret: credentials?.autoGeneratedPassword,
89-
})?.then((response) => {
90-
if (response.jsonCode === CONST.JSON_CODE.UNABLE_TO_RETRY) {
91-
// When a fetch() fails due to a network issue and an error is thrown we won't log the user out. Most likely they
92-
// have a spotty connection and will need to retry reauthenticate when they come back online. Error so it can be handled by the retry mechanism.
93-
throw new Error('Unable to retry Authenticate request');
94-
}
95-
96-
// If authentication fails and we are online then log the user out
97-
if (response.jsonCode !== 200) {
98-
const errorMessage = getAuthenticateErrorMessage(response);
89+
Log.hmmm('Reauthenticate - Waiting for credentials', {
90+
command,
91+
});
92+
93+
// We need to wait for credentials to be loaded from Onyx store
94+
return hasReadRequiredDataFromStorage().then(() => {
95+
const credentials = getCredentials();
96+
97+
Log.hmmm('Reauthenticate - Starting authentication process', {
98+
command,
99+
});
100+
101+
return Authenticate({
102+
useExpensifyLogin: false,
103+
partnerName: CONFIG.EXPENSIFY.PARTNER_NAME,
104+
partnerPassword: CONFIG.EXPENSIFY.PARTNER_PASSWORD,
105+
partnerUserID: credentials?.autoGeneratedLogin,
106+
partnerUserSecret: credentials?.autoGeneratedPassword,
107+
})?.then((response) => {
108+
Log.hmmm('Reauthenticate - Processing authentication result', {
109+
command,
110+
});
111+
112+
if (response.jsonCode === CONST.JSON_CODE.UNABLE_TO_RETRY) {
113+
// When a fetch() fails due to a network issue and an error is thrown we won't log the user out. Most likely they
114+
// have a spotty connection and will need to retry reauthenticate when they come back online. Error so it can be handled by the retry mechanism.
115+
throw new Error('Unable to retry Authenticate request');
116+
}
117+
118+
// If authentication fails and we are online then log the user out
119+
if (response.jsonCode !== 200) {
120+
const errorMessage = getAuthenticateErrorMessage(response);
121+
setIsAuthenticating(false);
122+
Log.hmmm('Redirecting to Sign In because we failed to reauthenticate', {
123+
command,
124+
error: errorMessage,
125+
});
126+
redirectToSignIn(errorMessage);
127+
return;
128+
}
129+
130+
// If we reauthenticate due to an expired delegate token, restore the delegate's original account.
131+
// This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as.
132+
if (isConnectedAsDelegate()) {
133+
Log.info('Reauthenticate while connected as a delegate. Restoring original account.');
134+
restoreDelegateSession(response);
135+
return;
136+
}
137+
138+
// Update authToken in Onyx and in our local variables so that API requests will use the new authToken
139+
updateSessionAuthTokens(response.authToken, response.encryptedAuthToken);
140+
141+
// Note: It is important to manually set the authToken that is in the store here since any requests that are hooked into
142+
// reauthenticate .then() will immediate post and use the local authToken. Onyx updates subscribers lately so it is not
143+
// enough to do the updateSessionAuthTokens() call above.
144+
setAuthToken(response.authToken ?? null);
145+
146+
// The authentication process is finished so the network can be unpaused to continue processing requests
99147
setIsAuthenticating(false);
100-
Log.hmmm('Redirecting to Sign In because we failed to reauthenticate', {
148+
149+
Log.hmmm('Reauthenticate - Re-authentication successful', {
101150
command,
102-
error: errorMessage,
103151
});
104-
redirectToSignIn(errorMessage);
105-
return;
106-
}
107-
108-
// If we reauthenticate due to an expired delegate token, restore the delegate's original account.
109-
// This is because the credentials used to reauthenticate were for the delegate's original account, and not for the account they were connected as.
110-
if (isConnectedAsDelegate()) {
111-
Log.info('Reauthenticate while connected as a delegate. Restoring original account.');
112-
restoreDelegateSession(response);
113-
return;
114-
}
115-
116-
// Update authToken in Onyx and in our local variables so that API requests will use the new authToken
117-
updateSessionAuthTokens(response.authToken, response.encryptedAuthToken);
118-
119-
// Note: It is important to manually set the authToken that is in the store here since any requests that are hooked into
120-
// reauthenticate .then() will immediate post and use the local authToken. Onyx updates subscribers lately so it is not
121-
// enough to do the updateSessionAuthTokens() call above.
122-
setAuthToken(response.authToken ?? null);
123-
124-
// The authentication process is finished so the network can be unpaused to continue processing requests
125-
setIsAuthenticating(false);
152+
});
126153
});
127154
}
128155

0 commit comments

Comments
 (0)