Skip to content

feat: Adds passkeys support to flutter SDK#858

Merged
NandanPrabhu merged 5 commits into
mainfrom
feat/passkeys_apis
Jun 12, 2026
Merged

feat: Adds passkeys support to flutter SDK#858
NandanPrabhu merged 5 commits into
mainfrom
feat/passkeys_apis

Conversation

@NandanPrabhu

@NandanPrabhu NandanPrabhu commented Jun 9, 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

PR adds Passkeys support to Flutter SDK

  1. Signup with Passkeys
  2. Login with Passkeys
  3. Passkeys enrollment

📎 References

https://auth0.com/docs/authenticate/database-connections/passkeys/native-passkeys-api
https://auth0.com/docs/api/myaccount/authentication-methods/create-authentication-method

🎯 Testing

Summary by CodeRabbit

Release Notes

  • New Features

    • Added passkey-based authentication for login and signup flows
    • Added passkey enrollment and management for authenticated users
    • Cross-platform passkey support across iOS, macOS, and Android
  • Documentation

    • Added comprehensive passkey implementation guides and examples with code samples

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Passkey login, signup, credential exchange, and My Account enrollment are added across the shared Dart APIs, platform interfaces, native handlers, examples, tests, docs, and build configuration. iOS and macOS now share Darwin implementations, and the example apps wire passkey UI through platform credentials.

Changes

Passkey authentication and My Account enrollment

Layer / File(s) Summary
Auth passkey contracts and public API surface
auth0_flutter/lib/..., auth0_flutter_platform_interface/lib/...
Adds passkey challenge, credential, and request-option types; new auth platform methods; new method-channel auth wiring; and Dart API entry points plus exports.
Auth passkey Dart tests and mocks
auth0_flutter_platform_interface/test/..., auth0_flutter/test/mobile/...
Adds passkey request/response coverage for platform-channel auth behavior and serialization, including generated mocks and fixture data.
My Account passkey contracts and channel surface
auth0_flutter/lib/src/mobile/my_account_api.dart, auth0_flutter_platform_interface/lib/..., auth0_flutter_platform_interface/test/...
Adds passkey enrollment request options and models, platform methods, method-channel wiring, Dart API entry points, and tests for challenge and enrollment exchange.
Android passkey handlers and lifecycle wiring
auth0_flutter/android/...
Adds Android passkey auth and enrollment request handlers, plugin registration, activity lifecycle nullability handling, and Robolectric coverage.
Darwin passkey handlers and shared source routing
auth0_flutter/darwin/..., auth0_flutter/ios/..., auth0_flutter/macos/...
Adds Darwin passkey auth and enrollment handlers, shared base64 helpers, unsupported-platform handling, platform gating, and iOS/macOS symlinked source routing.
Example app passkey integration and validation
auth0_flutter/example/...
Wires the example Android and iOS projects for passkey UI support and adds example app passkey login/signup flows plus iOS test coverage.
Documentation and support configuration
auth0_flutter/EXAMPLES.md, auth0_flutter/README.md, .github/workflows/main.yml
Adds passkey documentation links and flow descriptions, updates README references, and adjusts the Windows CI job configuration.
Example app Android and iOS support wiring
auth0_flutter/example/android/app/build.gradle, auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj
Adds Android Credential Manager dependencies and updates the iOS example project to compile passkey sources, tests, and signing settings.
Example app flow implementation
auth0_flutter/example/lib/example_app.dart
Adds passkey login and signup UI actions, credential acquisition, token previewing, and redacted output handling.
Example iOS test support
auth0_flutter/example/ios/Tests/AuthAPI/*
Adds iOS passkey spies and XCTest coverage for handler routing, base64 helpers, login challenge, signup challenge, and credential exchange.
Example passkey source links
auth0_flutter/ios/Classes/AuthAPI/*, auth0_flutter/macos/Classes/AuthAPI/*
Repoints platform-specific passkey Swift sources to the shared Darwin implementations.
Android auth and My Account native handlers
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/..., auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/...
Adds Android native passkey handlers for auth and enrollment, plus request mapping and callback tests.
Darwin auth and My Account native handlers
auth0_flutter/darwin/Classes/AuthAPI/*, auth0_flutter/darwin/Classes/MyAccountAPI/*
Adds Darwin native passkey handlers for auth and enrollment, challenge reconstruction, response mapping, and source-level routing.
Shared passkey data types and tests
auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart, auth0_flutter_platform_interface/test/passkey_credential_test.dart
Adds and validates passkey credential and authenticator response serialization.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/passkeys_apis

@NandanPrabhu NandanPrabhu changed the title feat: Adds passkeys login, signup and enrollment support to flutter SDKs feat: Adds native passkeys APIs support for login and support Jun 10, 2026
@NandanPrabhu NandanPrabhu marked this pull request as ready for review June 10, 2026 08:26
@NandanPrabhu NandanPrabhu requested a review from a team as a code owner June 10, 2026 08:26
@NandanPrabhu

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj (2)

127-127: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Duplicate PBXFileReference entry will corrupt the Xcode project.

Line 127 and line 158 contain identical PBXFileReference entries for CredentialsManagerSSOCredentialsMethodHandlerTests.swift. This duplication will cause Xcode project parsing errors.

🔧 Remove the duplicate entry
 		C16443EA2BA08C71AE68B41B /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
 		C7412C9A0F502116EC6D51D0 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
 		C8270E3F40357C2A1DB27BB8 /* Pods_Runner_RunnerUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_RunnerUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		A09B2E3F1D4C7891BA000001 /* CredentialsManagerSSOCredentialsMethodHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialsManagerSSOCredentialsMethodHandlerTests.swift; sourceTree = "<group>"; };
 		B0CA00010000000000000001 /* MyAccountSpies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAccountSpies.swift; sourceTree = "<group>"; };

Also applies to: 158-158

🤖 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/example/ios/Runner.xcodeproj/project.pbxproj` at line 127, The
project.pbxproj contains a duplicate PBXFileReference entry for
CredentialsManagerSSOCredentialsMethodHandlerTests.swift (GUID
A09B2E3F1D4C7891BA000001) which will break Xcode; remove the redundant
PBXFileReference block so only one entry with that GUID and path remains, and
then verify any references in PBXGroup or PBXSourcesBuildPhase (or similar
sections) point to the remaining GUID to avoid dangling or duplicated
references.

29-29: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Duplicate PBXBuildFile entry will corrupt the Xcode project.

Line 29 and line 49 contain identical PBXBuildFile entries for CredentialsManagerSSOCredentialsMethodHandlerTests.swift. Xcode project files must have unique object identifiers; duplicates cause project corruption and build failures.

🔧 Remove the duplicate entry
 		A0AC1D0F2E0000000000AC04 /* CredentialsManagerClearApiCredentialsMethodHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0AC1D0F2E0000000000AC03 /* CredentialsManagerClearApiCredentialsMethodHandlerTests.swift */; };
 		5C59DA6527FFCF0600365CDB /* AuthAPIHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C59DA6427FFCF0600365CDB /* AuthAPIHandlerTests.swift */; };
 		5C59DA6727FFE75600365CDB /* AuthAPILoginUsernameOrEmailMethodHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C59DA6627FFE75600365CDB /* AuthAPILoginUsernameOrEmailMethodHandlerTests.swift */; };
-		A09B2E3F1D4C7891BA000002 /* CredentialsManagerSSOCredentialsMethodHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A09B2E3F1D4C7891BA000001 /* CredentialsManagerSSOCredentialsMethodHandlerTests.swift */; };
 		A128A3E84540D9257B15491D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03C97032096FE7868ACD2E52 /* Pods_Runner.framework */; };

Also applies to: 49-49

🤖 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/example/ios/Runner.xcodeproj/project.pbxproj` at line 29, The
project file contains a duplicate PBXBuildFile entry for
CredentialsManagerSSOCredentialsMethodHandlerTests.swift (object ID
A09B2E3F1D4C7891BA000002 with fileRef A09B2E3F1D4C7891BA000001) which must be
removed; locate the duplicate PBXBuildFile block (the second occurrence around
the other PBXBuildFile entries) and delete it so there is only one PBXBuildFile
entry for that source file, then scan build phases, PBXGroup and any other
references to ensure they point to the remaining object ID (or update them to
the kept ID) to avoid dangling or duplicate identifiers.
🧹 Nitpick comments (7)
auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart (1)

1383-1661: ⚡ Quick win

Add null-result failure-path tests for new passkey channel methods.

The new passkey groups validate PlatformException, but they don’t assert behavior when the method channel returns null (a path already covered in other API groups). Adding these cases would keep passkey methods aligned with existing error-contract coverage.

🤖 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_platform_interface/test/method_channel_auth0_flutter_auth_test.dart`
around lines 1383 - 1661, The tests for the new passkey channels currently only
cover PlatformException paths but are missing the null-return failure-paths; add
unit tests that mock mocked.methodCallHandler to return null and assert that
MethodChannelAuth0FlutterAuth().passkeyLoginChallenge,
.passkeyCredentialExchange, and .passkeySignupChallenge each throw an
ApiException when the platform channel result is null, mirroring the existing
null-result tests for other API groups and using verify(captureAny) where
appropriate to locate the invoked method.
auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart (1)

28-31: ⚡ Quick win

Avoid exposing internal map references in serialization.

Line 30 returns authParamsPublicKey by reference, so callers mutating the returned map can mutate the model state unexpectedly.

Suggested change
   Map<String, dynamic> toMap() => {
         'authSession': authSession,
-        'authParamsPublicKey': authParamsPublicKey,
+        'authParamsPublicKey': Map<String, dynamic>.from(authParamsPublicKey),
       };
🤖 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_platform_interface/lib/src/auth/passkey_challenge.dart` around
lines 28 - 31, The toMap() serializer is returning the internal
authParamsPublicKey map by reference, exposing mutable state; update toMap() so
it returns a defensive copy of authParamsPublicKey (e.g., create a new Map from
authParamsPublicKey) instead of the original reference while still returning
authSession as before, ensuring callers cannot mutate the model's internal map
via the serialized output.
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt (1)

55-58: ⚡ Quick win

Simplify the Gson serialization.

The double serialization (object → JSON string → Map) is inefficient. Consider using Gson().toJsonTree(challenge.authParamsPublicKey).asJsonObject or a similar approach to convert directly to a Map structure without the intermediate JSON string step.

♻️ Proposed simplification
-                    val authParamsPublicKey: Map<*, *> = Gson().fromJson(
-                        Gson().toJson(challenge.authParamsPublicKey),
-                        Map::class.java
-                    )
+                    `@Suppress`("UNCHECKED_CAST")
+                    val authParamsPublicKey = Gson().toJsonTree(challenge.authParamsPublicKey).asJsonObject.asMap() as Map<*, *>
🤖 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/PasskeySignupChallengeApiRequestHandler.kt`
around lines 55 - 58, The double-serialization in
PasskeySignupChallengeApiRequestHandler (creating authParamsPublicKey by
Gson().toJson(...) then fromJson(..., Map::class.java)) is inefficient; replace
it with a direct conversion such as using
Gson().toJsonTree(challenge.authParamsPublicKey).asJsonObject (or
Gson().fromJson with a TypeToken<Map<String,Any>>() to get a Map) to avoid the
intermediate JSON string — update the authParamsPublicKey assignment in that
handler to use the direct JsonTree/TypeToken approach.
auth0_flutter/example/ios/Runner/PasskeyAuthenticator.swift (1)

117-139: ⚡ Quick win

Nil-coalescing to empty Data() may mask missing assertion fields.

If rawAuthenticatorData or signature is nil, substituting empty Data() will produce an invalid WebAuthn assertion that fails server-side validation with a confusing error. Consider returning a FlutterError for these unexpected nil cases instead.

