Skip to content

feat : support to pass organisation while signing-up and signing-in with passkeys #843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -1048,7 +1049,7 @@ try {
)

val userCredential = authenticationApiClient.signinWithPasskey(
challenge.authSession, authRequest, "{realm}"
challenge.authSession, authRequest, "{realm}" , "{organization-id}"
)
.validateClaims()
.await()
Expand All @@ -1060,7 +1061,7 @@ try {
<summary>Using Java</summary>

```java
authenticationAPIClient.signupWithPasskey("{user-data}", "{realm}")
authenticationAPIClient.signupWithPasskey("{user-data}", "{realm}","{organization-id}")
.start(new Callback<PasskeyRegistrationChallenge, AuthenticationException>() {
@Override
public void onSuccess(PasskeyRegistrationChallenge result) {
Expand All @@ -1078,7 +1079,7 @@ try {
PublicKeyCredentials.class);

authenticationAPIClient.signinWithPasskey(result.getAuthSession(),
credentials, "{realm}")
credentials, "{realm}","{organization-id}")
.start(new Callback<Credentials, AuthenticationException>() {
@Override
public void onSuccess(Credentials result) {}
Expand All @@ -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
Expand All @@ -1122,7 +1123,8 @@ try {
val userCredential = authenticationApiClient.signinWithPasskey(
challenge.authSession,
authRequest,
"{realm}"
"{realm}",
"{organization-id}"
)
.validateClaims()
.await()
Expand All @@ -1138,7 +1140,7 @@ try {
<summary>Using Java</summary>

```java
authenticationAPIClient.passkeyChallenge("realm")
authenticationAPIClient.passkeyChallenge("realm","{organization-id}")
.start(new Callback<PasskeyChallenge, AuthenticationException>() {
@Override
public void onSuccess(PasskeyChallenge result) {
Expand All @@ -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<Credentials, AuthenticationException>() {
@Override
public void onSuccess(Credentials result) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -257,11 +260,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<PasskeyRegistrationChallenge, AuthenticationException> {
val user = gson.toJsonTree(userData)
val url = auth0.getDomainUrl().toHttpUrl().newBuilder()
Expand All @@ -272,6 +277,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<PasskeyRegistrationChallenge> =
Expand Down Expand Up @@ -304,7 +310,8 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* @return a request to configure and start that will yield [PasskeyChallenge]
*/
public fun passkeyChallenge(
realm: String? = null
realm: String? = null,
organization: String? = null
): Request<PasskeyChallenge, AuthenticationException> {
val url = auth0.getDomainUrl().toHttpUrl().newBuilder()
.addPathSegment(PASSKEY_PATH)
Expand All @@ -314,6 +321,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<PasskeyChallenge> = GsonAdapter(
Expand Down Expand Up @@ -1054,7 +1062,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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ public class AuthenticationAPIClientTest {
val callback = MockAuthenticationCallback<Credentials>()
val auth0 = auth0
val client = AuthenticationAPIClient(auth0)
client.signinWithPasskey("auth-session", mock<PublicKeyCredentials>(), MY_CONNECTION)
client.signinWithPasskey("auth-session", mock<PublicKeyCredentials>(), MY_CONNECTION,
"testOrganisation")
.start(callback)
ShadowLooper.idleMainLooper()
assertThat(
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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))
Expand All @@ -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(
Expand All @@ -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))

Expand Down Expand Up @@ -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"
}
}