Skip to content

Commit 716ee66

Browse files
authored
W-19758940: Improve ClientManager for multi-user (#2973)
* feat(W-19758940): bind ClientManager to persisted user * fix(W-19758940): address Android PR review feedback * test(W-19758940): automate multi-user refresh failures * fix(push): log skipped deregistration work * fix(AuthFlowTester): dismiss logout dialog on completion
1 parent e34a1d5 commit 716ee66

56 files changed

Lines changed: 4361 additions & 1935 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/reusable-ui-workflow.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ jobs:
103103
class com.salesforce.samples.authflowtester.ECALoginTests#testECAJwt_AllScopes, \
104104
class com.salesforce.samples.authflowtester.TokenMigrationTest#testMigrate_ECA_AddMoreScopes, \
105105
class com.salesforce.samples.authflowtester.MultiUserLoginTests#testSameApp_SameScopes_uniqueTokens, \
106+
class com.salesforce.samples.authflowtester.MultiUserLoginTests#testRetainedUserClient_refreshesWhileOtherUserCurrent, \
106107
class com.salesforce.samples.authflowtester.BeaconLoginTests#testBeaconOpaque_DefaultScopes, \
107108
class com.salesforce.samples.authflowtester.AdvancedAuthBeaconLoginTests#testBeaconOpaque_DefaultScopes"
108109

docs/auth/token-lifecycle.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ delegates to `AccMgrAuthTokenProvider.getNewAuthToken()`. That method:
7373
the instance URL changed), publishes the new tokens to the per-account `RefreshState`,
7474
and wakes waiting losers.
7575

76-
6. On terminal failure (`invalid_grant`, `client_blocked`): broadcasts
76+
6. On terminal failure (`invalid_grant`, `app_attest_failed`): broadcasts
7777
`ACCESS_TOKEN_REVOKE_INTENT` and calls `SalesforceSDKManager.logout()`.
7878

7979
---

docs/push/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ Registration status constants (passed to `onPushNotificationRegistrationStatus`)
217217

218218
Internal `Worker` subclass that executes push registration changes on a background thread via `WorkManager`. Not instantiated directly — use `PushService.enqueuePushNotificationsRegistrationWork(...)`.
219219

220-
When `userAccount` is `null`, the worker iterates all authenticated users and calls `performRegistrationChange` for each.
220+
For registration, absent account identifiers target all authenticated users. Deregistration always
221+
requires an exact org and user ID. If that account no longer resolves, WorkManager records a
222+
non-retryable failure; best-effort server deregistration may remain incomplete until the record's
223+
TTL expires or a later explicit deregistration succeeds. If a resolved account cannot produce a
224+
REST client, the worker completes without a remote change and logs a warning.
221225

222226
---
223227

libs/MobileSync/src/com/salesforce/androidsdk/mobilesync/manager/SyncManager.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import com.salesforce.androidsdk.mobilesync.util.SyncState.Status.STOPPED
4646
import com.salesforce.androidsdk.mobilesync.util.SyncState.Type.syncDown
4747
import com.salesforce.androidsdk.mobilesync.util.SyncState.Type.syncUp
4848
import com.salesforce.androidsdk.rest.ApiVersionStrings
49+
import com.salesforce.androidsdk.rest.ClientManager
4950
import com.salesforce.androidsdk.rest.RestClient
5051
import com.salesforce.androidsdk.rest.RestRequest
5152
import com.salesforce.androidsdk.rest.RestResponse
@@ -826,9 +827,10 @@ class SyncManager private constructor(smartStore: SmartStore, restClient: RestCl
826827
* RestClient should be set to the unauthenticated RestClient instance.
827828
*/
828829
val restClient: RestClient? = if (user == null) {
829-
SalesforceSDKManager.getInstance().clientManager.peekUnauthenticatedRestClient()
830+
SalesforceSDKManager.getInstance().getUnauthenticatedRestClient()
830831
} else {
831-
SalesforceSDKManager.getInstance().clientManager.peekRestClient(user)
832+
ClientManager(SalesforceSDKManager.getInstance().appContext, user)
833+
.peekRestClient()
832834
}
833835
instance = SyncManager(store, restClient)
834836
instance.also { INSTANCES[uniqueId] = it }
@@ -874,4 +876,4 @@ class SyncManager private constructor(smartStore: SmartStore, restClient: RestCl
874876
}
875877
}
876878
}
877-
}
879+
}

libs/SalesforceHybrid/src/com/salesforce/androidsdk/phonegap/plugin/SFAccountManagerPlugin.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.content.Intent;
3030

3131
import com.salesforce.androidsdk.accounts.UserAccount;
32+
import com.salesforce.androidsdk.accounts.UserAccountManager;
3233
import com.salesforce.androidsdk.app.SalesforceSDKManager;
3334
import com.salesforce.androidsdk.phonegap.util.SalesforceHybridLogger;
3435

@@ -133,7 +134,13 @@ protected void logout(JSONArray args, CallbackContext callbackContext) {
133134
account = new UserAccount(user);
134135
}
135136
}
136-
SalesforceSDKManager.getInstance().getUserAccountManager().signoutUser(account, cordova.getActivity());
137+
final UserAccountManager userAccountManager =
138+
SalesforceSDKManager.getInstance().getUserAccountManager();
139+
if (account == null) {
140+
userAccountManager.signoutCurrentUser(cordova.getActivity());
141+
} else {
142+
userAccountManager.signoutUser(account, cordova.getActivity());
143+
}
137144
callbackContext.success();
138145
}
139146

libs/SalesforceHybrid/src/com/salesforce/androidsdk/phonegap/plugin/SalesforceNetworkPlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.text.TextUtils;
3030
import android.util.Base64;
3131

32+
import com.salesforce.androidsdk.app.SalesforceSDKManager;
3233
import com.salesforce.androidsdk.phonegap.ui.SalesforceDroidGapActivity;
3334
import com.salesforce.androidsdk.phonegap.util.SalesforceHybridLogger;
3435
import com.salesforce.androidsdk.rest.RestClient;
@@ -270,7 +271,7 @@ private RestClient getRestClient(boolean doesNotRequireAuth) {
270271
return null;
271272
}
272273
if (doesNotRequireAuth) {
273-
return currentActivity.buildClientManager().peekUnauthenticatedRestClient();
274+
return SalesforceSDKManager.getInstance().getUnauthenticatedRestClient();
274275
}
275276
return currentActivity.getRestClient();
276277
}

0 commit comments

Comments
 (0)