-
Notifications
You must be signed in to change notification settings - Fork 165
Expanding Flexible Factors Grant Android Support #896
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -84,6 +84,31 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe | |||||
| return this | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Creates a new [MfaApiClient] to handle a multi-factor authentication transaction. | ||||||
| * | ||||||
| * Example usage: | ||||||
| * ``` | ||||||
| * try { | ||||||
| * val credentials = authClient.login("user@example.com", "password").await() | ||||||
| * } catch (error: AuthenticationException) { | ||||||
| * if (error.isMultifactorRequired) { | ||||||
| * val mfaToken = error.mfaToken | ||||||
| * if (mfaToken != null) { | ||||||
| * val mfaClient = authClient.mfa(mfaToken) | ||||||
| * // Use mfaClient to handle MFA flow | ||||||
| * } | ||||||
| * } | ||||||
| * } | ||||||
| * ``` | ||||||
| * | ||||||
| * @param mfaToken The token received in the 'mfa_required' error from a login attempt. | ||||||
| * @return A new [MfaApiClient] instance configured for the transaction. | ||||||
| */ | ||||||
| public fun mfa(mfaToken: String): MfaApiClient { | ||||||
| return MfaApiClient(this.auth0, mfaToken) | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Log in a user with email/username and password for a connection/realm. | ||||||
| * It will use the password-realm grant type for the `/oauth/token` endpoint | ||||||
|
|
@@ -1081,7 +1106,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe | |||||
| return factory.get(url.toString(), userProfileAdapter, dPoP) | ||||||
| } | ||||||
|
|
||||||
| private companion object { | ||||||
| internal companion object { | ||||||
| private const val SMS_CONNECTION = "sms" | ||||||
| private const val EMAIL_CONNECTION = "email" | ||||||
| private const val USERNAME_KEY = "username" | ||||||
|
|
@@ -1122,7 +1147,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe | |||||
| private const val WELL_KNOWN_PATH = ".well-known" | ||||||
| private const val JWKS_FILE_PATH = "jwks.json" | ||||||
| private const val TAG = "AuthenticationAPIClient" | ||||||
| private fun createErrorAdapter(): ErrorAdapter<AuthenticationException> { | ||||||
| internal fun createErrorAdapter(): ErrorAdapter<AuthenticationException> { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why make them internal ?
|
||||||
| internal fun createErrorAdapter(): ErrorAdapter<AuthenticationException> { | |
| private fun createErrorAdapter(): ErrorAdapter<AuthenticationException> { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,8 @@ import android.util.Log | |
| import com.auth0.android.Auth0Exception | ||
| import com.auth0.android.NetworkErrorException | ||
| import com.auth0.android.provider.TokenValidationException | ||
| import com.auth0.android.request.internal.GsonProvider | ||
| import com.auth0.android.result.MfaRequirements | ||
|
|
||
| public class AuthenticationException : Auth0Exception { | ||
| private var code: String? = null | ||
|
|
@@ -147,6 +149,26 @@ public class AuthenticationException : Auth0Exception { | |
| public val isMultifactorEnrollRequired: Boolean | ||
| get() = "a0.mfa_registration_required" == code || "unsupported_challenge_type" == code | ||
|
|
||
| /** | ||
| * The MFA token returned when multi-factor authentication is required. | ||
| * This token should be used to create an [MfaApiClient] to continue the MFA flow. | ||
| */ | ||
| public val mfaToken: String? | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep this as part of the |
||
| get() = getValue("mfa_token") as? String | ||
|
|
||
| /** | ||
| * The MFA requirements returned when multi-factor authentication is required. | ||
| * Contains information about the required challenge types. | ||
| */ | ||
| public val mfaRequirements: MfaRequirements? | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hope the name is consistent with Auth0.Swift implementation |
||
| get() = (getValue("mfa_requirements") as? Map<*, *>)?.let { | ||
| @Suppress("UNCHECKED_CAST") | ||
| GsonProvider.gson.fromJson( | ||
| GsonProvider.gson.toJson(it), | ||
| MfaRequirements::class.java | ||
| ) | ||
| } | ||
|
Comment on lines
+163
to
+170
|
||
|
|
||
| /// When Bot Protection flags the request as suspicious | ||
| public val isVerificationRequired: Boolean | ||
| get() = "requires_verification" == code | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename it to
mfaClient