diff --git a/EXAMPLES.md b/EXAMPLES.md
index 763a4188..71c21b61 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -1032,7 +1032,8 @@ To sign up a user with passkey
try {
val challenge = authenticationApiClient.signupWithPasskey(
"{user-data}",
- "{realm}"
+ "{realm}",
+ "{organization-id}"
).await()
//Use CredentialManager to create public key credentials
@@ -1048,7 +1049,7 @@ try {
)
val userCredential = authenticationApiClient.signinWithPasskey(
- challenge.authSession, authRequest, "{realm}"
+ challenge.authSession, authRequest, "{realm}" , "{organization-id}"
)
.validateClaims()
.await()
@@ -1060,7 +1061,7 @@ try {
Using Java
```java
- authenticationAPIClient.signupWithPasskey("{user-data}", "{realm}")
+ authenticationAPIClient.signupWithPasskey("{user-data}", "{realm}","{organization-id}")
.start(new Callback() {
@Override
public void onSuccess(PasskeyRegistrationChallenge result) {
@@ -1078,7 +1079,7 @@ try {
PublicKeyCredentials.class);
authenticationAPIClient.signinWithPasskey(result.getAuthSession(),
- credentials, "{realm}")
+ credentials, "{realm}","{organization-id}")
.start(new Callback() {
@Override
public void onSuccess(Credentials result) {}
@@ -1104,7 +1105,7 @@ To sign in a user with passkey
try {
val challenge =
- authenticationApiClient.passkeyChallenge("{realm}")
+ authenticationApiClient.passkeyChallenge("{realm}","{organization-id}")
.await()
//Use CredentialManager to create public key credentials
@@ -1122,7 +1123,8 @@ try {
val userCredential = authenticationApiClient.signinWithPasskey(
challenge.authSession,
authRequest,
- "{realm}"
+ "{realm}",
+ "{organization-id}"
)
.validateClaims()
.await()
@@ -1138,7 +1140,7 @@ try {
Using Java
```java
-authenticationAPIClient.passkeyChallenge("realm")
+authenticationAPIClient.passkeyChallenge("realm","{organization-id}")
.start(new Callback() {
@Override
public void onSuccess(PasskeyChallenge result) {
@@ -1158,7 +1160,7 @@ authenticationAPIClient.passkeyChallenge("realm")
responseJson,
PublicKeyCredentials.class
);
- authenticationAPIClient.signinWithPasskey(result.getAuthSession(), publicKeyCredentials,"{realm}")
+ authenticationAPIClient.signinWithPasskey(result.getAuthSession(), publicKeyCredentials,"{realm}","{organization-id}")
.start(new Callback() {
@Override
public void onSuccess(Credentials result) {}
diff --git a/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt b/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt
index 560e649f..a026084c 100755
--- a/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt
+++ b/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt
@@ -166,7 +166,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* Example usage:
*
* ```
- * client.signinWithPasskey("{authSession}", "{authResponse}","{realm}")
+ * client.signinWithPasskey("{authSession}", "{authResponse}","{realm}","${organization}")
* .validateClaims() //mandatory
* .setScope("{scope}")
* .start(object: Callback {
@@ -178,17 +178,20 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* @param authSession the auth session received from the server as part of the public key challenge request.
* @param authResponse the [PublicKeyCredentials] authentication response
* @param realm the connection to use. If excluded, the application will use the default connection configured in the tenant
+ * @param organization id of the organization to be associated with the user while signing in
* @return a request to configure and start that will yield [Credentials]
*/
public fun signinWithPasskey(
authSession: String,
authResponse: PublicKeyCredentials,
- realm: String? = null
+ realm: String? = null,
+ organization: String? = null,
): AuthenticationRequest {
val params = ParameterBuilder.newBuilder().apply {
setGrantType(ParameterBuilder.GRANT_TYPE_PASSKEY)
set(AUTH_SESSION_KEY, authSession)
realm?.let { setRealm(it) }
+ organization?.let { set(ORGANIZATION_KEY, organization) }
}.asDictionary()
return loginWithToken(params)
@@ -210,7 +213,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* Example usage:
*
* ```
- * client.signinWithPasskey("{authSession}", "{authResponse}","{realm}")
+ * client.signinWithPasskey("{authSession}", "{authResponse}","{realm}","{organization}")
* .validateClaims() //mandatory
* .setScope("{scope}")
* .start(object: Callback {
@@ -222,18 +225,20 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* @param authSession the auth session received from the server as part of the public key challenge request.
* @param authResponse the public key credential authentication response in JSON string format that follows the standard webauthn json format
* @param realm the connection to use. If excluded, the application will use the default connection configured in the tenant
+ * @param organization id of the organization to be associated with the user while signing in
* @return a request to configure and start that will yield [Credentials]
*/
public fun signinWithPasskey(
authSession: String,
authResponse: String,
- realm: String? = null
+ realm: String? = null,
+ organization: String? = null,
): AuthenticationRequest {
val publicKeyCredentials = gson.fromJson(
authResponse,
PublicKeyCredentials::class.java
)
- return signinWithPasskey(authSession, publicKeyCredentials, realm)
+ return signinWithPasskey(authSession, publicKeyCredentials, realm, organization)
}
@@ -247,7 +252,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
*
*
* ```
- * client.signupWithPasskey("{userData}","{realm}")
+ * client.signupWithPasskey("{userData}","{realm}","{organization}")
* .addParameter("scope","scope")
* .start(object: Callback {
* override fun onSuccess(result: PasskeyRegistration) { }
@@ -257,11 +262,13 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
*
* @param userData user information of the client
* @param realm the connection to use. If excluded, the application will use the default connection configured in the tenant
+ * @param organization id of the organization to be associated with the user while signing up
* @return a request to configure and start that will yield [PasskeyRegistrationChallenge]
*/
public fun signupWithPasskey(
userData: UserData,
- realm: String? = null
+ realm: String? = null,
+ organization: String? = null
): Request {
val user = gson.toJsonTree(userData)
val url = auth0.getDomainUrl().toHttpUrl().newBuilder()
@@ -272,6 +279,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
val params = ParameterBuilder.newBuilder().apply {
setClientId(clientId)
realm?.let { setRealm(it) }
+ organization?.let { set(ORGANIZATION_KEY, it) }
}.asDictionary()
val passkeyRegistrationChallengeAdapter: JsonAdapter =
@@ -293,7 +301,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* Example usage:
*
* ```
- * client.passkeyChallenge("{realm}")
+ * client.passkeyChallenge("{realm}", "{organization}")
* .start(object: Callback {
* override fun onSuccess(result: PasskeyChallenge) { }
* override fun onFailure(error: AuthenticationException) { }
@@ -301,10 +309,12 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* ```
*
* @param realm the connection to use. If excluded, the application will use the default connection configured in the tenant
+ * @param organization id of the organization to be associated with the user while signing in
* @return a request to configure and start that will yield [PasskeyChallenge]
*/
public fun passkeyChallenge(
- realm: String? = null
+ realm: String? = null,
+ organization: String? = null
): Request {
val url = auth0.getDomainUrl().toHttpUrl().newBuilder()
.addPathSegment(PASSKEY_PATH)
@@ -314,6 +324,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
val parameters = ParameterBuilder.newBuilder().apply {
setClientId(clientId)
realm?.let { setRealm(it) }
+ organization?.let { set(ORGANIZATION_KEY, organization) }
}.asDictionary()
val passkeyChallengeAdapter: JsonAdapter = GsonAdapter(
@@ -1054,7 +1065,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
private const val RECOVERY_CODE_KEY = "recovery_code"
private const val SUBJECT_TOKEN_KEY = "subject_token"
private const val SUBJECT_TOKEN_TYPE_KEY = "subject_token_type"
- private const val REQUESTED_TOKEN_TYPE_KEY = "requested_token_type"
+ private const val ORGANIZATION_KEY = "organization"
private const val USER_METADATA_KEY = "user_metadata"
private const val AUTH_SESSION_KEY = "auth_session"
private const val AUTH_RESPONSE_KEY = "authn_response"
diff --git a/auth0/src/test/java/com/auth0/android/authentication/AuthenticationAPIClientTest.kt b/auth0/src/test/java/com/auth0/android/authentication/AuthenticationAPIClientTest.kt
index fc37fcfa..3c42da6f 100755
--- a/auth0/src/test/java/com/auth0/android/authentication/AuthenticationAPIClientTest.kt
+++ b/auth0/src/test/java/com/auth0/android/authentication/AuthenticationAPIClientTest.kt
@@ -193,7 +193,8 @@ public class AuthenticationAPIClientTest {
val callback = MockAuthenticationCallback()
val auth0 = auth0
val client = AuthenticationAPIClient(auth0)
- client.signinWithPasskey("auth-session", mock(), MY_CONNECTION)
+ client.signinWithPasskey("auth-session", mock(), MY_CONNECTION,
+ "testOrganisation")
.start(callback)
ShadowLooper.idleMainLooper()
assertThat(
@@ -216,6 +217,7 @@ public class AuthenticationAPIClientTest {
)
assertThat(body, Matchers.hasKey("authn_response"))
assertThat(body, Matchers.hasEntry("auth_session", "auth-session"))
+ assertThat(body, Matchers.hasEntry("organization", "testOrganisation"))
}
@Test
@@ -225,7 +227,8 @@ public class AuthenticationAPIClientTest {
val client = AuthenticationAPIClient(auth0)
val registrationResponse = client.signupWithPasskey(
mock(),
- MY_CONNECTION
+ MY_CONNECTION,
+ "testOrganization"
)
.execute()
val request = mockAPI.takeRequest()
@@ -238,6 +241,7 @@ public class AuthenticationAPIClientTest {
assertThat(request.path, Matchers.equalTo("/passkey/register"))
assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID))
assertThat(body, Matchers.hasEntry("realm", MY_CONNECTION))
+ assertThat(body, Matchers.hasEntry("organization", "testOrganization"))
assertThat(body, Matchers.hasKey("user_profile"))
assertThat(registrationResponse, Matchers.`is`(Matchers.notNullValue()))
assertThat(registrationResponse.authSession, Matchers.comparesEqualTo(SESSION_ID))
@@ -248,7 +252,7 @@ public class AuthenticationAPIClientTest {
mockAPI.willReturnSuccessfulPasskeyChallenge()
val auth0 = auth0
val client = AuthenticationAPIClient(auth0)
- val challengeResponse = client.passkeyChallenge(MY_CONNECTION)
+ val challengeResponse = client.passkeyChallenge(MY_CONNECTION, "testOrganization")
.execute()
val request = mockAPI.takeRequest()
assertThat(
@@ -260,6 +264,7 @@ public class AuthenticationAPIClientTest {
assertThat(request.path, Matchers.equalTo("/passkey/challenge"))
assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID))
assertThat(body, Matchers.hasEntry("realm", MY_CONNECTION))
+ assertThat(body, Matchers.hasEntry("organization", "testOrganization"))
assertThat(challengeResponse, Matchers.`is`(Matchers.notNullValue()))
assertThat(challengeResponse.authSession, Matchers.comparesEqualTo(SESSION_ID))
@@ -2749,7 +2754,6 @@ public class AuthenticationAPIClientTest {
private const val FIRST_NAME = "John"
private const val LAST_NAME = "Doe"
private const val COMPANY = "Auth0"
- private const val OPENID = "openid"
private const val DEFAULT_LOCALE_IF_MISSING = "en_US"
}
}
\ No newline at end of file
diff --git a/auth0/src/test/java/com/auth0/android/provider/PasskeyManagerTest.kt b/auth0/src/test/java/com/auth0/android/provider/PasskeyManagerTest.kt
index 4c39dea3..3f99b78d 100644
--- a/auth0/src/test/java/com/auth0/android/provider/PasskeyManagerTest.kt
+++ b/auth0/src/test/java/com/auth0/android/provider/PasskeyManagerTest.kt
@@ -140,7 +140,8 @@ public class PasskeyManagerTest {
authenticationAPIClient.signinWithPasskey(
any(),
any(),
- any()
+ any(),
+ eq(null)
)
).thenReturn(
AuthenticationRequestMock(
@@ -185,7 +186,10 @@ public class PasskeyManagerTest {
verify(authenticationAPIClient).signupWithPasskey(userMetadata, "testRealm")
verify(credentialManager).createCredentialAsync(eq(context), any(), any(), any(), any())
- verify(authenticationAPIClient).signinWithPasskey(any(), any(), any())
+ verify(authenticationAPIClient).signinWithPasskey(
+ any(), any(), any(),
+ eq(null)
+ )
verify(callback).onSuccess(credentialsCaptor.capture())
Assert.assertEquals("codeAccess", credentialsCaptor.firstValue.accessToken)
Assert.assertEquals("codeScope", credentialsCaptor.firstValue.scope)
@@ -215,7 +219,8 @@ public class PasskeyManagerTest {
verify(authenticationAPIClient, never()).signinWithPasskey(
any(),
any(),
- any()
+ any(),
+ eq(null)
)
verify(credentialManager, never()).createCredentialAsync(
any(),
@@ -265,7 +270,7 @@ public class PasskeyManagerTest {
verify(authenticationAPIClient, never()).signinWithPasskey(
any(),
any(),
- any()
+ any(), eq(null)
)
verify(callback).onFailure(exceptionCaptor.capture())
Assert.assertEquals(
@@ -292,7 +297,14 @@ public class PasskeyManagerTest {
PublicKeyCredential(registrationResponseJSON)
)
- `when`(authenticationAPIClient.signinWithPasskey(any(), any(), any())).thenReturn(
+ `when`(
+ authenticationAPIClient.signinWithPasskey(
+ any(),
+ any(),
+ any(),
+ eq(null)
+ )
+ ).thenReturn(
AuthenticationRequestMock(
Credentials(
"expectedIdToken",
@@ -324,7 +336,10 @@ public class PasskeyManagerTest {
any(),
any()
)
- verify(authenticationAPIClient).signinWithPasskey(any(), any(), any())
+ verify(authenticationAPIClient).signinWithPasskey(
+ any(), any(), any(),
+ eq(null)
+ )
verify(callback).onSuccess(credentialsCaptor.capture())
Assert.assertEquals("codeAccess", credentialsCaptor.firstValue.accessToken)
Assert.assertEquals("codeScope", credentialsCaptor.firstValue.scope)
@@ -342,7 +357,7 @@ public class PasskeyManagerTest {
passkeyManager.signin(context, "testRealm", parameters, callback, serialExecutor)
- verify(authenticationAPIClient).passkeyChallenge(any())
+ verify(authenticationAPIClient).passkeyChallenge(any(), eq(null))
verify(credentialManager, never()).getCredentialAsync(
any(),
any(),
@@ -350,7 +365,12 @@ public class PasskeyManagerTest {
any(),
any()
)
- verify(authenticationAPIClient, never()).signinWithPasskey(any(), any(), any())
+ verify(authenticationAPIClient, never()).signinWithPasskey(
+ any(),
+ any(),
+ any(),
+ eq(null)
+ )
verify(callback).onFailure(error)
}
@@ -384,7 +404,12 @@ public class PasskeyManagerTest {
any(),
any()
)
- verify(authenticationAPIClient, never()).signinWithPasskey(any(), any(), any())
+ verify(authenticationAPIClient, never()).signinWithPasskey(
+ any(),
+ any(),
+ any(),
+ eq(null)
+ )
verify(callback).onFailure(exceptionCaptor.capture())
Assert.assertEquals(
AuthenticationException::class.java,