Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,20 @@ public AccMgrAuthTokenProvider(ClientManager clientManager, String instanceUrl,
@Override
public String getNewAuthToken() {
SalesforceSDKLogger.i(TAG, "Need new access token");
final Account acc = clientManager.getAccount();
if (acc == null) {
UserAccountManager userAccountManager = SalesforceSDKManager.getInstance().getUserAccountManager();
Account[] accounts = clientManager.getAccounts();
Account matchingAccount = null;

// Find the account for this client.
for (Account account : accounts) {
UserAccount user = userAccountManager.buildUserAccount(account);
if (user != null && lastNewAuthToken.equals(user.getAuthToken())) {
matchingAccount = account;
}
}
Comment on lines +386 to +392
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish there was a better way to do this. Perhaps we should associate each ClientManager to an account?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But don't we have an account associated already with ClientManager: final Account acc = clientManager.getAccount();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That returns the current account, which is (part of) the problem. If the user we are trying to get a new token for not the current user we will invalidate and refresh for the wrong account.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tying the ClientManager to account would make sense, but it's quite a change in behavior so probably not a 13.1 change. Maybe we could add a convenience method on UserAccountManager to find a matching account by auth token?


// Fail early to ensure we don't logout the current user below by sending null.
if (matchingAccount == null) {
return null;
}

Expand All @@ -401,9 +413,8 @@ public String getNewAuthToken() {
try {

// Invalidate current auth token.
final String cachedAuthToken = clientManager.peekRestClient(acc).getAuthToken();
clientManager.invalidateToken(cachedAuthToken);
final UserAccount userAccount = refreshStaleToken(acc);
clientManager.invalidateToken(lastNewAuthToken);
final UserAccount userAccount = refreshStaleToken(matchingAccount);

// NB: userAccount will be null if refresh token is no longer valid
newAuthToken = userAccount != null ? userAccount.getAuthToken() : null;
Expand All @@ -417,11 +428,12 @@ public String getNewAuthToken() {
if (Looper.myLooper() == null) {
Looper.prepare();
}
boolean showLoginPage = accounts.length > 1;
// Note: As of writing (2024) this call will never succeed because revoke API is an
// authenticated endpoint. However, there is no harm in attempting and the debug logs
// produced may help developers better understand the state of their app.
SalesforceSDKManager.getInstance()
.logout(null, null, false, OAuth2.LogoutReason.REFRESH_TOKEN_EXPIRED);
.logout(matchingAccount, null, showLoginPage, OAuth2.LogoutReason.REFRESH_TOKEN_EXPIRED);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logout will default to the current user if null is passed 😬. That is intended in most cases, but really bad in this one.

}

// Broadcasts an intent that the refresh token has been revoked.
Expand Down
Loading
Loading