Proposed approach
         if let credential = authorization.credential
                 as? ASAuthorizationPlatformPublicKeyCredentialAssertion {
             // Login assertion.
+            guard let rawAuthenticatorData = credential.rawAuthenticatorData,
+                  let signature = credential.signature else {
+                result(FlutterError(code: "invalid_assertion",
+                                    message: "Missing authenticatorData or signature",
+                                    details: nil))
+                cleanup()
+                return
+            }
             var response: [String: Any] = [
                 "clientDataJSON": Self.encodeBase64URL(credential.rawClientDataJSON),
-                "authenticatorData":
-                    Self.encodeBase64URL(credential.rawAuthenticatorData ?? Data()),
-                "signature": Self.encodeBase64URL(credential.signature ?? Data())
+                "authenticatorData": Self.encodeBase64URL(rawAuthenticatorData),
+                "signature": Self.encodeBase64URL(signature)
             ]
🤖 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/example/ios/Runner/PasskeyAuthenticator.swift` around lines 117
- 139, The code in PasskeyAuthenticator handling
ASAuthorizationPlatformPublicKeyCredentialAssertion currently nil-coalesces
rawAuthenticatorData and signature to Data(), which can produce invalid
assertions; instead validate that credential.rawAuthenticatorData and
credential.signature are non-nil (and credential.credentialID is present), and
if any are missing call result with a FlutterError (provide a clear code/message
and include which field is missing), then call cleanup() and return; only call
Self.encodeBase64URL on non-nil values and proceed to build the response when
all required fields are present.
auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart (1)

101-108: 💤 Low value

Consider conditionally including nullable fields for consistency.

PasskeyCredential.toMap() includes authenticatorAttachment and clientExtensionResults even when null, while PasskeyAuthenticatorResponse.toMap() uses conditional inclusion (if (field != null)). While both approaches work for JSON serialization, conditional inclusion produces cleaner output and is more consistent.

♻️ Use conditional inclusion for consistency
   Map<String, dynamic> toMap() => {
         'id': id,
         'rawId': rawId,
         'type': type,
-        'authenticatorAttachment': authenticatorAttachment,
+        if (authenticatorAttachment != null) 'authenticatorAttachment': authenticatorAttachment,
         'response': response.toMap(),
-        'clientExtensionResults': clientExtensionResults,
+        if (clientExtensionResults != null) 'clientExtensionResults': clientExtensionResults,
       };
🤖 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_platform_interface/lib/src/auth/passkey_credential.dart` around
lines 101 - 108, PasskeyCredential.toMap() currently always emits
authenticatorAttachment and clientExtensionResults even when null; update
PasskeyCredential.toMap() to mirror PasskeyAuthenticatorResponse.toMap() by
conditionally including 'authenticatorAttachment' and 'clientExtensionResults'
only when they are non-null (use inline if checks) so the serialized map is
cleaner and consistent with PasskeyAuthenticatorResponse.toMap().
auth0_flutter/example/lib/example_app.dart (1)

81-81: 💤 Low value

Use raw string literal for regex pattern.

RegExp('.') should be RegExp(r'.') to properly escape the dot metacharacter. While both work in this masking context (since you want to match any character), the raw string literal is more idiomatic and avoids potential confusion.

💡 Use raw string literal
-        output = result.idToken.replaceAll(RegExp('.'), '*');
+        output = result.idToken.replaceAll(RegExp(r'.'), '*');
🤖 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/example/lib/example_app.dart` at line 81, The regex pattern
used to mask the token uses RegExp('.') which is not an idiomatic raw string;
update the call that constructs the masked output (the line assigning to output
using result.idToken.replaceAll(RegExp('.'), '*')) to use a raw string literal
for the regex, i.e., RegExp(r'.'), so the dot metacharacter is expressed clearly
and unambiguously when creating the masked output from result.idToken.
auth0_flutter/example/lib/passkey_authenticator.dart (1)

44-45: ⚡ Quick win

Add error handling for platform response structure validation.

The Map.from() casts assume the platform always returns a well-formed response structure. If the native code returns unexpected data (e.g., response is not a Map), this will throw a cryptic TypeError instead of a clear error message.

🛡️ Add validation or wrap in try-catch
+    if (result['response'] is! Map) {
+      throw PlatformException(
+        code: 'invalid_response',
+        message: 'Platform returned malformed credential response.',
+      );
+    }
+
     final response = Map<String, dynamic>.from(
         result['response'] as Map<dynamic, dynamic>);

Or wrap the entire credential construction in a try-catch to provide a clearer error:

+    try {
       final response = Map<String, dynamic>.from(
           result['response'] as Map<dynamic, dynamic>);

       return PasskeyCredential(
         id: result['id'] as String,
         ...
       );
+    } catch (e) {
+      throw PlatformException(
+        code: 'invalid_response',
+        message: 'Failed to parse platform credential response: $e',
+      );
+    }

Also applies to: 88-89

🤖 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/example/lib/passkey_authenticator.dart` around lines 44 - 45,
The code assumes result['response'] is a Map and directly calls Map<String,
dynamic>.from(...), which will throw a cryptic TypeError for unexpected platform
responses; change the logic in the credential construction (the block that
assigns response from result['response'] and the similar code around lines
88-89) to first validate the type (e.g., check result['response'] is Map or
Map<dynamic,dynamic>) and then convert, or wrap the entire construction in a
try-catch that catches TypeError/Exception and throws a clear
PlatformException/FormatException with a descriptive message including the
unexpected value; ensure the thrown error identifies the offending key
("response") and includes the original value for easier debugging.
🤖 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/Auth0FlutterWebAuthMethodCallHandler.kt`:
- Around line 19-22: The call to requestHandler.handle uses activity!! which can
be null and crash; update Auth0FlutterWebAuthMethodCallHandler so before
creating the MethodCallRequest and calling requestHandler.handle(activity!!,
request, result) you check activity for null (e.g., if (activity == null) {
result.error("ACTIVITY_UNAVAILABLE", "Activity is null; plugin detached", null);
return }). Ensure you still check requestHandler != null and only call
MethodCallRequest.fromCall and requestHandler.handle(activity, request, result)
when activity is non-null, referencing the requestHandler,
MethodCallRequest.fromCall, handle, activity and result symbols to locate the
affected code.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt`:
- Around line 37-40: The code currently does unsafe casts in
PasskeyCredentialExchangeApiRequestHandler (assertHasProperties, authSession,
credentialMap); replace those casts with safe type checks: verify
args["challenge"] is a Map<*, *> and that its "authSession" entry is a String,
and verify args["credential"] is a Map<*, *> before extracting values; on
mismatch throw or return a clear IllegalArgumentException (or call the existing
error handling path) with a message referencing "challenge" or "credential" so
the Flutter caller receives a useful error instead of a ClassCastException.

In
`@auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift`:
- Around line 56-64: The Swift handler currently returns a minimal
authParamsPublicKey map (keys: challenge, rpId, userId, userName) which breaks
the cross-platform contract; update the PasskeySignupChallengeMethodHandler to
return the full authParamsPublicKey object exactly as Android does by
serializing challenge.authParamsPublicKey (or the full
PasskeyRegistrationChallenge) into a dictionary including nested fields like
user (id, name, displayName), relyingParty, authenticatorSelection,
pubKeyCredParams, timeout, etc., using the Auth0.swift model properties or
JSONEncoder-to-dictionary conversion so the resulting response dictionary
contains authSession and an authParamsPublicKey subtree matching Android's
shape.

In `@auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj`:
- Line 1115: The Debug build currently sets CODE_SIGN_STYLE = Manual without
setting DEVELOPMENT_TEAM or PROVISIONING_PROFILE_SPECIFIER, which prevents
device signing; either change the Debug configuration's CODE_SIGN_STYLE to
Automatic (so Xcode manages signing) or retain Manual but add placeholder values
and document that developers must set DEVELOPMENT_TEAM and
PROVISIONING_PROFILE_SPECIFIER locally; update the project.pbxproj Debug block
(look for CODE_SIGN_STYLE, DEVELOPMENT_TEAM, PROVISIONING_PROFILE_SPECIFIER
entries) and apply the chosen approach consistently (also mirror the same change
at the other occurrence noted).

In `@auth0_flutter/example/lib/example_app.dart`:
- Line 256: The dotenv.env['AUTH0_PASSKEY_CONNECTION'] value is nullable but is
passed directly to the connection parameter (at the occurrences around lines
256, 283, 356), so add an explicit null-check and fail-fast or provide a default
before calling the API: replace direct uses of
dotenv.env['AUTH0_PASSKEY_CONNECTION'] with a validated value (e.g., assign to a
local variable passkeyConnection = dotenv.env['AUTH0_PASSKEY_CONNECTION'] ??
throw StateError("AUTH0_PASSKEY_CONNECTION not set") or use a sensible default)
and then pass passkeyConnection into the connection parameter; update all three
occurrences (the calls that set connection:
dotenv.env['AUTH0_PASSKEY_CONNECTION']) to use the validated variable.

---

Outside diff comments:
In `@auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj`:
- Line 127: The project.pbxproj contains a duplicate PBXFileReference entry for
CredentialsManagerSSOCredentialsMethodHandlerTests.swift (GUID
A09B2E3F1D4C7891BA000001) which will break Xcode; remove the redundant
PBXFileReference block so only one entry with that GUID and path remains, and
then verify any references in PBXGroup or PBXSourcesBuildPhase (or similar
sections) point to the remaining GUID to avoid dangling or duplicated
references.
- Line 29: The project file contains a duplicate PBXBuildFile entry for
CredentialsManagerSSOCredentialsMethodHandlerTests.swift (object ID
A09B2E3F1D4C7891BA000002 with fileRef A09B2E3F1D4C7891BA000001) which must be
removed; locate the duplicate PBXBuildFile block (the second occurrence around
the other PBXBuildFile entries) and delete it so there is only one PBXBuildFile
entry for that source file, then scan build phases, PBXGroup and any other
references to ensure they point to the remaining object ID (or update them to
the kept ID) to avoid dangling or duplicate identifiers.

---

Nitpick comments:
In `@auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart`:
- Around line 28-31: The toMap() serializer is returning the internal
authParamsPublicKey map by reference, exposing mutable state; update toMap() so
it returns a defensive copy of authParamsPublicKey (e.g., create a new Map from
authParamsPublicKey) instead of the original reference while still returning
authSession as before, ensuring callers cannot mutate the model's internal map
via the serialized output.

In `@auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart`:
- Around line 101-108: PasskeyCredential.toMap() currently always emits
authenticatorAttachment and clientExtensionResults even when null; update
PasskeyCredential.toMap() to mirror PasskeyAuthenticatorResponse.toMap() by
conditionally including 'authenticatorAttachment' and 'clientExtensionResults'
only when they are non-null (use inline if checks) so the serialized map is
cleaner and consistent with PasskeyAuthenticatorResponse.toMap().

In
`@auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart`:
- Around line 1383-1661: The tests for the new passkey channels currently only
cover PlatformException paths but are missing the null-return failure-paths; add
unit tests that mock mocked.methodCallHandler to return null and assert that
MethodChannelAuth0FlutterAuth().passkeyLoginChallenge,
.passkeyCredentialExchange, and .passkeySignupChallenge each throw an
ApiException when the platform channel result is null, mirroring the existing
null-result tests for other API groups and using verify(captureAny) where
appropriate to locate the invoked method.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt`:
- Around line 55-58: The double-serialization in
PasskeySignupChallengeApiRequestHandler (creating authParamsPublicKey by
Gson().toJson(...) then fromJson(..., Map::class.java)) is inefficient; replace
it with a direct conversion such as using
Gson().toJsonTree(challenge.authParamsPublicKey).asJsonObject (or
Gson().fromJson with a TypeToken<Map<String,Any>>() to get a Map) to avoid the
intermediate JSON string — update the authParamsPublicKey assignment in that
handler to use the direct JsonTree/TypeToken approach.

In `@auth0_flutter/example/ios/Runner/PasskeyAuthenticator.swift`:
- Around line 117-139: The code in PasskeyAuthenticator handling
ASAuthorizationPlatformPublicKeyCredentialAssertion currently nil-coalesces
rawAuthenticatorData and signature to Data(), which can produce invalid
assertions; instead validate that credential.rawAuthenticatorData and
credential.signature are non-nil (and credential.credentialID is present), and
if any are missing call result with a FlutterError (provide a clear code/message
and include which field is missing), then call cleanup() and return; only call
Self.encodeBase64URL on non-nil values and proceed to build the response when
all required fields are present.

In `@auth0_flutter/example/lib/example_app.dart`:
- Line 81: The regex pattern used to mask the token uses RegExp('.') which is
not an idiomatic raw string; update the call that constructs the masked output
(the line assigning to output using result.idToken.replaceAll(RegExp('.'), '*'))
to use a raw string literal for the regex, i.e., RegExp(r'.'), so the dot
metacharacter is expressed clearly and unambiguously when creating the masked
output from result.idToken.

In `@auth0_flutter/example/lib/passkey_authenticator.dart`:
- Around line 44-45: The code assumes result['response'] is a Map and directly
calls Map<String, dynamic>.from(...), which will throw a cryptic TypeError for
unexpected platform responses; change the logic in the credential construction
(the block that assigns response from result['response'] and the similar code
around lines 88-89) to first validate the type (e.g., check result['response']
is Map or Map<dynamic,dynamic>) and then convert, or wrap the entire
construction in a try-catch that catches TypeError/Exception and throws a clear
PlatformException/FormatException with a descriptive message including the
unexpected value; ensure the thrown error identifies the offending key
("response") and includes the original value for easier debugging.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b084c441-c964-4dc6-be32-43049e8d9539

📥 Commits

Reviewing files that changed from the base of the PR and between 13af0ac and 8ed5dbf.

📒 Files selected for processing (65)
  • .github/workflows/main.yml
  • auth0_flutter/EXAMPLES.md
  • auth0_flutter/README.md
  • auth0_flutter/android/build.gradle
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterAuthMethodCallHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterPlugin.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterWebAuthMethodCallHandler.kt
  • 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/PasskeyCredentialExchangeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyLoginChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyLoginChallengeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandlerTest.kt
  • auth0_flutter/darwin/.gitignore
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/MethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter.podspec
  • auth0_flutter/example/android/app/build.gradle
  • auth0_flutter/example/android/app/src/main/kotlin/com/auth0/auth0_flutter_example/MainActivity.kt
  • auth0_flutter/example/android/app/src/main/kotlin/com/auth0/auth0_flutter_example/PasskeyAuthenticator.kt
  • auth0_flutter/example/android/gradle.properties
  • auth0_flutter/example/android/settings.gradle
  • auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj
  • auth0_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  • auth0_flutter/example/ios/Runner/AppDelegate.swift
  • auth0_flutter/example/ios/Runner/PasskeyAuthenticator.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIHandlerTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandlerTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyExtensionsTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandlerTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandlerTests.swift
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPISpies.swift
  • auth0_flutter/example/lib/example_app.dart
  • auth0_flutter/example/lib/passkey_authenticator.dart
  • auth0_flutter/ios/.gitignore
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift
  • auth0_flutter/ios/auth0_flutter.podspec
  • auth0_flutter/lib/auth0_flutter.dart
  • auth0_flutter/lib/src/mobile/authentication_api.dart
  • auth0_flutter/macos/.gitignore
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift
  • auth0_flutter/macos/auth0_flutter.podspec
  • auth0_flutter/test/mobile/authentication_api_test.dart
  • auth0_flutter/test/mobile/authentication_api_test.mocks.dart
  • auth0_flutter_platform_interface/lib/auth0_flutter_platform_interface.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_exchange_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_login_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_signup_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart
  • auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart
  • auth0_flutter_platform_interface/lib/src/auth0_flutter_auth_platform.dart
  • auth0_flutter_platform_interface/lib/src/method_channel_auth0_flutter_auth.dart
  • auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart
  • auth0_flutter_platform_interface/test/passkey_credential_test.dart

Comment thread auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj Outdated
Comment thread auth0_flutter/example/lib/example_app.dart Outdated

@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: 5

♻️ Duplicate comments (3)
auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift (1)

56-64: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Cross-platform contract: authParamsPublicKey structure mismatch persists.

The Swift implementation returns a minimal authParamsPublicKey with 4 fields (challenge, rpId, userId, userName), while the Android signup handler serializes the entire challenge.authParamsPublicKey object via Gson (including nested structures like user, authenticatorSelection, pubKeyCredParams, etc.). This inconsistency was flagged in previous review and remains unresolved.

If Dart/Flutter code accesses nested fields present in Android's response, it will fail on iOS/macOS.

🤖 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/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift`
around lines 56 - 64, The iOS/macOS handler
AuthAPIPasskeySignupChallengeMethodHandler currently builds authParamsPublicKey
manually with only four flat fields, causing a mismatch with Android's
serialized challenge.authParamsPublicKey; update the response to serialize and
return the full challenge.authParamsPublicKey structure (including nested keys
like user, authenticatorSelection, pubKeyCredParams, etc.) instead of the
minimal map — locate where authParamsPublicKey is constructed in the handler and
replace the manual dictionary with a serialization of
challenge.authParamsPublicKey (or build an equivalent nested dictionary matching
Android’s shape) so Dart/Flutter consumers receive the same schema.
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterWebAuthMethodCallHandler.kt (1)

22-22: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Null-pointer crash risk: activity!! without guard.

Line 22 force-unwraps activity, which is nullable and set to null during detachment. If a method call arrives while the plugin is detached (e.g., during configuration changes), this will throw KotlinNullPointerException.

Add a null check and return result.error(...) instead of crashing. As per coding guidelines, force-unwraps are not acceptable in MethodChannel handlers.

🛡️ Proposed fix
     override fun onMethodCall(`@NonNull` call: MethodCall, `@NonNull` result: Result) {
         val requestHandler = requestHandlers.find { it.method == call.method }

         if (requestHandler != null) {
+            val activity = this.activity
+            if (activity == null) {
+                result.error(
+                    "no_activity",
+                    "Web authentication requires an active Activity context",
+                    null
+                )
+                return
+            }
             val request = MethodCallRequest.fromCall(call)

-            requestHandler.handle(activity!!, request, result)
+            requestHandler.handle(activity, request, result)
         } else {
             result.notImplemented()
         }
     }
🤖 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/Auth0FlutterWebAuthMethodCallHandler.kt`
at line 22, The handler currently force-unwraps the plugin Activity with
activity!! in Auth0FlutterWebAuthMethodCallHandler when calling
requestHandler.handle, which can throw a KotlinNullPointerException if the
plugin is detached; change this to guard for null by checking activity (e.g., if
(activity == null) ...) and immediately call result.error with a clear error
code/message indicating the plugin is detached (do not throw), otherwise pass
the non-null activity to requestHandler.handle; update the MethodChannel handler
logic in Auth0FlutterWebAuthMethodCallHandler to use this null-check pattern
instead of the force-unwrap.

Source: Coding guidelines

auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt (1)

39-40: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Unsafe casts will cause ClassCastException crashes.

Lines 39-40 perform unsafe casts without type validation. If the Flutter side passes incorrect types (e.g., challenge as a String, or credential as a primitive), these will throw ClassCastException at runtime instead of returning a clear error to Flutter.

This is inconsistent with lines 45 and 47, which correctly use safe casts (as?). As per coding guidelines, avoid force-casts in MethodChannel handlers — ClassCastException from unsafe casts has caused crashes in the past.

🛡️ Proposed fix with safe casts
         assertHasProperties(listOf("challenge.authSession", "credential"), args)

-        val authSession = (args["challenge"] as Map<*, *>)["authSession"] as String
-        val credentialMap = args["credential"] as Map<*, *>
+        val challengeMap = args["challenge"] as? Map<*, *>
+            ?: run {
+                result.error("invalid_argument", "Property 'challenge' must be a Map", null)
+                return
+            }
+        val authSession = challengeMap["authSession"] as? String
+            ?: run {
+                result.error("invalid_argument", "Property 'challenge.authSession' must be a String", null)
+                return
+            }
+        val credentialMap = args["credential"] as? Map<*, *>
+            ?: run {
+                result.error("invalid_argument", "Property 'credential' must be a Map", null)
+                return
+            }
🤖 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/PasskeyCredentialExchangeApiRequestHandler.kt`
around lines 39 - 40, Replace the unsafe force-casts for authSession and
credentialMap with safe casts and null checks: use safe cast operators (as?)
when extracting (args["challenge"] as? Map<*, *>)?["authSession"] as? String and
args["credential"] as? Map<*, *>, validate they are non-null, and if either is
null return a clear error to the Flutter side instead of allowing a
ClassCastException; update the PasskeyCredentialExchangeApiRequestHandler (the
variables authSession and credentialMap and any downstream usages) to use the
safely-cast values or early-return an error.

Source: Coding guidelines

🤖 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_platform_interface/lib/src/auth/passkey_challenge.dart`:
- Around line 21-26: PasskeyChallenge.fromMap currently does unchecked `as`
casts for authSession and authParamsPublicKey which can throw on malformed
input; update this factory to validate types first (use `is String` for
result['authSession'] and `is Map` for result['authParamsPublicKey']),
convert/cast safely (e.g., Map<String,dynamic>.from only after confirming a
Map), and throw a clear ArgumentError or return a well-documented fallback if
validation fails; locate the PasskeyChallenge.fromMap constructor and add these
guards around access to authSession and authParamsPublicKey.

In `@auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart`:
- Around line 32-40: PasskeyAuthenticatorResponse.fromMap and
PasskeyCredential.fromMap currently perform unchecked `as` casts from a dynamic
map which can raise runtime TypeError if fields are missing or wrong-typed;
update both factory methods to validate types using `is` checks (e.g., ensure
map['clientDataJSON'] is String, map['id']/'rawId' is String, map['response'] is
Map or expected shape) and validate optional fields with `== null || value is
String` (or appropriate types) before casting, and throw a clear ArgumentError
with a descriptive message when required fields are absent or of the wrong type
so callers get explicit errors instead of uncaught TypeError.

In
`@auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandlerTest.kt`:
- Around line 103-109: Replace the JVM assert(...) and unsafe casts in
PasskeySignupChallengeApiRequestHandlerTest with Hamcrest assertions and safe
nullable casts: capture the success map via the existing captor and use
assertThat(resultMap["authSession"], equalTo("test-auth-session")); cast
authParamsPublicKey with as? to a Map and assertThat(publicKey, notNullValue())
before checking its "challenge" with assertThat(publicKey?.get("challenge"),
equalTo("test-challenge")); similarly cast the "user" entry with as? Map,
assertThat(user, notNullValue()), then assertThat(user?.get("name"),
equalTo("test-user-name")). Ensure you reference the existing captor, resultMap,
publicKey and user variables and Hamcrest matchers already used in the repo.

In
`@auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift`:
- Around line 15-22: Replaced implicitly unwrapped optionals in
ReconstructedLoginPasskey (userID, rawAuthenticatorData, signature) with regular
optionals (Data?) and remove force-unwraps in the MethodChannel handler; update
the reconstruction logic (the function that creates ReconstructedLoginPasskey
around lines 148-180) to explicitly unwrap those optionals with guard let (or
return a clear error) before using them so no `!` is used in the handler flow
and the handler returns nil or a descriptive error if any required field is
missing.

In `@auth0_flutter/test/mobile/authentication_api_test.dart`:
- Line 451: The long inline casts like "verify(...).captured.single as
ApiRequest<AuthPasskeyLoginChallengeOptions>" exceed 80 chars; fix by extracting
the complex generic type into a shorter typedef (e.g., alias
ApiRequest<AuthPasskeyLoginChallengeOptions> to a short name) or by splitting
the expression across lines (assign verify(...).captured.single to a local var
and then cast on the next line) for each occurrence (the capture/cast lines at
or near verify(...).captured.single as
ApiRequest<AuthPasskeyLoginChallengeOptions> and the similar casts for other
AuthPasskey*Options in the test file) so each line stays ≤80 chars while keeping
the same runtime behavior.

---

Duplicate comments:
In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterWebAuthMethodCallHandler.kt`:
- Line 22: The handler currently force-unwraps the plugin Activity with
activity!! in Auth0FlutterWebAuthMethodCallHandler when calling
requestHandler.handle, which can throw a KotlinNullPointerException if the
plugin is detached; change this to guard for null by checking activity (e.g., if
(activity == null) ...) and immediately call result.error with a clear error
code/message indicating the plugin is detached (do not throw), otherwise pass
the non-null activity to requestHandler.handle; update the MethodChannel handler
logic in Auth0FlutterWebAuthMethodCallHandler to use this null-check pattern
instead of the force-unwrap.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt`:
- Around line 39-40: Replace the unsafe force-casts for authSession and
credentialMap with safe casts and null checks: use safe cast operators (as?)
when extracting (args["challenge"] as? Map<*, *>)?["authSession"] as? String and
args["credential"] as? Map<*, *>, validate they are non-null, and if either is
null return a clear error to the Flutter side instead of allowing a
ClassCastException; update the PasskeyCredentialExchangeApiRequestHandler (the
variables authSession and credentialMap and any downstream usages) to use the
safely-cast values or early-return an error.

In
`@auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift`:
- Around line 56-64: The iOS/macOS handler
AuthAPIPasskeySignupChallengeMethodHandler currently builds authParamsPublicKey
manually with only four flat fields, causing a mismatch with Android's
serialized challenge.authParamsPublicKey; update the response to serialize and
return the full challenge.authParamsPublicKey structure (including nested keys
like user, authenticatorSelection, pubKeyCredParams, etc.) instead of the
minimal map — locate where authParamsPublicKey is constructed in the handler and
replace the manual dictionary with a serialization of
challenge.authParamsPublicKey (or build an equivalent nested dictionary matching
Android’s shape) so Dart/Flutter consumers receive the same schema.
🪄 Autofix (Beta)

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: 35bf48bb-d755-459b-8fde-7a60782d6644

📥 Commits

Reviewing files that changed from the base of the PR and between 8ed5dbf and 14de0ce.

⛔ Files ignored due to path filters (26)
  • auth0_flutter/example/android/app/build.gradle is excluded by !**/example/**
  • auth0_flutter/example/android/app/src/main/kotlin/com/auth0/auth0_flutter_example/MainActivity.kt is excluded by !**/example/**
  • auth0_flutter/example/android/app/src/main/kotlin/com/auth0/auth0_flutter_example/PasskeyAuthenticator.kt is excluded by !**/example/**
  • auth0_flutter/example/android/gradle.properties is excluded by !**/example/**
  • auth0_flutter/example/android/settings.gradle is excluded by !**/example/**
  • auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj is excluded by !**/example/**
  • auth0_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme is excluded by !**/example/**
  • auth0_flutter/example/ios/Runner/AppDelegate.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Runner/PasskeyAuthenticator.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyExtensionsTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPISpies.swift is excluded by !**/example/**
  • auth0_flutter/example/lib/example_app.dart is excluded by !**/example/**
  • auth0_flutter/example/lib/passkey_authenticator.dart is excluded by !**/example/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/test/mobile/authentication_api_test.mocks.dart is excluded by !**/*.mocks.dart
📒 Files selected for processing (39)
  • .github/workflows/main.yml
  • auth0_flutter/EXAMPLES.md
  • auth0_flutter/README.md
  • auth0_flutter/android/build.gradle
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterAuthMethodCallHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterPlugin.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterWebAuthMethodCallHandler.kt
  • 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/PasskeyCredentialExchangeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyLoginChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyLoginChallengeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandlerTest.kt
  • auth0_flutter/darwin/.gitignore
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/MethodHandler.swift
  • auth0_flutter/darwin/auth0_flutter.podspec
  • auth0_flutter/ios/.gitignore
  • auth0_flutter/ios/auth0_flutter.podspec
  • auth0_flutter/lib/auth0_flutter.dart
  • auth0_flutter/lib/src/mobile/authentication_api.dart
  • auth0_flutter/macos/.gitignore
  • auth0_flutter/macos/auth0_flutter.podspec
  • auth0_flutter/test/mobile/authentication_api_test.dart
  • auth0_flutter_platform_interface/lib/auth0_flutter_platform_interface.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_exchange_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_login_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_signup_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart
  • auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart
  • auth0_flutter_platform_interface/lib/src/auth0_flutter_auth_platform.dart
  • auth0_flutter_platform_interface/lib/src/method_channel_auth0_flutter_auth.dart
  • auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart
  • auth0_flutter_platform_interface/test/passkey_credential_test.dart

Comment thread auth0_flutter/test/mobile/authentication_api_test.dart
@NandanPrabhu NandanPrabhu changed the title feat: Adds native passkeys APIs support for login and support feat: Adds passkeys support to flutter SDK Jun 11, 2026

@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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/MyAccountExtensions.kt (1)

17-67: 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Potential confusion between extension functions.

toMyAccountMethodMap() (line 17) and toMyAccountPasskeyMethodMap() (line 50) are separate extension functions on different types. The existing toMyAccountMethodMap() has no branch for passkey types, which could cause confusion if callers aren't aware they need to use the passkey-specific extension.

Document the intended usage pattern or consider whether these extensions should be unified if the types share a common base.

🤖 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/MyAccountExtensions.kt`
around lines 17 - 67, The two extension functions toMyAccountMethodMap (on
AuthenticationMethod) and toMyAccountPasskeyMethodMap (on
PasskeyAuthenticationMethod) can be confusing because callers might expect
passkeys to be handled by toMyAccountMethodMap; update toMyAccountMethodMap to
include a branch for PasskeyAuthenticationMethod that delegates to
toMyAccountPasskeyMethodMap (or consolidate both into a single extension if
PasskeyAuthenticationMethod shares a common base), and add a short comment
documenting the intended usage; reference the functions toMyAccountMethodMap,
toMyAccountPasskeyMethodMap and the type PasskeyAuthenticationMethod when making
the change.
auth0_flutter_platform_interface/test/method_channel_auth0_flutter_my_account_test.dart (1)

76-313: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Multiple line length violations exceed 80 characters.

Lines 222, 246, and several others violate the Dart guideline. Break long parameter lists and test descriptions across multiple lines.

Example violations:

  • Line 222: Long parameter list in MyAccountConfirmEnrollmentOptions
  • Line 246: Test description exceeds limit
  • Line 263: Long parameter list in MyAccountEnrollPasskeyChallengeOptions
🤖 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_platform_interface/test/method_channel_auth0_flutter_my_account_test.dart`
around lines 76 - 313, Several tests contain lines longer than 80 characters;
split long test descriptions and multi-argument constructors across multiple
lines (use one argument per line and add trailing commas to enable formatter) so
they conform to line-length rules. Specifically update the long parameter lists
in MyAccountConfirmEnrollmentOptions and MyAccountEnrollPasskeyChallengeOptions
within the confirmEnrollment and enrollPasskeyChallenge tests, and break long
test description strings (e.g., the test at the long description near
enrollPasskey) into shorter strings or wrap the test call across lines; apply
the same wrapping pattern to other offending tests (updateAuthenticationMethod,
enrollPasskey) and run dart format to ensure all lines are under 80 chars.

Source: Coding guidelines

♻️ Duplicate comments (1)
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt (1)

37-40: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Use safe casts to prevent ClassCastException.

Lines 39-40 perform unsafe casts that will throw ClassCastException if Flutter passes incorrect types. Per coding guidelines, ClassCastException from unsafe casts in MethodChannel handlers has caused crashes in the past and must be treated as a bug.

Use safe casts with explicit validation:

🛡️ Proposed fix with safe casts
         assertHasProperties(listOf("challenge.authSession", "credential"), args)

-        val authSession = (args["challenge"] as Map<*, *>)["authSession"] as String
-        val credentialMap = args["credential"] as Map<*, *>
+        val challengeMap = args["challenge"] as? Map<*, *>
+            ?: throw IllegalArgumentException("Property 'challenge' must be a Map")
+        val authSession = challengeMap["authSession"] as? String
+            ?: throw IllegalArgumentException("Property 'challenge.authSession' must be a String")
+        val credentialMap = args["credential"] as? Map<*, *>
+            ?: throw IllegalArgumentException("Property 'credential' must be a Map")
🤖 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/PasskeyCredentialExchangeApiRequestHandler.kt`
around lines 37 - 40, The code currently does unsafe casts for authSession and
credentialMap which can throw ClassCastException; replace them with safe casts
and explicit null/type checks: retrieve challenge as (args["challenge"] as?
Map<*, *>) and then authSession as (challenge["authSession"] as? String) and
credentialMap as (args["credential"] as? Map<*, *>), validate that these are
non-null and of the expected types, and if validation fails throw or return a
clear argument error (consistent with other MethodChannel handlers) rather than
allowing a ClassCastException; update the code in
PasskeyCredentialExchangeApiRequestHandler (where assertHasProperties,
authSession and credentialMap are used) accordingly.

Source: Coding guidelines

🤖 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_platform_interface/lib/src/myaccount/my_account_enroll_passkey_challenge_options.dart`:
- Around line 8-12: The constructor parameters of
MyAccountEnrollPasskeyChallengeOptions should be marked final: update the class
fields and the MyAccountEnrollPasskeyChallengeOptions constructor to declare
accessToken, userIdentityId, and connection as final (replace any non-final
declarations with final) so the properties are immutable and follow Dart
guidelines; ensure the class members corresponding to these constructor
parameters are final as well.

In
`@auth0_flutter_platform_interface/lib/src/myaccount/my_account_passkey_authentication_method.dart`:
- Around line 85-87: The createdAt parsing currently uses
result['created_at'].toString() which hides type issues; update the code in
my_account_passkey_authentication_method (the createdAt assignment) to cast
explicitly and safely: check if result['created_at'] is a String (or int/num if
you expect epoch) and then call DateTime.parse on that String (or
DateTime.fromMillisecondsSinceEpoch for epoch), otherwise keep null or handle
the type mismatch explicitly so a non-String value fails visibly instead of
being silently stringified.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/MyAccountExtensions.kt`:
- Around line 72-75: The code is doing an unnecessary and fragile
double-serialization when building authParamsPublicKey: replace the
Gson().toJson(...)/fromJson(...) round-trip by directly converting or casting
the SDK value to a typed map (e.g. attempt a safe cast like authParamsPublicKey
as? Map<String, Any> or, if it is a JSON element, use
Gson().fromJson(jsonElement, object : TypeToken<Map<String,Any>>() {}.type) to
preserve types), and change the target type from Map<*, *> to a more specific
Map<String, Any> (or an appropriate concrete type) so callers and Kotlin's type
system get safer types; update usages of authParamsPublicKey accordingly and add
a short comment describing why a cast/typed conversion is used if the SDK
already returns a typed object.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyRequestHandler.kt`:
- Around line 108-109: In EnrollPasskeyRequestHandler where PublicKeyCredentials
is constructed, replace the unsafe casts (credentialMap["id"] as String,
credentialMap["rawId"] as String, response["attestationObject"] as String,
response["clientDataJSON"] as String) with safe casts (e.g., using the Kotlin
safe cast operator as? String) and if any required field is null or the wrong
type, return null (or propagate a clear error) from the enclosing method;
validate each value (id, rawId, attestationObject, clientDataJSON) after safe
casting before creating the PublicKeyCredentials instance so you avoid
ClassCastException on bad input.
- Line 95: Replace the unsafe cast "val response = credentialMap[\"response\"]
as Map<*, *>" in the reconstructCredentials function with a safe cast (as?) and
handle the null case by returning null; specifically, change how you read from
credentialMap (variable response) to use "as? Map<*, *>" and if that yields
null, return null from reconstructCredentials (the caller already checks for
null), avoiding throwing a ClassCastException and providing explicit error
handling.
- Around line 47-48: Replace the unsafe casts in EnrollPasskeyRequestHandler
(the lines obtaining request.data["challenge"] and request.data["credential"])
with safe casts (use as? Map<*, *>) and explicit null/type checks: verify each
cast result is non-null and contains expected key types before proceeding, and
handle failures by returning an appropriate error via the MethodChannel
request/result path (or early-return) instead of allowing a ClassCastException
to propagate; update any downstream code that assumes non-null maps to use the
validated variables.
- Around line 86-87: In EnrollPasskeyRequestHandler, replace the unsafe casts
challengeMap["authenticationMethodId"] as String and challengeMap["authSession"]
as String with safe casts (as?) and explicit null/type checks; if either cast
yields null, return or throw a clear error (e.g., invoke the existing
result/error callback) rather than letting a ClassCastException propagate.
Locate the code in the handler method reading challengeMap, change to safe
casts, validate the values' presence and types, and provide a descriptive error
path when validation fails.

---

Outside diff comments:
In
`@auth0_flutter_platform_interface/test/method_channel_auth0_flutter_my_account_test.dart`:
- Around line 76-313: Several tests contain lines longer than 80 characters;
split long test descriptions and multi-argument constructors across multiple
lines (use one argument per line and add trailing commas to enable formatter) so
they conform to line-length rules. Specifically update the long parameter lists
in MyAccountConfirmEnrollmentOptions and MyAccountEnrollPasskeyChallengeOptions
within the confirmEnrollment and enrollPasskeyChallenge tests, and break long
test description strings (e.g., the test at the long description near
enrollPasskey) into shorter strings or wrap the test call across lines; apply
the same wrapping pattern to other offending tests (updateAuthenticationMethod,
enrollPasskey) and run dart format to ensure all lines are under 80 chars.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/MyAccountExtensions.kt`:
- Around line 17-67: The two extension functions toMyAccountMethodMap (on
AuthenticationMethod) and toMyAccountPasskeyMethodMap (on
PasskeyAuthenticationMethod) can be confusing because callers might expect
passkeys to be handled by toMyAccountMethodMap; update toMyAccountMethodMap to
include a branch for PasskeyAuthenticationMethod that delegates to
toMyAccountPasskeyMethodMap (or consolidate both into a single extension if
PasskeyAuthenticationMethod shares a common base), and add a short comment
documenting the intended usage; reference the functions toMyAccountMethodMap,
toMyAccountPasskeyMethodMap and the type PasskeyAuthenticationMethod when making
the change.

---

Duplicate comments:
In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt`:
- Around line 37-40: The code currently does unsafe casts for authSession and
credentialMap which can throw ClassCastException; replace them with safe casts
and explicit null/type checks: retrieve challenge as (args["challenge"] as?
Map<*, *>) and then authSession as (challenge["authSession"] as? String) and
credentialMap as (args["credential"] as? Map<*, *>), validate that these are
non-null and of the expected types, and if validation fails throw or return a
clear argument error (consistent with other MethodChannel handlers) rather than
allowing a ClassCastException; update the code in
PasskeyCredentialExchangeApiRequestHandler (where assertHasProperties,
authSession and credentialMap are used) accordingly.
🪄 Autofix (Beta)

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: 2e72c4c2-d786-4781-b5b0-e0f597f5d44f

📥 Commits

Reviewing files that changed from the base of the PR and between 14de0ce and d1b7bc5.

⛔ Files ignored due to path filters (11)
  • auth0_flutter/example/android/app/src/main/kotlin/com/auth0/auth0_flutter_example/MainActivity.kt is excluded by !**/example/**
  • auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/MyAccount/MyAccountEnrollPasskeyChallengeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/MyAccount/MyAccountEnrollPasskeyMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/MyAccount/MyAccountSpies.swift is excluded by !**/example/**
  • auth0_flutter/example/lib/example_app.dart is excluded by !**/example/**
  • auth0_flutter/ios/Classes/MyAccountAPI/MyAccountEnrollPasskeyChallengeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/MyAccountAPI/MyAccountEnrollPasskeyMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/macos/Classes/MyAccountAPI/MyAccountEnrollPasskeyChallengeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/MyAccountAPI/MyAccountEnrollPasskeyMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/test/mobile/authentication_api_test.mocks.dart is excluded by !**/*.mocks.dart
📒 Files selected for processing (24)
  • auth0_flutter/EXAMPLES.md
  • auth0_flutter/README.md
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterPlugin.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/MyAccountExtensions.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyChallengeRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyRequestHandler.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyChallengeRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyRequestHandlerTest.kt
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountEnrollPasskeyChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountEnrollPasskeyMethodHandler.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountExtensions.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountHandler.swift
  • auth0_flutter/lib/auth0_flutter.dart
  • auth0_flutter/lib/src/mobile/my_account_api.dart
  • auth0_flutter_platform_interface/lib/auth0_flutter_platform_interface.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/auth0_flutter_my_account_platform.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/method_channel_auth0_flutter_my_account.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_enroll_passkey_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_enroll_passkey_options.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_passkey_authentication_method.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_passkey_enrollment_challenge.dart
  • auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart
  • auth0_flutter_platform_interface/test/method_channel_auth0_flutter_my_account_test.dart

Comment thread .github/workflows/main.yml
Comment thread auth0_flutter/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme Outdated
@sanchitmehtagit sanchitmehtagit dismissed their stale review June 12, 2026 06:43

Changes have been addressed

Comment thread auth0_flutter/example/android/app/build.gradle Outdated
@NandanPrabhu

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 4

♻️ Duplicate comments (4)
auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart (1)

21-26: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Past comment marked as addressed, but unsafe casts remain.

The previous review flagged unchecked as casts at lines 23 and 24-25, which can throw at runtime if the native platform returns malformed data. You confirmed this was addressed, but the current code still performs direct casts without is checks or guards. Per Dart coding guidelines, use is checks before casting.

🛡️ Recommended fix with type guards
 factory PasskeyChallenge.fromMap(final Map<dynamic, dynamic> result) {
+  final authSession = result['authSession'];
+  if (authSession is! String) {
+    throw ArgumentError('authSession must be a String');
+  }
+  final authParamsPublicKey = result['authParamsPublicKey'];
+  if (authParamsPublicKey is! Map) {
+    throw ArgumentError('authParamsPublicKey must be a Map');
+  }
   return PasskeyChallenge(
-    authSession: result['authSession'] as String,
-    authParamsPublicKey: Map<String, dynamic>.from(
-        result['authParamsPublicKey'] as Map<dynamic, dynamic>),
+    authSession: authSession,
+    authParamsPublicKey: Map<String, dynamic>.from(authParamsPublicKey),
   );
+ }
🤖 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_platform_interface/lib/src/auth/passkey_challenge.dart` around
lines 21 - 26, PasskeyChallenge.fromMap uses unchecked casts for authSession and
authParamsPublicKey that can throw; update the factory to validate types before
casting: check result['authSession'] is String and result['authParamsPublicKey']
is Map (or Map<dynamic,dynamic>), only then convert authParamsPublicKey with
Map<String, dynamic>.from, and otherwise throw an ArgumentError or return a
clear failure. Locate and update the PasskeyChallenge.fromMap factory and the
authSession/authParamsPublicKey extraction to use these type guards.

Source: Coding guidelines

auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt (1)

56-58: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reuse a single Gson instance instead of creating two per call.

Gson is thread-safe after construction. Creating two instances per invocation just to serialize then deserialize is inefficient. Define private val gson = Gson() at class level and reuse it.

🤖 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/PasskeySignupChallengeApiRequestHandler.kt`
around lines 56 - 58, PasskeySignupChallengeApiRequestHandler currently
constructs two Gson instances when converting challenge.authParamsPublicKey;
create a single reusable instance by adding a private val gson = Gson() at the
class level and replace both occurrences of Gson() in the authParamsPublicKey
conversion with this gson instance so the code uses gson.toJson(...) and
gson.fromJson(..., Map::class.java) instead of creating new Gson objects per
call.
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandlerTest.kt (1)

106-109: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace JVM assert(...) and unsafe casts with Hamcrest assertions and safe casts.

Lines 106-109 use Kotlin JVM assert(...) (which can be disabled at runtime) and unsafe as Map<*, *> casts that can throw ClassCastException. Switch to Hamcrest assertThat with equalTo and notNullValue, and use safe as? casts with null checks.

🤖 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/PasskeySignupChallengeApiRequestHandlerTest.kt`
around lines 106 - 109, In PasskeySignupChallengeApiRequestHandlerTest replace
JVM assert(...) and unsafe casts: use Hamcrest assertThat with
equalTo/notNullValue instead of assert, and change unsafe casts like
resultMap["authParamsPublicKey"] as Map<*, *> to safe casts (as?) with null
checks; e.g. retrieve publicKey = resultMap["authParamsPublicKey"] as? Map<*, *>
and assertThat(publicKey, notNullValue()), then
assertThat(publicKey?.get("challenge"), equalTo("test-challenge")) and for the
nested user use safe cast user = publicKey?.get("user") as? Map<*, *> and
assertThat(user?.get("name"), equalTo("test-user-name")). Ensure references to
resultMap, publicKey, user and the test class
PasskeySignupChallengeApiRequestHandlerTest are updated accordingly.
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt (1)

39-41: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Unsafe casts can throw ClassCastException instead of clear error.

Lines 39-41 perform unsafe casts (as Map<*, *>, as String) without type validation. While assertHasProperties checks presence, it does not validate types. If Flutter passes incorrect types (e.g., challenge as String), these casts throw ClassCastException at runtime instead of a clear error message. Per coding guidelines, this has caused crashes in the past and must be treated as a bug.

Replace with safe casts and explicit error handling.

🛡️ Proposed fix with safe casts
         assertHasProperties(listOf("challenge.authSession", "credential"), args)

-        val challenge = args["challenge"] as Map<*, *>
-        val authSession = challenge["authSession"] as String
-        val credentialMap = args["credential"] as Map<*, *>
+        val challenge = args["challenge"] as? Map<*, *>
+            ?: return result.error(
+                "INVALID_PARAMETERS",
+                "Property 'challenge' must be a Map",
+                null
+            )
+        val authSession = challenge["authSession"] as? String
+            ?: return result.error(
+                "INVALID_PARAMETERS",
+                "Property 'challenge.authSession' must be a String",
+                null
+            )
+        val credentialMap = args["credential"] as? Map<*, *>
+            ?: return result.error(
+                "INVALID_PARAMETERS",
+                "Property 'credential' must be a Map",
+                null
+            )
🤖 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/PasskeyCredentialExchangeApiRequestHandler.kt`
around lines 39 - 41, The code in PasskeyCredentialExchangeApiRequestHandler
uses unsafe casts for challenge, authSession, and credentialMap which can throw
ClassCastException; replace these with safe casts (using as?) and explicit
null/type checks: safely cast args["challenge"] to Map<*, *> and
args["credential"] to Map<*, *> and challenge["authSession"] to String, then if
any are null or wrong type raise/return a clear IllegalArgumentException or a
method-specific error with a descriptive message (e.g., "expected 'challenge' to
be Map, got X" / "expected 'authSession' to be String") instead of letting a
ClassCastException bubble up; keep existing assertHasProperties but add these
runtime type checks before using the variables.

Source: Coding guidelines

🤖 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_platform_interface/lib/src/auth/passkey_challenge.dart`:
- Around line 21-26: Replace unsafe unchecked `as` casts in
PasskeyChallenge.fromMap, PasskeyAuthenticatorResponse.fromMap, and
PasskeyCredential.fromMap with explicit runtime type guards: check each required
field with `is` (e.g., verify `result['authSession'] is String`,
`result['clientDataJSON'] is String`, `result['id'] is String`, `result['rawId']
is String`, `result['response'] is Map`, etc.), and for optional fields check
for `null` or the expected type; when a check fails throw an ArgumentError with
a clear message naming the factory (e.g., PasskeyChallenge.fromMap) and the
missing/wrong-typed field; for Map conversions use `is Map` then cast via
Map<String, dynamic>.from after the guard to avoid TypeError at runtime.

In
`@auth0_flutter_platform_interface/lib/src/myaccount/my_account_passkey_enrollment_challenge.dart`:
- Around line 26-33: The PasskeyEnrollmentChallenge.fromMap factory currently
uses unchecked `as` casts that will throw if keys are missing or of the wrong
type; update the factory (PasskeyEnrollmentChallenge.fromMap) to validate that
result['authenticationMethodId'] and result['authSession'] are non-null Strings
(using `is String`) and that result['authParamsPublicKey'] is a Map before
calling Map<String, dynamic>.from, and if any check fails throw a clear
ArgumentError or return a sensible default; reference the fields
authenticationMethodId, authSession, and authParamsPublicKey when performing
these guards so invalid input is detected early and safely.

In `@auth0_flutter/android/build.gradle`:
- Line 77: The build is forcing gson 2.10.1 while com.auth0.android:auth0:3.18.0
brings gson 2.8.9 transitively; decide and make the override explicit: either
exclude Gson from Auth0 (use dependency exclusion on artifact
com.auth0.android:auth0) and keep implementation
'com.google.code.gson:gson:2.10.1', or remove the explicit 2.10.1 and align to
Auth0’s transitive version, and add a comment documenting the chosen resolved
gson version to avoid surprises; locate the gson declaration and the auth0
dependency in android/build.gradle (look for implementation
'com.google.code.gson:gson:2.10.1' and com.auth0.android:auth0:3.18.0) and apply
the exclusion or version alignment accordingly.

In `@auth0_flutter/lib/src/mobile/my_account_api.dart`:
- Around line 104-134: The doc comment for enrollPasskeyChallenge has lines
exceeding the 80-character limit; reflow the long sentences so each line is <=80
characters while preserving wording and sentence breaks. Update the comment
above the Future<PasskeyEnrollmentChallenge> enrollPasskeyChallenge(...) (the
block describing usage, parameters, and required scopes) so all lines wrap to
~80 chars, leaving the method signature and call to
Auth0FlutterMyAccountPlatform.instance.enrollPasskeyChallenge(_createApiRequest(MyAccountEnrollPasskeyChallengeOptions(accessToken:
_accessToken, userIdentityId: userIdentityId, connection: connection)))
unchanged.

---

Duplicate comments:
In `@auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart`:
- Around line 21-26: PasskeyChallenge.fromMap uses unchecked casts for
authSession and authParamsPublicKey that can throw; update the factory to
validate types before casting: check result['authSession'] is String and
result['authParamsPublicKey'] is Map (or Map<dynamic,dynamic>), only then
convert authParamsPublicKey with Map<String, dynamic>.from, and otherwise throw
an ArgumentError or return a clear failure. Locate and update the
PasskeyChallenge.fromMap factory and the authSession/authParamsPublicKey
extraction to use these type guards.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt`:
- Around line 39-41: The code in PasskeyCredentialExchangeApiRequestHandler uses
unsafe casts for challenge, authSession, and credentialMap which can throw
ClassCastException; replace these with safe casts (using as?) and explicit
null/type checks: safely cast args["challenge"] to Map<*, *> and
args["credential"] to Map<*, *> and challenge["authSession"] to String, then if
any are null or wrong type raise/return a clear IllegalArgumentException or a
method-specific error with a descriptive message (e.g., "expected 'challenge' to
be Map, got X" / "expected 'authSession' to be String") instead of letting a
ClassCastException bubble up; keep existing assertHasProperties but add these
runtime type checks before using the variables.

In
`@auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt`:
- Around line 56-58: PasskeySignupChallengeApiRequestHandler currently
constructs two Gson instances when converting challenge.authParamsPublicKey;
create a single reusable instance by adding a private val gson = Gson() at the
class level and replace both occurrences of Gson() in the authParamsPublicKey
conversion with this gson instance so the code uses gson.toJson(...) and
gson.fromJson(..., Map::class.java) instead of creating new Gson objects per
call.

In
`@auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandlerTest.kt`:
- Around line 106-109: In PasskeySignupChallengeApiRequestHandlerTest replace
JVM assert(...) and unsafe casts: use Hamcrest assertThat with
equalTo/notNullValue instead of assert, and change unsafe casts like
resultMap["authParamsPublicKey"] as Map<*, *> to safe casts (as?) with null
checks; e.g. retrieve publicKey = resultMap["authParamsPublicKey"] as? Map<*, *>
and assertThat(publicKey, notNullValue()), then
assertThat(publicKey?.get("challenge"), equalTo("test-challenge")) and for the
nested user use safe cast user = publicKey?.get("user") as? Map<*, *> and
assertThat(user?.get("name"), equalTo("test-user-name")). Ensure references to
resultMap, publicKey, user and the test class
PasskeySignupChallengeApiRequestHandlerTest are updated accordingly.
🪄 Autofix (Beta)

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: 8183a5f9-7b87-4cf1-a04d-d6966fdb6c25

📥 Commits

Reviewing files that changed from the base of the PR and between 004e270 and cc3b73d.

⛔ Files ignored due to path filters (26)
  • auth0_flutter/example/android/app/build.gradle is excluded by !**/example/**
  • auth0_flutter/example/android/app/src/main/kotlin/com/auth0/auth0_flutter_example/MainActivity.kt is excluded by !**/example/**
  • auth0_flutter/example/ios/Runner.xcodeproj/project.pbxproj is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyExtensionsTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/AuthAPI/AuthAPISpies.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/MyAccount/MyAccountEnrollPasskeyChallengeMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/MyAccount/MyAccountEnrollPasskeyMethodHandlerTests.swift is excluded by !**/example/**
  • auth0_flutter/example/ios/Tests/MyAccount/MyAccountSpies.swift is excluded by !**/example/**
  • auth0_flutter/example/lib/example_app.dart is excluded by !**/example/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/MyAccountAPI/MyAccountEnrollPasskeyChallengeMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/ios/Classes/MyAccountAPI/MyAccountEnrollPasskeyMethodHandler.swift is excluded by !auth0_flutter/ios/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/MyAccountAPI/MyAccountEnrollPasskeyChallengeMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/macos/Classes/MyAccountAPI/MyAccountEnrollPasskeyMethodHandler.swift is excluded by !auth0_flutter/macos/Classes/**
  • auth0_flutter/test/mobile/authentication_api_test.mocks.dart is excluded by !**/*.mocks.dart
📒 Files selected for processing (53)
  • .github/workflows/main.yml
  • auth0_flutter/EXAMPLES.md
  • auth0_flutter/README.md
  • auth0_flutter/android/build.gradle
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterAuthMethodCallHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterPlugin.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterWebAuthMethodCallHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/CredentialsManagerMethodCallHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/MyAccountExtensions.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyLoginChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyChallengeRequestHandler.kt
  • auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyRequestHandler.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyCredentialExchangeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeyLoginChallengeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/PasskeySignupChallengeApiRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyChallengeRequestHandlerTest.kt
  • auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/my_account/EnrollPasskeyRequestHandlerTest.kt
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyCredentialExchangeMethodHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyExtensions.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeyLoginChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/AuthAPI/AuthAPIPasskeySignupChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/MethodHandler.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountEnrollPasskeyChallengeMethodHandler.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountEnrollPasskeyMethodHandler.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountExtensions.swift
  • auth0_flutter/darwin/Classes/MyAccountAPI/MyAccountHandler.swift
  • auth0_flutter/darwin/auth0_flutter.podspec
  • auth0_flutter/ios/auth0_flutter.podspec
  • auth0_flutter/lib/auth0_flutter.dart
  • auth0_flutter/lib/src/mobile/authentication_api.dart
  • auth0_flutter/lib/src/mobile/my_account_api.dart
  • auth0_flutter/macos/auth0_flutter.podspec
  • auth0_flutter/test/mobile/authentication_api_test.dart
  • auth0_flutter_platform_interface/lib/auth0_flutter_platform_interface.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_exchange_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_login_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/auth_passkey_signup_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/auth/passkey_challenge.dart
  • auth0_flutter_platform_interface/lib/src/auth/passkey_credential.dart
  • auth0_flutter_platform_interface/lib/src/auth0_flutter_auth_platform.dart
  • auth0_flutter_platform_interface/lib/src/method_channel_auth0_flutter_auth.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/auth0_flutter_my_account_platform.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/method_channel_auth0_flutter_my_account.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_enroll_passkey_challenge_options.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_enroll_passkey_options.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_passkey_authentication_method.dart
  • auth0_flutter_platform_interface/lib/src/myaccount/my_account_passkey_enrollment_challenge.dart
  • auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart
  • auth0_flutter_platform_interface/test/method_channel_auth0_flutter_my_account_test.dart
  • auth0_flutter_platform_interface/test/passkey_credential_test.dart

Comment thread auth0_flutter/android/build.gradle
Comment thread auth0_flutter/lib/src/mobile/my_account_api.dart
Comment thread .github/workflows/main.yml Outdated
Comment thread .github/workflows/main.yml Outdated
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