breaking : Moved the useDPoP method in the WebAuthProvider class to the login builder class#914
breaking : Moved the useDPoP method in the WebAuthProvider class to the login builder class#914pmathew92 merged 4 commits intov4_developmentfrom
useDPoP method in the WebAuthProvider class to the login builder class#914Conversation
… builder to scope it to individualk login requests
There was a problem hiding this comment.
Pull request overview
Moves DPoP configuration from a global WebAuthProvider.useDPoP(...) setting to a per-request WebAuthProvider.login(...).useDPoP(...) builder setting, aligning the API with request-scoped behavior and removing the prior “sticky” global configuration.
Changes:
- Removed global
WebAuthProvider.useDPoP(context)and addedBuilder.useDPoP(context)for per-login configuration. - Updated
WebAuthProviderTestDPoP-related tests to use the builder-based API and removed the global-instance behavior test. - Updated docs (migration guide + examples) to reflect the new call pattern.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| auth0/src/main/java/com/auth0/android/provider/WebAuthProvider.kt | Removes global DPoP config and adds per-builder DPoP support via SenderConstraining<Builder>. |
| auth0/src/test/java/com/auth0/android/provider/WebAuthProviderTest.kt | Updates DPoP tests to use builder-based configuration and removes obsolete global-instance test. |
| V4_MIGRATION_GUIDE.md | Documents the breaking API move from global to builder-based DPoP configuration. |
| EXAMPLES.md | Updates WebAuthProvider DPoP usage example to call useDPoP(context) on the login builder. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public override fun useDPoP(context: Context): Builder { | ||
| dPoP = DPoP(context) | ||
| return this | ||
| } |
There was a problem hiding this comment.
Because DPoP is now configured per login Builder instance, make sure the authentication flow still survives process death/restoration: WebAuthProvider saves/restores OAuthManager via OAuthManager.toState()/fromState(), but OAuthManager.toState() does not currently persist DPoP and OAuthManagerState/PKCE reconstruction doesn’t re-enable DPoP on the restored AuthenticationAPIClient. This can cause a DPoP-enabled login to resume without DPoP proofs after restore. Consider persisting only a lightweight “DPoP enabled” flag in state and reconstructing/configuring DPoP (without serializing a Context-bearing DPoP instance) when restoring.
V4_MIGRATION_GUIDE.md
Outdated
|
|
||
| ### DPoP Configuration Moved to Builder | ||
|
|
||
| The `useDPoP()` method has been moved from the `WebAuthProvider` object to the login `Builder` class. This change allows DPoP to be configured per-request instead of globally. |
There was a problem hiding this comment.
The text says the useDPoP() method moved, but the API requires a Context parameter (useDPoP(context) / useDPoP(context: Context)). Updating the inline code reference would avoid implying a zero-arg overload still exists.
| The `useDPoP()` method has been moved from the `WebAuthProvider` object to the login `Builder` class. This change allows DPoP to be configured per-request instead of globally. | |
| The `useDPoP(context: Context)` method has been moved from the `WebAuthProvider` object to the login `Builder` class. This change allows DPoP to be configured per-request instead of globally. |
There was a problem hiding this comment.
Nit: should be useDPoP(context: Context) to match the actual signature and avoid implying a zero-arg overload exists.
| public fun enablingDPoPWillGenerateNewKeyPairIfOneDoesNotExist() { | ||
| `when`(mockKeyStore.hasKeyPair()).thenReturn(false) | ||
| WebAuthProvider.useDPoP(mockContext) | ||
| .login(account) | ||
| login(account) | ||
| .useDPoP(mockContext) | ||
| .start(activity, callback) |
There was a problem hiding this comment.
There’s no test asserting the new per-request behavior (i.e., enabling DPoP on one login builder does not affect a subsequent login call that doesn’t call useDPoP). Adding a regression test for the non-sticky behavior would better cover the API change described in the PR motivation.
| intentCaptor.allValues[1].getParcelableExtra<Uri>(AuthenticationActivity.EXTRA_AUTHORIZE_URI) | ||
| assertThat(secondUri, `is`(notNullValue())) | ||
| assertThat(secondUri, not(UriMatchers.hasParamWithName("dpop_jkt"))) | ||
| } |
| * @param context the Android context used to access the keystore for DPoP key management | ||
| * @return the current builder instance | ||
| */ | ||
| public override fun useDPoP(context: Context): Builder { |
There was a problem hiding this comment.
Now that DPoP is scoped to the Builder (no longer on the singleton), the DPoP state won't survive process death. OAuthManager.toState() doesn't persist DPoP, and fromState() restores without it — so a DPoP-enabled login will silently resume without DPoP proofs if the OS kills the activity mid-redirect.
Please add a dpoPEnabled: Boolean flag to OAuthManagerState, persist it in toState(), and reconstruct DPoP(context) in fromState() when the flag is true. No need to serialize the DPoP instance itself (it holds a Context).
Please:
1>Add dpoPEnabled: Boolean = false to OAuthManagerState
2>Set it in toState() based on dPoP != null
3>In fromState(), if dpoPEnabled == true, pass DPoP(context) to the reconstructed OAuthManager
V4_MIGRATION_GUIDE.md
Outdated
|
|
||
| ### DPoP Configuration Moved to Builder | ||
|
|
||
| The `useDPoP()` method has been moved from the `WebAuthProvider` object to the login `Builder` class. This change allows DPoP to be configured per-request instead of globally. |
There was a problem hiding this comment.
Nit: should be useDPoP(context: Context) to match the actual signature and avoid implying a zero-arg overload exists.
| @@ -2861,8 +2853,7 @@ public class WebAuthProviderTest { | |||
|
|
|||
| @Test | |||
| public fun shouldNotAffectLogoutWhenDPoPIsEnabled() { | |||
There was a problem hiding this comment.
This test name is now misleading — it no longer enables DPoP at all, it just tests default logout. Consider renaming to shouldNotIncludeDPoPParametersInLogoutURI.
There was a problem hiding this comment.
Good catch. This test is no longer required. Removed it
Description
This PR moves the DPoP (Demonstrating Proof-of-Possession) configuration from a global setting on the
WebAuthProviderobject to the loginBuilderclass, enabling per-request DPoP configuration.Motivation
Previously, DPoP was configured globally via
WebAuthProvider.useDPoP(context), which meant:Changes
Before (v3):
WebAuthProvider .useDPoP(context) .login(account) .start(context, callback)** After(v4):**
WebAuthProvider .login(account) .useDPoP(context) .start(context, callback)