Skip to content

feat: Upgrade Auth0.Android to v4.0.0. - #918

Merged
utkrishtsahu merged 8 commits into
develop/v3.0from
feat/android-auth0-v4-bump
Aug 7, 2026
Merged

feat: Upgrade Auth0.Android to v4.0.0.#918
utkrishtsahu merged 8 commits into
develop/v3.0from
feat/android-auth0-v4-bump

Conversation

@utkrishtsahu

@utkrishtsahu utkrishtsahu commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

📋 Changes

Upgrades the Android side of the SDK to Auth0.Android v4 and gets the native bridge compiling and passing against the new major. This covers tickets A-1, A-2, and A-3 on the v3 Android track, plus the compile-blocking pieces of A-4 and A-5 (targets develop/v3.0).

A-1 — Dependency bump & build floor (android/build.gradle, example/android/*)

  • com.auth0.android:auth0 3.21.04.0.0; Gson 2.10.12.11.0
  • minSdkVersion 2126, compileSdk/targetSdk 3436
  • AGP 8.4.08.10.1, Kotlin 1.9.02.0.21, Java/jvmTarget 817, Gradle wrapper 8.78.11.1
  • Example app raised to the same floor (minSdk 26, compile/target 36, JDK 17, AGP/Kotlin pins)

A-2 — SecureCredentialsManager construction

  • v4 removed the constructors that took an Auth0 instance; the manager is now built from AuthenticationAPIClient (CredentialsManagerMethodCallHandler.kt). No Dart API change.

A-3 — Inline MFA routed through MfaApiClient

  • v4 removed AuthenticationAPIClient.loginWithOTP / multifactorChallenge. LoginWithOtpApiRequestHandler now calls mfaClient(mfaToken).verify(Otp(otp)); MultifactorChallengeApiRequestHandler now calls mfaClient(mfaToken).challenge(authenticatorId). On Android authenticatorId is now required and types is ignored (matching iOS from feat: Upgrade Auth0.swift to v3.0.2 #909). No Dart signature change — the shared Dart surface is realigned later in S-A.

A-4 — SSOCredentials.expiresInexpiresAt (compile-blocker pulled forward)

  • v4 renamed SSOCredentials.expiresIn (Int, seconds) to expiresAt (Date). SSOExchangeApiRequestHandler and GetSSOCredentialsRequestHandler now convert the absolute Date back to seconds-until-expiry and keep sending it under the expiresIn key, mirroring the iOS handler from feat: Upgrade Auth0.swift to v3.0.2 #909. No Dart model change — the expiresAt rename on the shared Dart model lands in S-A.

A-5 — useDPoP moved to the login builder (compile-blocker pulled forward)

  • v4 moved useDPoP off the global WebAuthProvider onto the login builder: WebAuthProvider.useDPoP(context)builder.useDPoP(context) (LoginWebAuthRequestHandler.kt). Required for the module to compile; full per-request DPoP work remains A-5.

Docs

  • Adds auth0_flutter/V3_MIGRATION_GUIDE.md (living doc) covering the Android requirement bumps, the clearCredentials full-wipe behavior change, and the multifactorChallenge authenticatorId requirement.

Public API: unchanged in this PR. Management API, passkey providers, and dedicated MFA handlers required no changes — no removed-API references remained for them.

🎯 Testing

  • Unit tests updated: LoginWithOtpApiRequestHandlerTest and MultifactorChallengeApiRequestHandlerTest were reworked to mock the mfaClient().verify() / mfaClient().challenge() chain and the new MfaVerifyException / MfaChallengeException callbacks. Added a missing authenticatorId test for the challenge handler. Existing success/error/response-shape assertions are preserved.
  • SSO tests updated: SSOExchangeApiRequestHandlerTest and GetSSOCredentialsRequestHandlerTest now mock expiresAt (a Date) and assert the converted seconds value.

Summary by CodeRabbit

  • New Features

    • Added support for the latest Auth0 Android SDK and updated Android build requirements, including Android 8.0+, Java 17, and compile SDK 36.
    • Updated OTP login and multifactor challenge flows to use the latest authentication behavior.
    • Improved SSO credential expiration handling for more accurate remaining-session times.
    • Updated DPoP configuration for web authentication.
  • Documentation

    • Added a v2-to-v3 migration guide covering platform requirements, behavior changes, migration examples, and troubleshooting guidance.

…26, compile/target 36, AGP 8.10.1, Kotlin 2.0.21, JDK 17, Gradle 8.11.1, Gson 2.11.0.
… v4 removed the constructors taking an Auth0 instance construct from AuthenticationAPIClient instead. clearCredentials() now full-wipes via Storage.removeAll()
v4 removed AuthenticationAPIClient.loginWithOTP/multifactorChallenge; reroute both through mfaClient. challenge() takes only authenticatorId (now required, types ignored)
v4 removed WebAuthProvider.useDPoP; DPoP is now configured per-request on the login builder.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • main
  • beta-release/.*
  • release/.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 31cde28d-bd60-43ae-82e3-11107fa02e88

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: upgrading Auth0.Android to version 4.0.0.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…id v4

v4 renamed SSOCredentials.expiresIn (Int seconds) to expiresAt (Date). Convert back to seconds-until-expiry so the Dart model is unchanged, mirroring iOS (#909).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/CredentialsManagerMethodCallHandler.kt`:
- Line 116: Replace the force-cast in the SecureCredentialsManager construction
flow with a safe cast to FragmentActivity. Validate the cast result before
constructing SecureCredentialsManager, and route a null activity through
result.error instead of allowing a ClassCastException.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt`:
- Around line 22-38: Replace throwing validation and unsafe String casts in
MultifactorChallengeApiRequestHandler and LoginWithOtpApiRequestHandler with
safe extraction of required values; when mfaToken, authenticatorId, or OTP
request values are missing or malformed, call result.error(...) exactly once and
return before creating the API request. Update
MultifactorChallengeApiRequestHandlerTest and LoginWithOtpApiRequestHandlerTest
to assert result.error(...) for missing properties and add malformed-type cases;
the listed LoginWithOtpApiRequestHandler.kt site requires the same handler
change, and its corresponding test requires the same assertion updates.

In
`@auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt`:
- Around line 205-206: Make both SSO expiry tests deterministic by using a fixed
or captured clock when creating mock expiresAt values, then assert the exact
expected expiresIn delta instead of a timing window; update
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt
lines 205-206 and
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/credentials_manager/GetSSOCredentialsRequestHandlerTest.kt
lines 138-141. In both assertions, replace the unsafe Long cast with a safe
numeric extraction that explicitly fails for missing or non-numeric expiresIn
values.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8d6df1ef-f34a-4f9f-8cb2-3d3f19c76f9f

📥 Commits

Reviewing files that changed from the base of the PR and between 2cf6765 and e8fc37e.

⛔ Files ignored due to path filters (3)
  • auth0_flutter/example/android/app/build.gradle is excluded by !**/example/**
  • auth0_flutter/example/android/gradle/wrapper/gradle-wrapper.properties is excluded by !**/example/**
  • auth0_flutter/example/android/settings.gradle is excluded by !**/example/**
📒 Files selected for processing (13)
  • auth0_flutter/V3_MIGRATION_GUIDE.md
  • auth0_flutter/android/build.gradle
  • auth0_flutter/android/gradle/wrapper/gradle-wrapper.properties
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/CredentialsManagerMethodCallHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/credentials_manager/GetSSOCredentialsRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/web_auth/LoginWebAuthRequestHandler.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/credentials_manager/GetSSOCredentialsRequestHandlerTest.kt

Comment on lines +22 to +38
// v4 removed AuthenticationAPIClient.multifactorChallenge; the challenge
// now goes through MfaApiClient, whose challenge() takes only an
// authenticatorId (no challenge-type filtering). `authenticatorId` is
// therefore now required and any `types` value is ignored; the shared
// Dart surface is realigned separately in the integration PR (S-A).
assertHasProperties(listOf("mfaToken", "authenticatorId"), request.data)

val builder = api
.mfaClient(request.data["mfaToken"] as String)
.challenge(request.data["authenticatorId"] as String)

builder.start(object : Callback<Challenge, MfaChallengeException> {
override fun onFailure(exception: MfaChallengeException) {
result.error(
exception.getCode(),
exception.getDescription(),
exception.toMap()
exception.toMfaMap()

@coderabbitai coderabbitai Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files 'auth0_flutter/android/src/main/kotlin/**' 'auth0_flutter/android/src/test/kotlin/**' | grep -E '(^|/)MultifactorChallengeApiRequestHandler\.kt$|(^|/)LoginWithOtpApiRequestHandler\.kt$|(^|/).*ApiRequestHandler.*Test\.kt$' || true

echo
echo "Outline related files:"
for f in auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt \
         auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt; do
  if [ -f "$f" ]; then
    echo "--- $f"
    wc -l "$f"
    ast-grep outline "$f" || true
  fi
done

echo
echo "Relevant source excerpts:"
for f in auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt \
         auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt; do
  if [ -f "$f" ]; then
    echo "--- $f"
    cat -n "$f"
  fi
done

echo
echo "Relevant tests:"
for f in auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandlerTest.kt \
         auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandlerTest.kt; do
  if [ -f "$f" ]; then
    echo "--- $f"
    cat -n "$f"
  fi
done

echo
echo "Search assertHasProperties and Method call result handling"
rg -n "fun assertHasProperties|assertHasProperties|Result|result\.(success|error|notImplemented)|MethodCallRequest|MethodCall\.data" auth0_flutter/android/src main/kotlin auth0_flutter/android/src/test/kotlin 2>/dev/null || true

Repository: auth0/auth0-flutter

Length of output: 50376


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Target files exist:"
for f in auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt \
         auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt \
         auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandlerTest.kt
do
  if [ -f "$f" ]; then
    echo "$f"
    wc -l "$f"
  else
    echo "MISSING: $f"
  fi
done

echo
echo "Main handler excerpts:"
for f in auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt \
         auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt
do
  if [ -f "$f" ]; then
    echo "--- $f"
    cat -n "$f"
  fi
done

echo
echo "Multifactor test excerpt:"
f='auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandlerTest.kt'
if [ -f "$f" ]; then
  sed -n '1,90p' "$f" | cat -n
fi

echo
echo "Login OTP test file if present:"
f='auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandlerTest.kt'
if [ -f "$f" ]; then
  cat -n "$f"
else
  echo "MISSING: $f"
fi

echo
echo "assertHasProperties definition:"
rg -n "fun assertHasProperties|internal fun assertHasProperties|private fun assertHasProperties|assertHasProperties" auth0_flutter/android/src/main/kotlin auth0_flutter/android/src/test/kotlin | head -100

Repository: auth0/auth0-flutter

Length of output: 32485


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "assertHas_PROPERTIES implementation:"
cat -n auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/utils/assertHasProperties.kt

echo
echo "MethodCallRequest definition:"
cat -n auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/MethodCallRequest.kt

echo
echo "Related existing validation/result pattern examples:"
rg -n -C 5 "as\\? String|as String|illegalArgument|result\\.error\\(|illegalArgument|require\\(" auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/utils | head -200

Repository: auth0/auth0-flutter

Length of output: 33683


Return MethodChannel errors for invalid MFA request input.

assertHasProperties throws before result is used, and both handlers cast MethodChannel values with as String. A missing required value or wrong payload type should call result.error(...) once and return. Update the existing exception-only tests for MultifactorChallengeApiRequestHandler and LoginWithOtpApiRequestHandler to assert the result.error(...) behavior and add malformed-type coverage.

  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt: replace the throwing presence check and as String casts with safe casts and result.error(...) handling.
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt: replace the throwing presence check and as String casts with safe casts and result.error(...) handling.
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandlerTest.kt and LoginWithOtpApiRequestHandlerTest.kt: replace missing-property exception tests with result.error(...) assertions and add malformed-type coverage.
📍 Affects 3 files
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt#L22-L38 (this comment)
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithOtpApiRequestHandler.kt#L29-L40
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandlerTest.kt#L43-L58
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt`
around lines 22 - 38, Replace throwing validation and unsafe String casts in
MultifactorChallengeApiRequestHandler and LoginWithOtpApiRequestHandler with
safe extraction of required values; when mfaToken, authenticatorId, or OTP
request values are missing or malformed, call result.error(...) exactly once and
return before creating the API request. Update
MultifactorChallengeApiRequestHandlerTest and LoginWithOtpApiRequestHandlerTest
to assert result.error(...) for missing properties and add malformed-type cases;
the listed LoginWithOtpApiRequestHandler.kt site requires the same handler
change, and its corresponding test requires the same assertion updates.

Source: Path instructions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the established validation pattern (assertHasProperties + cast) used consistently across all handlers in the module. Changing it here would diverge from the rest of the codebase; reworking the validation approach is out of scope for the v4 bump.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@utkrishtsahu, acknowledged. This PR should keep the established validation pattern.

The unchecked casts remain a MethodChannel crash risk, so I will keep the finding unresolved rather than request a local exception to the module convention. Would you like me to create a follow-up GitHub issue for a module-wide validation update?


✏️ Learnings added
Learnt from: utkrishtsahu
Repo: auth0/auth0-flutter PR: 918
File: auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/MultifactorChallengeApiRequestHandler.kt:0-0
Timestamp: 2026-08-07T08:14:31.573Z
Learning: The Android request handlers in `auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers` consistently use `assertHasProperties` followed by unchecked casts for MethodChannel request validation. Changes to this validation pattern should be handled as a module-wide refactor, not as part of an Auth0.Android v4 migration.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Comment on lines +205 to +206
// Converted from an absolute Date, so allow a small execution-time delta.
assertThat((resultMap["expiresIn"] as Long) in 58L..60L, equalTo(true))

@coderabbitai coderabbitai Bot Aug 6, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | rg 'SSOExchangeApiRequestHandlerTest\.kt|GetSSOCredentialsRequestHandlerTest\.kt|auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers' || true

echo
echo "Test snippets:"
for f in \
  auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt \
  auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/credentials_manager/GetSSOCredentialsRequestHandlerTest.kt
do
  if [ -f "$f" ]; then
    echo "--- $f"
    wc -l "$f"
    sed -n '160,225p' "$f"
    echo
    sed -n '110,155p' "$f"
    echo
  fi
done

echo
echo "Search expiresIn production test fixtures:"
rg -n 'expiresIn|System\.currentTimeMillis|Instant|Date\(|afterExpiresIn|beforeExpiresOn|expiresOn|expires in|TTL|ttl' auth0_flutter/android/src/test auth0_flutter/android/src/main || true

Repository: auth0/auth0-flutter

Length of output: 25112


Make the SSO expiry assertions deterministic and type-safe.

Both tests use System.currentTimeMillis() for the mock expiresAt and then assert a two-second window. Slow CI execution can fail correct conversions. Use a fixed/captured clock for the conversion, then assert an exact delta or deterministic token expiry. Also replace (resultMap["expiresIn"] as Long) with a safe cast/error path that rejects missing or non-numeric values.

📍 Affects 2 files
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt#L205-L206 (this comment)
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/credentials_manager/GetSSOCredentialsRequestHandlerTest.kt#L138-L141
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt`
around lines 205 - 206, Make both SSO expiry tests deterministic by using a
fixed or captured clock when creating mock expiresAt values, then assert the
exact expected expiresIn delta instead of a timing window; update
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/SSOExchangeApiRequestHandlerTest.kt
lines 205-206 and
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/credentials_manager/GetSSOCredentialsRequestHandlerTest.kt
lines 138-141. In both assertions, replace the unsafe Long cast with a safe
numeric extraction that explicitly fails for missing or non-numeric expiresIn
values.

Source: Path instructions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional: the handler derives expiresIn from expiresAt - now, so a small delta is expected. The range keeps the test robust without injecting a clock abstraction. Kept as-is.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@utkrishtsahu Understood. The timing window matches the current expiresAt - now conversion contract and avoids adding a clock abstraction. I will leave this unchanged.

🐇

You are interacting with an AI system.

v4 made AuthenticationMethod and EnrollmentChallenge sealed classes, which Mockito cannot mock. Use concrete subclass instances in the affected success tests
}

override fun onSuccess(credentials: SSOCredentials) {
// v4 renamed SSOCredentials.expiresIn (seconds) to expiresAt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets clean up all these AI generated comments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


assertHasProperties(listOf("mfaToken", "otp"), args)

// v4 removed AuthenticationAPIClient.loginWithOTP; the inline MFA OTP

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need these comments?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


builder.start(object : Callback<Challenge, AuthenticationException> {
override fun onFailure(exception: AuthenticationException) {
// v4 removed AuthenticationAPIClient.multifactorChallenge; the challenge

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@utkrishtsahu
utkrishtsahu merged commit 3d68c9f into develop/v3.0 Aug 7, 2026
13 checks passed
@utkrishtsahu
utkrishtsahu deleted the feat/android-auth0-v4-bump branch August 7, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants