From 7aff129250ddb10e6ff2653898ed66ca295c7249 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 30 Mar 2026 20:26:32 +0530 Subject: [PATCH 1/4] breaking: removed the deprecated MFA APIs from AuthenticationAPIClient class --- EXAMPLES.md | 56 ------ .../authentication/AuthenticationAPIClient.kt | 169 ---------------- .../com/auth0/android/result/Challenge.kt | 2 +- .../AuthenticationAPIClientTest.kt | 189 ------------------ 4 files changed, 1 insertion(+), 415 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 2b5690269..efb75aa4b 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -404,62 +404,6 @@ authentication > The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. -### Login using MFA with One Time Password code - -This call requires the client to have the *MFA* Client Grant Type enabled. Check [this article](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it. - -When you sign in to a multifactor authentication enabled connection using the `login` method, you receive an error standing that MFA is required for that user along with an `mfa_token` value. Use this value to call `loginWithOTP` and complete the MFA flow passing the One Time Password from the enrolled MFA code generator app. - -```kotlin -authentication - .loginWithOTP("the mfa token", "123456") - .validateClaims() //mandatory - .start(object: Callback { - override fun onFailure(exception: AuthenticationException) { } - - override fun onSuccess(credentials: Credentials) { } - }) -``` - -
- Using coroutines - -```kotlin -try { - val credentials = authentication - .loginWithOTP("the mfa token", "123456") - .validateClaims() - .await() - println(credentials) -} catch (e: AuthenticationException) { - e.printStacktrace() -} -``` -
- -
- Using Java - -```java -authentication - .loginWithOTP("the mfa token", "123456") - .validateClaims() //mandatory - .start(new Callback() { - @Override - public void onSuccess(@Nullable Credentials payload) { - //Logged in! - } - - @Override - public void onFailure(@NonNull AuthenticationException error) { - //Error! - } - }); -``` -
- -> The default scope used is `openid profile email`. Regardless of the scopes set to the request, the `openid` scope is always enforced. - ### MFA Flexible Factors Grant > [!IMPORTANT] 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 572ecc513..3086b533e 100755 --- a/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt +++ b/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt @@ -25,7 +25,6 @@ import com.auth0.android.request.internal.GsonAdapter.Companion.forMapOf import com.auth0.android.request.internal.GsonProvider import com.auth0.android.request.internal.RequestFactory import com.auth0.android.request.internal.ResponseUtils.isNetworkError -import com.auth0.android.result.Challenge import com.auth0.android.result.Credentials import com.auth0.android.result.DatabaseUser import com.auth0.android.result.PasskeyChallenge @@ -175,42 +174,6 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe } - /** - * Log in a user using the One Time Password code after they have received the 'mfa_required' error. - * The MFA token tells the server the username or email, password, and realm values sent on the first request. - * - * Requires your client to have the **MFA OTP** Grant Type enabled. See [Client Grant Types](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it. - * - * Example usage: - * - *``` - * client.loginWithOTP("{mfa token}", "{one time password}") - * .validateClaims() //mandatory - * .start(object : Callback { - * override fun onFailure(error: AuthenticationException) { } - * override fun onSuccess(result: Credentials) { } - * }) - *``` - * - * @param mfaToken the token received in the previous [.login] response. - * @param otp the one time password code provided by the resource owner, typically obtained from an - * MFA application such as Google Authenticator or Guardian. - * @return a request to configure and start that will yield [Credentials] - */ - @Deprecated( - message = "loginWithOTP is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.", - level = DeprecationLevel.WARNING - ) - public fun loginWithOTP(mfaToken: String, otp: String): AuthenticationRequest { - val parameters = ParameterBuilder.newBuilder() - .setGrantType(ParameterBuilder.GRANT_TYPE_MFA_OTP) - .set(MFA_TOKEN_KEY, mfaToken) - .set(ONE_TIME_PASSWORD_KEY, otp) - .asDictionary() - return loginWithToken(parameters) - } - - /** * Sign-in a user using passkeys. * This should be called after the client has received the passkey challenge from the server and generated the public key response. @@ -391,132 +354,6 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe .addParameters(parameters) } - /** - * Log in a user using an Out Of Band authentication code after they have received the 'mfa_required' error. - * The MFA token tells the server the username or email, password, and realm values sent on the first request. - * - * Requires your client to have the **MFA OOB** Grant Type enabled. See [Client Grant Types](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it. - * - * Example usage: - * - *``` - * client.loginWithOOB("{mfa token}", "{out of band code}", "{binding code}") - * .validateClaims() //mandatory - * .start(object : Callback { - * override fun onFailure(error: AuthenticationException) { } - * override fun onSuccess(result: Credentials) { } - * }) - *``` - * - * @param mfaToken the token received in the previous [.login] response. - * @param oobCode the out of band code received in the challenge response. - * @param bindingCode the code used to bind the side channel (used to deliver the challenge) with the main channel you are using to authenticate. - * This is usually an OTP-like code delivered as part of the challenge message. - * @return a request to configure and start that will yield [Credentials] - */ - @Deprecated( - message = "loginWithOOB is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.", - level = DeprecationLevel.WARNING - ) - public fun loginWithOOB( - mfaToken: String, - oobCode: String, - bindingCode: String? = null - ): AuthenticationRequest { - val parameters = ParameterBuilder.newBuilder() - .setGrantType(ParameterBuilder.GRANT_TYPE_MFA_OOB) - .set(MFA_TOKEN_KEY, mfaToken) - .set(OUT_OF_BAND_CODE_KEY, oobCode) - .set(BINDING_CODE_KEY, bindingCode) - .asDictionary() - return loginWithToken(parameters) - } - - /** - * Log in a user using a multi-factor authentication Recovery Code after they have received the 'mfa_required' error. - * The MFA token tells the server the username or email, password, and realm values sent on the first request. - * - * Requires your client to have the **MFA** Grant Type enabled. See [Client Grant Types](https://auth0.com/docs/clients/client-grant-types) to learn how to enable it. - * - * Example usage: - * - *``` - * client.loginWithRecoveryCode("{mfa token}", "{recovery code}") - * .validateClaims() //mandatory - * .start(object : Callback { - * override fun onFailure(error: AuthenticationException) { } - * override fun onSuccess(result: Credentials) { } - * }) - *``` - * - * @param mfaToken the token received in the previous [.login] response. - * @param recoveryCode the recovery code provided by the end-user. - * @return a request to configure and start that will yield [Credentials]. It might also include a [recoveryCode] field, - * which your application must display to the end-user to be stored securely for future use. - */ - @Deprecated( - message = "loginWithRecoveryCode is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.", - level = DeprecationLevel.WARNING - ) - public fun loginWithRecoveryCode( - mfaToken: String, - recoveryCode: String - ): AuthenticationRequest { - val parameters = ParameterBuilder.newBuilder() - .setGrantType(ParameterBuilder.GRANT_TYPE_MFA_RECOVERY_CODE) - .set(MFA_TOKEN_KEY, mfaToken) - .set(RECOVERY_CODE_KEY, recoveryCode) - .asDictionary() - return loginWithToken(parameters) - } - - /** - * Request a challenge for multi-factor authentication (MFA) based on the challenge types supported by the application and user. - * The challenge type is how the user will get the challenge and prove possession. Supported challenge types include: "otp" and "oob". - * - * Example usage: - * - *``` - * client.multifactorChallenge("{mfa token}", "{challenge type}", "{authenticator id}") - * .start(object : Callback { - * override fun onFailure(error: AuthenticationException) { } - * override fun onSuccess(result: Challenge) { } - * }) - *``` - * - * @param mfaToken the token received in the previous [.login] response. - * @param challengeType A whitespace-separated list of the challenges types accepted by your application. - * Accepted challenge types are oob or otp. Excluding this parameter means that your client application - * accepts all supported challenge types. - * @param authenticatorId The ID of the authenticator to challenge. - * @return a request to configure and start that will yield [Challenge] - */ - @Deprecated( - message = "multifactorChallenge is deprecated and will be removed in the next major version of the SDK. Use the APIs in the [com.auth0.android.authentication.mfa.MfaApiClient] class instead.", - level = DeprecationLevel.WARNING - ) - public fun multifactorChallenge( - mfaToken: String, - challengeType: String? = null, - authenticatorId: String? = null - ): Request { - val parameters = ParameterBuilder.newBuilder() - .setClientId(clientId) - .set(MFA_TOKEN_KEY, mfaToken) - .set(CHALLENGE_TYPE_KEY, challengeType) - .set(AUTHENTICATOR_ID_KEY, authenticatorId) - .asDictionary() - val url = auth0.getDomainUrl().toHttpUrl().newBuilder() - .addPathSegment(MFA_PATH) - .addPathSegment(CHALLENGE_PATH) - .build() - val challengeAdapter: JsonAdapter = GsonAdapter( - Challenge::class.java, gson - ) - return factory.post(url.toString(), challengeAdapter) - .addParameters(parameters) - } - /** * Log in a user using a token obtained from a Native Social Identity Provider, such as Facebook, using ['\oauth\token' endpoint](https://auth0.com/docs/api/authentication#token-exchange-for-native-social) * The default scope used is 'openid profile email'. @@ -1128,13 +965,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe private const val OAUTH_CODE_KEY = "code" private const val REDIRECT_URI_KEY = "redirect_uri" private const val TOKEN_KEY = "token" - private const val MFA_TOKEN_KEY = "mfa_token" private const val ONE_TIME_PASSWORD_KEY = "otp" - private const val OUT_OF_BAND_CODE_KEY = "oob_code" - private const val BINDING_CODE_KEY = "binding_code" - private const val CHALLENGE_TYPE_KEY = "challenge_type" - private const val AUTHENTICATOR_ID_KEY = "authenticator_id" - 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 ORGANIZATION_KEY = "organization" diff --git a/auth0/src/main/java/com/auth0/android/result/Challenge.kt b/auth0/src/main/java/com/auth0/android/result/Challenge.kt index b34231a61..7793c56c3 100755 --- a/auth0/src/main/java/com/auth0/android/result/Challenge.kt +++ b/auth0/src/main/java/com/auth0/android/result/Challenge.kt @@ -6,7 +6,7 @@ import com.google.gson.annotations.SerializedName /** * Multi-factor authentication (MFA) challenge * - * @see [com.auth0.android.authentication.AuthenticationAPIClient.multifactorChallenge] + * @see [com.auth0.android.authentication.mfa.MfaApiClient] */ public class Challenge( @field:JsonRequired @field:SerializedName("challenge_type") 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 cf2819427..c261573fa 100755 --- a/auth0/src/test/java/com/auth0/android/authentication/AuthenticationAPIClientTest.kt +++ b/auth0/src/test/java/com/auth0/android/authentication/AuthenticationAPIClientTest.kt @@ -18,7 +18,6 @@ import com.auth0.android.request.ServerResponse import com.auth0.android.request.internal.RequestFactory import com.auth0.android.request.internal.ThreadSwitcherShadow import com.auth0.android.result.Authentication -import com.auth0.android.result.Challenge import com.auth0.android.result.Credentials import com.auth0.android.result.DatabaseUser import com.auth0.android.result.SSOCredentials @@ -167,41 +166,6 @@ public class AuthenticationAPIClientTest { assertThat(client.baseURL, Matchers.equalTo("https://" + DOMAIN + "/")) } - @Test - public fun shouldLoginWithMFAOTPCode() { - mockAPI.willReturnSuccessfulLogin() - val callback = MockAuthenticationCallback() - val auth0 = auth0 - val client = AuthenticationAPIClient(auth0) - client.loginWithOTP("ey30.the-mfa-token.value", "123456") - .start(callback) - ShadowLooper.idleMainLooper() - assertThat( - callback, AuthenticationCallbackMatcher.hasPayloadOfType( - Credentials::class.java - ) - ) - val request = mockAPI.takeRequest() - assertThat( - request.getHeader("Accept-Language"), Matchers.`is`( - defaultLocale - ) - ) - val body = bodyFromRequest(request) - assertThat(request.path, Matchers.equalTo("/oauth/token")) - assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID)) - assertThat( - body, - Matchers.hasEntry("grant_type", "http://auth0.com/oauth/grant-type/mfa-otp") - ) - assertThat(body, Matchers.hasEntry("mfa_token", "ey30.the-mfa-token.value")) - assertThat(body, Matchers.hasEntry("otp", "123456")) - assertThat(body, Matchers.not(Matchers.hasKey("scope"))) - assertThat(body, Matchers.not(Matchers.hasKey("username"))) - assertThat(body, Matchers.not(Matchers.hasKey("password"))) - assertThat(body, Matchers.not(Matchers.hasKey("connection"))) - } - @Test public fun shouldSigninWithPasskey() { mockAPI.willReturnSuccessfulLogin() @@ -287,159 +251,6 @@ public class AuthenticationAPIClientTest { } - @Test - public fun shouldLoginWithMFARecoveryCode() { - mockAPI.willReturnSuccessfulLoginWithRecoveryCode() - val callback = MockAuthenticationCallback() - val auth0 = auth0 - val client = AuthenticationAPIClient(auth0) - client.loginWithRecoveryCode("ey30.the-mfa-token.value", "123456") - .start(callback) - ShadowLooper.idleMainLooper() - assertThat( - callback, AuthenticationCallbackMatcher.hasPayloadOfType( - Credentials::class.java - ) - ) - assertThat(callback.payload.recoveryCode, Matchers.`is`("654321")) - val request = mockAPI.takeRequest() - assertThat( - request.getHeader("Accept-Language"), Matchers.`is`( - defaultLocale - ) - ) - val body = bodyFromRequest(request) - assertThat(request.path, Matchers.equalTo("/oauth/token")) - assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID)) - assertThat( - body, - Matchers.hasEntry("grant_type", "http://auth0.com/oauth/grant-type/mfa-recovery-code") - ) - assertThat(body, Matchers.hasEntry("mfa_token", "ey30.the-mfa-token.value")) - assertThat(body, Matchers.hasEntry("recovery_code", "123456")) - assertThat(body, Matchers.not(Matchers.hasKey("scope"))) - } - - @Test - public fun shouldLoginWithMFAOOBCode() { - mockAPI.willReturnSuccessfulLogin() - val callback = MockAuthenticationCallback() - val auth0 = auth0 - val client = AuthenticationAPIClient(auth0) - client.loginWithOOB("ey30.the-mfa-token.value", "123456", null) - .start(callback) - ShadowLooper.idleMainLooper() - assertThat( - callback, AuthenticationCallbackMatcher.hasPayloadOfType( - Credentials::class.java - ) - ) - val request = mockAPI.takeRequest() - assertThat( - request.getHeader("Accept-Language"), Matchers.`is`( - defaultLocale - ) - ) - val body = bodyFromRequest(request) - assertThat(request.path, Matchers.equalTo("/oauth/token")) - assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID)) - assertThat( - body, - Matchers.hasEntry("grant_type", "http://auth0.com/oauth/grant-type/mfa-oob") - ) - assertThat(body, Matchers.hasEntry("mfa_token", "ey30.the-mfa-token.value")) - assertThat(body, Matchers.hasEntry("oob_code", "123456")) - assertThat(body, Matchers.not(Matchers.hasKey("scope"))) - assertThat(body, Matchers.not(Matchers.hasKey("binding_code"))) - } - - @Test - public fun shouldLoginWithMFAOOBCodeAndBindingCode() { - mockAPI.willReturnSuccessfulLogin() - val callback = MockAuthenticationCallback() - val auth0 = auth0 - val client = AuthenticationAPIClient(auth0) - client.loginWithOOB("ey30.the-mfa-token.value", "123456", "abcdefg") - .start(callback) - ShadowLooper.idleMainLooper() - assertThat( - callback, AuthenticationCallbackMatcher.hasPayloadOfType( - Credentials::class.java - ) - ) - val request = mockAPI.takeRequest() - assertThat( - request.getHeader("Accept-Language"), Matchers.`is`( - defaultLocale - ) - ) - val body = bodyFromRequest(request) - assertThat(request.path, Matchers.equalTo("/oauth/token")) - assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID)) - assertThat( - body, - Matchers.hasEntry("grant_type", "http://auth0.com/oauth/grant-type/mfa-oob") - ) - assertThat(body, Matchers.hasEntry("mfa_token", "ey30.the-mfa-token.value")) - assertThat(body, Matchers.hasEntry("oob_code", "123456")) - assertThat(body, Matchers.hasEntry("binding_code", "abcdefg")) - assertThat(body, Matchers.not(Matchers.hasKey("scope"))) - } - - @Test - public fun shouldStartMFAChallenge() { - mockAPI.willReturnSuccessfulMFAChallenge() - val callback = MockAuthenticationCallback() - client.multifactorChallenge("ey30.the-mfa-token.value", null, null) - .start(callback) - ShadowLooper.idleMainLooper() - val request = mockAPI.takeRequest() - assertThat( - request.getHeader("Accept-Language"), Matchers.`is`( - defaultLocale - ) - ) - assertThat(request.path, Matchers.equalTo("/mfa/challenge")) - val body = bodyFromRequest(request) - assertThat(body, Matchers.hasEntry("mfa_token", "ey30.the-mfa-token.value")) - assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID)) - assertThat(body, Matchers.not(Matchers.hasKey("challenge_type"))) - assertThat(body, Matchers.not(Matchers.hasKey("authenticator_id"))) - assertThat(body, Matchers.not(Matchers.hasKey("scope"))) - assertThat( - callback, AuthenticationCallbackMatcher.hasPayloadOfType( - Challenge::class.java - ) - ) - } - - @Test - public fun shouldStartMFAChallengeWithTypeAndAuthenticator() { - mockAPI.willReturnSuccessfulMFAChallenge() - val callback = MockAuthenticationCallback() - client.multifactorChallenge("ey30.the-mfa-token.value", "oob", "sms|dev_NU1Ofuw3Cw0XCt5x") - .start(callback) - ShadowLooper.idleMainLooper() - val request = mockAPI.takeRequest() - assertThat( - request.getHeader("Accept-Language"), Matchers.`is`( - defaultLocale - ) - ) - assertThat(request.path, Matchers.equalTo("/mfa/challenge")) - val body = bodyFromRequest(request) - assertThat(body, Matchers.hasEntry("mfa_token", "ey30.the-mfa-token.value")) - assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID)) - assertThat(body, Matchers.hasEntry("challenge_type", "oob")) - assertThat(body, Matchers.hasEntry("authenticator_id", "sms|dev_NU1Ofuw3Cw0XCt5x")) - assertThat(body, Matchers.not(Matchers.hasKey("scope"))) - assertThat( - callback, AuthenticationCallbackMatcher.hasPayloadOfType( - Challenge::class.java - ) - ) - } - @Test public fun shouldLoginWithUserAndPasswordSync() { val jwt = JwtTestUtils.createTestJWT("HS256", mapOf("sub" to "auth0|123456")) From 18d763a72433e9f5355a350a80bbaa4a0fdd4237 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 30 Mar 2026 20:37:15 +0530 Subject: [PATCH 2/4] Updated the migration guide --- V4_MIGRATION_GUIDE.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/V4_MIGRATION_GUIDE.md b/V4_MIGRATION_GUIDE.md index ea4fe01eb..8e858f157 100644 --- a/V4_MIGRATION_GUIDE.md +++ b/V4_MIGRATION_GUIDE.md @@ -14,6 +14,7 @@ v4 of the Auth0 Android SDK includes significant build toolchain updates, update + [Kotlin Version](#kotlin-version) - [**Breaking Changes**](#breaking-changes) + [Classes Removed](#classes-removed) + + [Deprecated MFA Methods Removed from AuthenticationAPIClient](#deprecated-mfa-methods-removed-from-authenticationapiclient) + [DPoP Configuration Moved to Builder](#dpop-configuration-moved-to-builder) + [SSOCredentials.expiresIn Renamed to expiresAt](#ssocredentialsexpiresin-renamed-to-expiresat) - [**Default Values Changed**](#default-values-changed) @@ -110,6 +111,15 @@ buildscript { 2. Call that endpoint from your app, passing the user's access token as a `Bearer` token in the `Authorization` header. 3. On your backend, obtain a machine-to-machine token via the Client Credentials flow and use it to call the Management API with the precise scopes required. +### Deprecated MFA Methods Removed from AuthenticationAPIClient + +The following MFA methods have been removed from `AuthenticationAPIClient`. They were deprecated in v3 in favor of the `MfaApiClient` class APIs. + +- `loginWithOTP(mfaToken, otp)` +- `loginWithOOB(mfaToken, oobCode, bindingCode)` +- `loginWithRecoveryCode(mfaToken, recoveryCode)` +- `multifactorChallenge(mfaToken, challengeType, authenticatorId)` + ### DPoP Configuration Moved to Builder The `useDPoP(context: Context)` method has been moved from the `WebAuthProvider` object to the login From e281ce9ee9285bf6c4ab8fc8473e168377cf2a05 Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Mon, 30 Mar 2026 21:37:14 +0530 Subject: [PATCH 3/4] Addressed review comments --- V4_MIGRATION_GUIDE.md | 2 ++ .../com/auth0/android/authentication/AuthenticationAPIClient.kt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/V4_MIGRATION_GUIDE.md b/V4_MIGRATION_GUIDE.md index 8e858f157..736a3ddee 100644 --- a/V4_MIGRATION_GUIDE.md +++ b/V4_MIGRATION_GUIDE.md @@ -120,6 +120,8 @@ The following MFA methods have been removed from `AuthenticationAPIClient`. They - `loginWithRecoveryCode(mfaToken, recoveryCode)` - `multifactorChallenge(mfaToken, challengeType, authenticatorId)` +Use `AuthenticationAPIClient.mfaClient(mfaToken)` to obtain a `MfaApiClient` instance and handle MFA flows using the new APIs. See the [MFA Flexible Factors Grant](EXAMPLES.md#mfa-flexible-factors-grant) section in `EXAMPLES.md` for usage guidance. + ### DPoP Configuration Moved to Builder The `useDPoP(context: Context)` method has been moved from the `WebAuthProvider` object to the login 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 3086b533e..9b0e45861 100755 --- a/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt +++ b/auth0/src/main/java/com/auth0/android/authentication/AuthenticationAPIClient.kt @@ -982,7 +982,6 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe private const val TOKEN_PATH = "token" private const val USER_INFO_PATH = "userinfo" private const val REVOKE_PATH = "revoke" - private const val MFA_PATH = "mfa" private const val CHALLENGE_PATH = "challenge" private const val PASSKEY_PATH = "passkey" private const val REGISTER_PATH = "register" From 28a27096ff3cca6171d7958f4b403fd223ac36ee Mon Sep 17 00:00:00 2001 From: Prince Mathew Date: Tue, 31 Mar 2026 10:18:54 +0530 Subject: [PATCH 4/4] Removed dead links from Table of Contents --- EXAMPLES.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index efb75aa4b..49c6ac0b6 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -15,14 +15,12 @@ - [DPoP](#dpop) - [Authentication API](#authentication-api) - [Login with database connection](#login-with-database-connection) - - [Login using MFA with One Time Password code](#login-using-mfa-with-one-time-password-code) - [MFA Flexible Factors Grant](#mfa-flexible-factors-grant) - [Understanding the mfa_required Error Payload](#understanding-the-mfa_required-error-payload) - [Handling MFA Required Errors](#handling-mfa-required-errors) - [Getting Available Authenticators](#getting-available-authenticators) - [Enrolling New Authenticators](#enrolling-new-authenticators) - [Challenging an Authenticator](#challenging-an-authenticator) - - [Verifying MFA](#verifying-mfa) - [MFA Client Errors](#mfa-client-errors) - [Passwordless Login](#passwordless-login) - [Step 1: Request the code](#step-1-request-the-code) @@ -52,11 +50,6 @@ - [Handling Credentials Manager exceptions](#handling-credentials-manager-exceptions) - [Passkeys](#passkeys) - [Bot Protection](#bot-protection) - - [Management API](#management-api) - - [Link users](#link-users) - - [Unlink users](#unlink-users) - - [Get User Profile](#get-user-profile) - - [Update User Metadata](#update-user-metadata) - [Token Validation](#token-validation) - [Organizations](#organizations) - [Log in to an organization](#log-in-to-an-organization)