Skip to content

Conversation

@brandonpage
Copy link
Contributor

@brandonpage brandonpage commented Sep 18, 2025

This bugfix is not a simple revert of a previous change since I believe the code changed in this PR has been working incorrectly for some time by using the wrong accounts token. We simply did not notice until the logout issue was added on top.

// 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.

Comment on lines +386 to +392
// Find the account for this client.
for (Account account : accounts) {
UserAccount user = userAccountManager.buildUserAccount(account);
if (user != null && lastNewAuthToken.equals(user.getAuthToken())) {
matchingAccount = account;
}
}
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?

@wmathurin
Copy link
Contributor

@brandonpage do you know how it was working in 12.1.1?

@brandonpage
Copy link
Contributor Author

brandonpage commented Sep 19, 2025

@brandonpage do you know how it was working in 12.1.1?

It "worked" in 12.1.1 because the getNewAuthToken call would refresh the token for the user you were switching to (technically current user). This happened because refreshStaleToken used the refresh token from the wrong account we passed in. That operation is successful since the current user has not been revoked so we don't call logout.

12.2.0 onwards refreshStaleToken was changed to (correctly?) use the cached refresh token. This cached token is for the correct user, which means the refresh correctly fails. When that happens refreshStaleToken returns a null user, which leads to logout being called with that null user and the current user is removed.

In this PR I am passing the correct account to refreshStaleToken because we should, but the real fix is passing the correct account to logout.

@brandonpage brandonpage merged commit 23874ff into forcedotcom:dev Sep 23, 2025
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants