Skip to content

chore: bring v5.11.0 changes into v6-development - #1618

Merged
subhankarmaiti merged 4 commits into
v6-developmentfrom
chore/sync-master-into-v6-development
Jul 31, 2026
Merged

chore: bring v5.11.0 changes into v6-development#1618
subhankarmaiti merged 4 commits into
v6-developmentfrom
chore/sync-master-into-v6-development

Conversation

@subhankarmaiti

@subhankarmaiti subhankarmaiti commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Merges master at v5.11.0 into v6-development so the v6 line carries the latest 5.x fixes and features. Keeps the two branches from drifting further apart before v6 ships.

What it brings in: IPSIE session_expiry enforcement with a SESSION_EXPIRED error, web passkeys support, and My Account API support on the web platform.

The v6-only changes are preserved through the merge — the SDK stays New Architecture-only, the legacy Android oldarch spec remains removed, and the react-native >=0.82.0 peer floor is unchanged. .version and package.json move to 5.11.0 as part of the sync.

Summary by CodeRabbit

  • New Features
    • Added web passkey signup, login, and token exchange support, including MFA handling.
    • Added session-expiry tracking through sessionExpiresAt and a SESSION_EXPIRED error requiring re-authentication.
    • Added clearer passkey error handling for invalid credentials, parameters, and MFA requirements.
  • Documentation
    • Updated guides and examples for web passkeys, session expiry, and safer credential handling.
  • Chores
    • Released version 5.11.0.

@subhankarmaiti
subhankarmaiti requested a review from a team as a code owner July 31, 2026 10:30
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The v5.11.0 release adds IPSIE session-expiry handling, web passkey support, passkey error normalization, native credential validation, platform credential metadata propagation, documentation, tests, and release metadata updates.

Changes

Authentication features

Layer / File(s) Summary
Authentication contracts and errors
src/types/common.ts, src/types/parameters.ts, src/core/models/*
Adds sessionExpiresAt, web PublicKeyCredential inputs, normalized passkey error codes, and MFA payload extraction.
Session expiry propagation and enforcement
src/platforms/web/adapters/WebCredentialsManager.ts, android/..., ios/NativeBridge.swift, src/platforms/.../__tests__/*
Validates and propagates IPSIE session expiry data. Maps missing silent-token responses and native errors to SESSION_EXPIRED.
Web passkey flows and native input validation
src/platforms/web/adapters/WebAuth0Client.ts, src/platforms/native/adapters/NativeAuth0Client.ts, example/src/App.web.tsx, EXAMPLES*.md
Implements web challenge and token exchange flows. Uses browser WebAuthn credentials and rejects invalid native inputs.
Release metadata and documentation updates
.version, package.json, CHANGELOG.md, README.md, CLAUDE.md, A0Auth0.podspec
Updates v5.11.0 metadata, dependencies, release notes, API documentation, and authentication examples.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: pmathew92

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the merge of v5.11.0 changes into the v6-development branch.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/sync-master-into-v6-development

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

❤️ Share

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

@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

🧹 Nitpick comments (1)
src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts (1)

646-654: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the error instance and type separately.

toMatchObject({ constructor: PasskeyError, ... }) does not express intent clearly and relies on Jest comparing a constructor property. Use rejects.toBeInstanceOf(PasskeyError) with a stored promise, then assert type separately, and move the PasskeyError import out of the inline require so the test continues under single-assertion isolation.

🤖 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 `@src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts` around
lines 646 - 654, Update the getTokenByPasskey rejection test to store the
rejected promise, assert it with rejects.toBeInstanceOf(PasskeyError), and
separately assert the error’s type equals PasskeyErrorCodes.INVALID_PARAMETER.
Move PasskeyError to a top-level import instead of using an inline require,
while preserving the existing request inputs and single-assertion isolation.

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 `@example/src/App.web.tsx`:
- Around line 218-226: Add explicit null checks to the credential results in
both the creation flow and the get flow, using the surrounding passkey handlers
and their PublicKeyCredential assignments. Treat a null result as an error and
throw the existing PasskeyError before assigning or forwarding the credential;
preserve the current catch behavior for rejected credential operations.

In `@ios/NativeBridge.swift`:
- Line 21: Update the sessionExpiresAtKey declaration to remove its trailing
semicolon, leaving the string value and constant unchanged.

In `@src/core/models/PasskeyError.ts`:
- Around line 190-201: Update PasskeyError.getMfaRequiredPayload so absent
this.json is normalized to an empty object before accessing payload fields,
while preserving the existing fallback values. Validate that json.mfa_token is a
string and use the existing empty-string fallback otherwise. Add coverage for an
MFA_REQUIRED error without JSON and verify it returns a payload without
throwing.

In `@src/platforms/web/adapters/__tests__/WebAuth0Client.spec.ts`:
- Around line 956-975: Update the getTokenByPasskey test to guarantee rejection
and execution of the getMfaRequiredPayload assertion: add an assertion count
covering the catch-block expectation or use Jest’s rejects form. Preserve the
existing expected payload values and ensure a resolved promise cannot make the
test pass.

---

Nitpick comments:
In `@src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts`:
- Around line 646-654: Update the getTokenByPasskey rejection test to store the
rejected promise, assert it with rejects.toBeInstanceOf(PasskeyError), and
separately assert the error’s type equals PasskeyErrorCodes.INVALID_PARAMETER.
Move PasskeyError to a top-level import instead of using an inline require,
while preserving the existing request inputs and single-assertion isolation.
🪄 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: CHILL

Plan: Pro Plus

Run ID: ec7a1805-9247-4dab-a17c-a54bbb2fcb06

📥 Commits

Reviewing files that changed from the base of the PR and between eaca7af and 1ed54f0.

⛔ Files ignored due to path filters (2)
  • example/ios/Podfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (31)
  • .version
  • A0Auth0.podspec
  • CHANGELOG.md
  • CLAUDE.md
  • EXAMPLES-WEB.md
  • EXAMPLES.md
  • README.md
  • android/src/main/java/com/auth0/react/A0Auth0Module.kt
  • android/src/main/java/com/auth0/react/CredentialsParser.kt
  • example/src/App.web.tsx
  • ios/NativeBridge.swift
  • package.json
  • src/Auth0.ts
  • src/core/models/Credentials.ts
  • src/core/models/CredentialsManagerError.ts
  • src/core/models/PasskeyError.ts
  • src/core/models/__tests__/Credentials.spec.ts
  • src/core/models/__tests__/ErrorCodes.spec.ts
  • src/core/models/__tests__/PasskeyError.spec.ts
  • src/core/utils/telemetry.ts
  • src/platforms/native/adapters/NativeAuth0Client.ts
  • src/platforms/native/adapters/__tests__/NativeAuth0Client.spec.ts
  • src/platforms/native/adapters/__tests__/NativeCredentialsManager.errors.spec.ts
  • src/platforms/native/adapters/__tests__/NativeCredentialsManager.spec.ts
  • src/platforms/web/adapters/WebAuth0Client.ts
  • src/platforms/web/adapters/WebCredentialsManager.ts
  • src/platforms/web/adapters/__tests__/WebAuth0Client.spec.ts
  • src/platforms/web/adapters/__tests__/WebCredentialsManager.errors.spec.ts
  • src/platforms/web/adapters/__tests__/WebCredentialsManager.spec.ts
  • src/types/common.ts
  • src/types/parameters.ts
💤 Files with no reviewable changes (1)
  • src/Auth0.ts

Comment thread example/src/App.web.tsx
Comment on lines +218 to +226
let credential: PublicKeyCredential;
try {
credential = (await navigator.credentials.create({
publicKey:
challenge.authParamsPublicKey as PublicKeyCredentialCreationOptions,
})) as PublicKeyCredential;
} catch (e) {
throw new PasskeyError(e as Error);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add the null check that the documentation prescribes.

navigator.credentials.create() and .get() resolve to Credential | null. Both blocks cast the result to PublicKeyCredential without a null check, so a null resolution is forwarded as authResponse. The web adapter guard only rejects a string, and typeof null === 'object', so null reaches getTokenWithPasskey. EXAMPLES-WEB.md lines 306-309 documents the opposite pattern and throws on a missing credential. Align the example with the documentation.

🐛 Proposed fix for both flows
-      let credential: PublicKeyCredential;
-      try {
-        credential = (await navigator.credentials.create({
-          publicKey:
-            challenge.authParamsPublicKey as PublicKeyCredentialCreationOptions,
-        })) as PublicKeyCredential;
-      } catch (e) {
-        throw new PasskeyError(e as Error);
-      }
+      let credential: PublicKeyCredential;
+      try {
+        const created = (await navigator.credentials.create({
+          publicKey:
+            challenge.authParamsPublicKey as PublicKeyCredentialCreationOptions,
+        })) as PublicKeyCredential | null;
+        if (!created) {
+          throw new Error('No passkey credential returned');
+        }
+        credential = created;
+      } catch (e) {
+        throw new PasskeyError(e as Error);
+      }

Apply the same change to the navigator.credentials.get() block in onPasskeyLogin.

Also applies to: 254-262

🤖 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 `@example/src/App.web.tsx` around lines 218 - 226, Add explicit null checks to
the credential results in both the creation flow and the get flow, using the
surrounding passkey handlers and their PublicKeyCredential assignments. Treat a
null result as an error and throw the existing PasskeyError before assigning or
forwarding the credential; preserve the current catch behavior for rejected
credential operations.

Comment thread ios/NativeBridge.swift
static let accessTokenKey = "accessToken";
static let idTokenKey = "idToken";
static let expiresAtKey = "expiresAt";
static let sessionExpiresAtKey = "sessionExpiresAt";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the trailing semicolon.

Line 21 violates the configured SwiftLint trailing_semicolon rule. Remove the semicolon to keep the lint check clean.

🧰 Tools
🪛 SwiftLint (0.65.0)

[Warning] 21-21: Lines should not have trailing semicolons

(trailing_semicolon)

🤖 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 `@ios/NativeBridge.swift` at line 21, Update the sessionExpiresAtKey
declaration to remove its trailing semicolon, leaving the string value and
constant unchanged.

Source: Linters/SAST tools

Comment on lines +190 to +201
public getMfaRequiredPayload(): MfaRequiredErrorPayload | null {
if (this.type !== PasskeyErrorCodes.MFA_REQUIRED) {
return null;
}

const json = this.json as any;
return {
mfaToken: json.mfa_token ?? '',
error: json.error ?? this.code,
errorDescription: json.error_description ?? this.message,
mfaRequirements: json.mfa_requirements,
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Handle absent MFA error JSON before reading payload fields.

AuthError.json is optional. If an AuthError has code mfa_required but no JSON body, json is undefined and Line 197 throws.

Normalize this.json to an object before reading fields. Validate mfa_token as a string. Add a test for an MFA-required error without JSON.

Proposed fix
-    const json = this.json as any;
+    const json =
+      typeof this.json === 'object' && this.json !== null
+        ? (this.json as Record<string, unknown>)
+        : {};
+
     return {
-      mfaToken: json.mfa_token ?? '',
-      error: json.error ?? this.code,
-      errorDescription: json.error_description ?? this.message,
+      mfaToken: typeof json.mfa_token === 'string' ? json.mfa_token : '',
+      error: typeof json.error === 'string' ? json.error : this.code,
+      errorDescription:
+        typeof json.error_description === 'string'
+          ? json.error_description
+          : this.message,
       mfaRequirements: json.mfa_requirements,
     };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public getMfaRequiredPayload(): MfaRequiredErrorPayload | null {
if (this.type !== PasskeyErrorCodes.MFA_REQUIRED) {
return null;
}
const json = this.json as any;
return {
mfaToken: json.mfa_token ?? '',
error: json.error ?? this.code,
errorDescription: json.error_description ?? this.message,
mfaRequirements: json.mfa_requirements,
};
public getMfaRequiredPayload(): MfaRequiredErrorPayload | null {
if (this.type !== PasskeyErrorCodes.MFA_REQUIRED) {
return null;
}
const json =
typeof this.json === 'object' && this.json !== null
? (this.json as Record<string, unknown>)
: {};
return {
mfaToken: typeof json.mfa_token === 'string' ? json.mfa_token : '',
error: typeof json.error === 'string' ? json.error : this.code,
errorDescription:
typeof json.error_description === 'string'
? json.error_description
: this.message,
mfaRequirements: json.mfa_requirements,
};
🤖 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 `@src/core/models/PasskeyError.ts` around lines 190 - 201, Update
PasskeyError.getMfaRequiredPayload so absent this.json is normalized to an empty
object before accessing payload fields, while preserving the existing fallback
values. Validate that json.mfa_token is a string and use the existing
empty-string fallback otherwise. Add coverage for an MFA_REQUIRED error without
JSON and verify it returns a payload without throwing.

Comment on lines +956 to +975

// Also verify getMfaRequiredPayload() returns structured data
try {
await client.getTokenByPasskey({
authSession: 'auth-session-123',
authResponse: rawCredential,
});
} catch (error: any) {
const payload = error.getMfaRequiredPayload();
expect(payload).toEqual({
mfaToken: 'mfa_tok_123',
error: 'mfa_required',
errorDescription: 'MFA is required',
mfaRequirements: {
challenge: [{ type: 'sms' }, { type: 'otp' }],
enroll: [{ type: 'email' }],
},
});
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Guard the try/catch assertion against a vacuous pass.

If getTokenByPasskey resolves, the catch block never runs and the test passes without checking getMfaRequiredPayload(). Add expect.assertions or use the rejects form so the payload assertion always executes.

💚 Proposed fix
       // Also verify getMfaRequiredPayload() returns structured data
+      expect.assertions(2);
       try {
         await client.getTokenByPasskey({
           authSession: 'auth-session-123',
           authResponse: rawCredential,
         });
+        throw new Error('Expected getTokenByPasskey to reject');
       } catch (error: any) {
         const payload = error.getMfaRequiredPayload();
🤖 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 `@src/platforms/web/adapters/__tests__/WebAuth0Client.spec.ts` around lines 956
- 975, Update the getTokenByPasskey test to guarantee rejection and execution of
the getMfaRequiredPayload assertion: add an assertion count covering the
catch-block expectation or use Jest’s rejects form. Preserve the existing
expected payload values and ensure a resolved promise cannot make the test pass.

@subhankarmaiti
subhankarmaiti merged commit 8a7531d into v6-development Jul 31, 2026
5 checks passed
@subhankarmaiti
subhankarmaiti deleted the chore/sync-master-into-v6-development branch July 31, 2026 10:36
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