Skip to content

Commit b20617b

Browse files
authored
Merge branch 'main' into process_death_support_v3
2 parents 7f397f4 + 1364458 commit b20617b

File tree

16 files changed

+490
-34
lines changed

16 files changed

+490
-34
lines changed

.github/actions/maven-publish/action.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ runs:
2020
- name: Checkout code
2121
uses: actions/checkout@v4
2222

23-
- name: Setup Java
24-
shell: bash
25-
run: |
26-
curl -s "https://get.sdkman.io" | bash
27-
source "/home/runner/.sdkman/bin/sdkman-init.sh"
28-
sdk list java
29-
sdk install java ${{ inputs.java-version }} && sdk default java ${{ inputs.java-version }}
23+
- name: Set up Java
24+
uses: actions/setup-java@v4
25+
with:
26+
distribution: 'temurin'
27+
java-version: '11'
3028

3129
- uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # pin@1.1.0
3230

.github/actions/setup/action.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ runs:
1919
using: composite
2020

2121
steps:
22+
- name: Set up Java
23+
uses: actions/setup-java@v4
24+
with:
25+
distribution: 'temurin'
26+
java-version: '11'
27+
2228
- run: |
2329
curl -s "https://get.sdkman.io" | bash
2430
source "/home/runner/.sdkman/bin/sdkman-init.sh"
25-
sdk list java
26-
sdk install java ${{ inputs.java }} && sdk default java ${{ inputs.java }}
2731
sdk install gradle ${{ inputs.gradle }} && sdk default gradle ${{ inputs.gradle }}
2832
sdk install kotlin ${{ inputs.kotlin }} && sdk default kotlin ${{ inputs.kotlin }}
2933
shell: bash

.github/workflows/codeql.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ jobs:
3535
- if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group'
3636
run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection.
3737

38+
- name: Set up Java
39+
uses: actions/setup-java@v4
40+
with:
41+
distribution: 'temurin'
42+
java-version: '11'
43+
3844
- name: Checkout
3945
uses: actions/checkout@v4
4046

.snyk

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ ignore:
55
SNYK-JAVA-COMFASTERXMLWOODSTOX-3091135:
66
- '*':
77
reason: Latest version of dokka has this vulnerability
8-
expires: 2024-12-31T12:54:23.000Z
8+
expires: 2025-02-21T12:54:23.000Z
99
created: 2024-08-01T12:08:37.770Z
1010
SNYK-JAVA-ORGJETBRAINSKOTLIN-2393744:
1111
- '*':
1212
reason: Latest version of dokka has this vulnerability
13-
expires: 2024-12-31T12:54:23.000Z
13+
expires: 2025-02-21T12:54:23.000Z
1414
created: 2024-08-01T12:08:55.927Z
1515
SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538:
1616
- '*':
1717
reason: Latest version of dokka has this vulnerability
18-
expires: 2024-12-31T1:54:23.000Z
18+
expires: 2025-02-21T1:54:23.000Z
1919
created: 2024-08-01T12:08:02.973Z
2020
patch: {}

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.2.0
1+
3.3.0

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Change Log
22

3+
## [3.3.0](https://github.com/auth0/Auth0.Android/tree/3.3.0) (2025-02-03)
4+
[Full Changelog](https://github.com/auth0/Auth0.Android/compare/3.2.1...3.3.0)
5+
6+
**Added**
7+
- Add support for custom token exchange [\#789](https://github.com/auth0/Auth0.Android/pull/789) ([pmathew92](https://github.com/pmathew92))
8+
9+
## [3.2.1](https://github.com/auth0/Auth0.Android/tree/3.2.1) (2024-12-06)
10+
[Full Changelog](https://github.com/auth0/Auth0.Android/compare/3.2.0...3.2.1)
11+
12+
**Added**
13+
- Added new error types for CredentialsManagerException [\#783](https://github.com/auth0/Auth0.Android/pull/783) ([pmathew92](https://github.com/pmathew92))
14+
- Making realm parameter optional for passkeys [\#776](https://github.com/auth0/Auth0.Android/pull/776) ([pmathew92](https://github.com/pmathew92))
15+
316
## [3.2.0](https://github.com/auth0/Auth0.Android/tree/3.2.0) (2024-11-07)
417
[Full Changelog](https://github.com/auth0/Auth0.Android/compare/3.1.0...3.2.0)
518

EXAMPLES.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- [Step 2: Input the code](#step-2-input-the-code)
1818
- [Sign Up with a database connection](#sign-up-with-a-database-connection)
1919
- [Get user information](#get-user-information)
20+
- [Custom Token Exchange](#custom-token-exchange)
2021
- [Credentials Manager](#credentials-manager)
2122
- [Secure Credentials Manager](#secure-credentials-manager)
2223
- [Usage](#usage)
@@ -487,6 +488,57 @@ authentication
487488
```
488489
</details>
489490

491+
### Custom Token Exchange
492+
493+
```kotlin
494+
authentication
495+
.customTokenExchange("subject_token_type", "subject_token")
496+
.start(object : Callback<Credentials, AuthenticationException> {
497+
override fun onSuccess(result: Credentials) {
498+
// Handle success
499+
}
500+
501+
override fun onFailure(exception: AuthenticationException) {
502+
// Handle error
503+
}
504+
505+
})
506+
```
507+
<details>
508+
<summary>Using coroutines</summary>
509+
510+
``` kotlin
511+
try {
512+
val credentials = authentication
513+
.tokenExchange("subject_token_type", "subject_token")
514+
.await()
515+
} catch (e: AuthenticationException) {
516+
e.printStacktrace()
517+
}
518+
```
519+
</details>
520+
521+
<details>
522+
<summary>Using Java</summary>
523+
524+
```java
525+
authentication
526+
.customTokenExchange("subject_token_type", "subject_token")
527+
.start(new Callback<Credentials, AuthenticationException>() {
528+
@Override
529+
public void onSuccess(@Nullable Credentials payload) {
530+
// Handle success
531+
}
532+
@Override
533+
public void onFailure(@NonNull AuthenticationException error) {
534+
// Handle error
535+
}
536+
});
537+
```
538+
539+
540+
</details>
541+
490542

491543
## Credentials Manager
492544

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ To install Auth0.Android with [Gradle](https://gradle.org/), simply add the foll
5151

5252
```gradle
5353
dependencies {
54-
implementation 'com.auth0.android:auth0:3.2.0'
54+
implementation 'com.auth0.android:auth0:3.3.0'
5555
}
5656
```
5757

auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
167167
* ```
168168
* client.signinWithPasskey("{authSession}", "{authResponse}","{realm}")
169169
* .validateClaims() //mandatory
170-
* .addParameter("scope","scope")
170+
* .setScope("{scope}")
171171
* .start(object: Callback<Credentials, AuthenticationException> {
172172
* override fun onFailure(error: AuthenticationException) { }
173173
* override fun onSuccess(result: Credentials) { }
@@ -211,7 +211,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
211211
* ```
212212
* client.signinWithPasskey("{authSession}", "{authResponse}","{realm}")
213213
* .validateClaims() //mandatory
214-
* .addParameter("scope","scope")
214+
* .setScope("{scope}")
215215
* .start(object: Callback<Credentials, AuthenticationException> {
216216
* override fun onFailure(error: AuthenticationException) { }
217217
* override fun onSuccess(result: Credentials) { }
@@ -457,13 +457,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
457457
* @return a request to configure and start that will yield [Credentials]
458458
*/
459459
public fun loginWithNativeSocialToken(token: String, tokenType: String): AuthenticationRequest {
460-
val parameters = ParameterBuilder.newAuthenticationBuilder()
461-
.setGrantType(ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
462-
.setClientId(clientId)
463-
.set(SUBJECT_TOKEN_KEY, token)
464-
.set(SUBJECT_TOKEN_TYPE_KEY, tokenType)
465-
.asDictionary()
466-
return loginWithToken(parameters)
460+
return tokenExchange(tokenType, token)
467461
}
468462

469463
/**
@@ -707,6 +701,34 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
707701
.addParameters(parameters)
708702
}
709703

704+
/**
705+
* The Custom Token Exchange feature allows clients to exchange their existing tokens for Auth0 tokens by calling the `/oauth/token` endpoint with specific parameters.
706+
* The default scope used is 'openid profile email'.
707+
*
708+
* Example usage:
709+
*
710+
* ```
711+
* client.customTokenExchange("{subject token type}", "{subject token}")
712+
* .validateClaims() //mandatory
713+
* .setScope("{scope}")
714+
* .setAudience("{audience}")
715+
* .start(object: Callback<Credentials, AuthenticationException> {
716+
* override fun onSuccess(result: Credentials) { }
717+
* override fun onFailure(error: AuthenticationException) { }
718+
* })
719+
* ```
720+
*
721+
* @param subjectTokenType the subject token type that is associated with the existing Identity Provider. e.g. 'http://acme.com/legacy-token'
722+
* @param subjectToken the subject token, typically obtained through the Identity Provider's SDK
723+
* @return a request to configure and start that will yield [Credentials]
724+
*/
725+
public fun customTokenExchange(
726+
subjectTokenType: String,
727+
subjectToken: String,
728+
): AuthenticationRequest {
729+
return tokenExchange(subjectTokenType, subjectToken)
730+
}
731+
710732
/**
711733
* Requests new Credentials using a valid Refresh Token. The received token will have the same audience and scope as first requested.
712734
*
@@ -922,6 +944,21 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
922944
return request
923945
}
924946

947+
/**
948+
* Helper function to make a request to the /oauth/token endpoint with the token exchange grant type.
949+
*/
950+
private fun tokenExchange(
951+
subjectTokenType: String,
952+
subjectToken: String
953+
): AuthenticationRequest {
954+
val parameters = ParameterBuilder.newAuthenticationBuilder()
955+
.setGrantType(ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
956+
.set(SUBJECT_TOKEN_TYPE_KEY, subjectTokenType)
957+
.set(SUBJECT_TOKEN_KEY, subjectToken)
958+
.asDictionary()
959+
return loginWithToken(parameters)
960+
}
961+
925962
private fun profileRequest(): Request<UserProfile, AuthenticationException> {
926963
val url =
927964
auth0.getDomainUrl().toHttpUrl().newBuilder()

auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,15 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
325325
saveCredentials(credentials)
326326
callback.onSuccess(credentials)
327327
} catch (error: AuthenticationException) {
328+
val exception = when {
329+
error.isRefreshTokenDeleted ||
330+
error.isInvalidRefreshToken -> CredentialsManagerException.Code.RENEW_FAILED
331+
error.isNetworkError -> CredentialsManagerException.Code.NO_NETWORK
332+
else -> CredentialsManagerException.Code.API_ERROR
333+
}
328334
callback.onFailure(
329335
CredentialsManagerException(
330-
CredentialsManagerException.Code.RENEW_FAILED,
336+
exception,
331337
error
332338
)
333339
)

0 commit comments

Comments
 (0)