Skip to content

SDKS-5102: Add Metadata, Image, and FIDO2 Error Capabilities - #126

Merged
SteinGabriel merged 4 commits into
mainfrom
SDKS-5102
Sep 16, 2026
Merged

SteinGabriel merged 4 commits into
mainfrom
SDKS-5102

Conversation

@SteinGabriel

@SteinGabriel SteinGabriel commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

https://pingidentity.atlassian.net/browse/SDKS-5102

Updates the reactjs-todo-davinci sample app to demonstrate three new @forgerock/davinci-client capabilities: the MetadataCollector (pausing a DaVinci flow to invoke a third-party SDK), the ImageCollector (Forms image rendering), and the typed FIDO2 client error contract. Each is added as a reference example for developers integrating DaVinci flows.

Changes

reactjs-todo-davinci/client/components/davinci-client

  • metadata.js (new) — MetadataComponent for MetadataCollector. Calls a runThirdPartySdk(config) stand-in against collector.output.config, then reports that SDK's outcome back to DaVinci: its success value via updater(sdkResult.value), or a structured MetadataError ({code, message} object literal, since the SDK exposes MetadataError as a type with no builder function) on failure. Checks updater's own return for an error before calling setNext(). Renders explicit "Success" and "Failure" buttons so both branches have a deterministic trigger, mirroring the SDK repo's own e2e fixture.
  • image.js (new) — ImageComponent for ImageCollector, rendering <img src alt data-testid="form-image">, wrapped in <a href> when output.href is present. parseSafeHref restricts the href to http:/https: schemes, as the SDK's type doc requires consumers to sanitize this value.
  • fido.js — new describeFidoError helper branches displayed copy on the typed GenericError.type returned by fido().register()/authenticate(): fido_error passes the SDK message through as an expected WebAuthn/browser failure, anything else gets generic unexpected-error copy. Error logging now uses labeled console.error calls.
  • form.jsImageCollector and MetadataCollector cases added to mapCollectorsToComponents, following the existing switch-statement pattern.
  • readonly.js — applies theme.textClass and mb-3 to both the ReadOnlyCollector and RichTextCollector render branches. Found during manual testing: the metadata flow's trailing message step rendered with class="", unstyled and invisible against the dark theme.

reactjs-todo-davinci (docs / manifest)

  • README.mdImageCollector and MetadataCollector added to the supported-collectors list.
  • package.json — dependency keys reordered alphabetically. @forgerock/davinci-client stays at "latest".

Tests

  • e2e/davinci-image.spec.js (new) — asserts the image renders with non-empty src/alt and no hyperlink wrapper, and that the wrapper appears when output.href is present. test.describe.skip.
  • e2e/davinci-metadata.spec.js (new) — asserts the flow advances on the Success path and on the Failure path (structured error reported, flow still advances). test.describe.skip.
  • e2e/davinci-fido.spec.js — the two existing failure tests now assert the branched fido_error copy directly rather than only checking the generic fallback is absent. Remains test.describe.skip for the same pre-existing WebAuthn registration limitation.

Unverified coverage — please read before approving

The image and metadata collector paths are not covered by a passing e2e run. Both new specs are test.describe.skip with acrValue = 'TBD', because they require DaVinci flow policy IDs that emit an IMAGE field and a METADATA action, which are not yet available. A green CI run on this PR does not exercise either new component. The FIDO2 spec is likewise still skipped (pre-existing).

The metadata component was verified manually against a real Metadata Flow, which is how the readonly.js styling bug was found. The image component has not been verified against a live flow.

MetadataCollector is not in a published @forgerock/davinci-client release. It only exists on PR #727 (SDKS-5100-metadata-collector); the latest published version is 2.1.0. package.json declares "latest" and the lockfile resolves entirely to the npm registry, so npm ci is clean and no ephemeral build URL is committed. To exercise the metadata path locally before #727 merges, apply an uncommitted override:

npm install @forgerock/davinci-client@https://pkg.pr.new/@forgerock/davinci-client@727 -w javascript/reactjs-todo-davinci

Revert that before committing. Once #727 publishes, "latest" resolves correctly with no change needed here.

How to test

1. Metadata collector

  1. npm ci from the repo root, then apply the pkg.pr.new override above.
  2. npm run start:reactjs-todo-dv from /javascript.
  3. Navigate to ?acrValue=<metadata-flow-policy-id> and sign in.
  4. Confirm the DaVinci-supplied config payload renders in the <pre> block.
  5. Click Success — the simulated third-party SDK resolves with a value, updater reports it, and the flow advances.
  6. Restart the flow and click Failure — a METADATA_PROCESSING_ERROR is reported via updater and the flow still advances. Confirm the trailing message step is legible (this is the readonly.js fix).

2. Image collector

  1. Navigate to ?acrValue=<image-flow-policy-id> and sign in.
  2. Confirm the image renders with the flow's src and alt.
  3. For a flow supplying href, confirm the image is wrapped in a same-tab link.

Verify the href sanitizer

Configure a flow whose image href uses a javascript: scheme, or temporarily hardcode one. Confirm the image renders unwrapped rather than as a link.

3. FIDO2 typed error branching

  1. Navigate to a FIDO2-enabled flow in a browser where WebAuthn will fail (no authenticator, or cancel the prompt).
  2. Confirm the alert reads "Your device or browser could not complete this request." for a fido_error, not the generic "Something unexpected went wrong." copy.

Summary by CodeRabbit

  • New Features

    • Added support for Image and Metadata collectors.
    • Images can display safely linked content and collector errors.
    • Metadata flows show configuration, loading states, errors, and success/failure actions.
    • Added theme-aware styling for read-only and rich-text content.
  • Bug Fixes

    • Improved FIDO error messages, error codes, and retry behavior.
    • Raw OIDC redirect settings can now override the default callback URI.
  • Documentation

    • Documented the newly supported collector types.

@SteinGabriel SteinGabriel added the do not merge Do not merge label Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: d9959fbf-f533-4766-886c-d230708586fb

📝 Walkthrough

Walkthrough

The React DaVinci client now supports image and metadata collectors, structured FIDO error display, themed read-only output, and raw OIDC redirect overrides. Documentation and end-to-end coverage were updated.

Changes

DaVinci collector updates

Layer / File(s) Summary
Image collector rendering
javascript/reactjs-todo-davinci/client/components/davinci-client/form.js, javascript/reactjs-todo-davinci/client/components/davinci-client/image.js, javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js, javascript/reactjs-todo-davinci/README.md
The form renders ImageCollector with ImageComponent. The component permits only HTTP(S) links and renders skipped end-to-end coverage for unsafe links.
Metadata collector flow
javascript/reactjs-todo-davinci/client/components/davinci-client/form.js, javascript/reactjs-todo-davinci/client/components/davinci-client/metadata.js
MetadataComponent runs the demo SDK, updates collector state, handles errors, and advances the form after success.

FIDO error updates

Layer / File(s) Summary
Structured FIDO error display
javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js, javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
FIDO failures now expose structured messages and codes. Registration and authentication tests verify the alert text and NotAllowedError code.

Client presentation and configuration

Layer / File(s) Summary
Themed read-only output
javascript/reactjs-todo-davinci/client/components/davinci-client/readonly.js
Read-only and rich-text output now uses the theme text class.
OIDC redirect configuration
javascript/reactjs-todo-davinci/client/constants.js
Raw OIDC configuration can override the default callback redirect URI.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant MetadataComponent
  participant runThirdPartySdk
  participant updater
  participant Form
  User->>MetadataComponent: Select Success or Failure
  MetadataComponent->>runThirdPartySdk: Run with collector config
  runThirdPartySdk-->>MetadataComponent: Return success or error
  MetadataComponent->>updater: Submit metadata result
  updater-->>MetadataComponent: Return update status
  MetadataComponent->>Form: Advance after successful update
Loading

Possibly related PRs

Suggested reviewers: vatsalparikh

🚥 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 and concisely identifies the three main changes: Metadata, Image, and FIDO2 error capabilities.
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 SDKS-5102

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

A rabbit checks each image bright,
Metadata guides the next step right.
FIDO errors show their code,
Themes style the read-only road.
OIDC redirects follow the flow.

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

🧹 Nitpick comments (2)
javascript/reactjs-todo-davinci/client/components/davinci-client/metadata.js (1)

64-81: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Always clear loading state when an SDK operation rejects.

A rejected third-party SDK call or thrown updater bypasses line 81, leaving both actions disabled with no user-facing error. Wrap the sequence in try/catch/finally.

Proposed fix
   async function handleContinue(shouldSucceed) {
     setIsLoading(true);
     setError(null);

-    const sdkResult = await runThirdPartySdk(collector.output.config, shouldSucceed);
-    const updateResult =
-      sdkResult && 'error' in sdkResult
-        ? updater({ code: 'METADATA_PROCESSING_ERROR', message: sdkResult.error })
-        : updater(sdkResult.value);
-
-    if (updateResult && 'error' in updateResult) {
-      setError(updateResult.error?.message || 'Update error');
-      console.error('Error updating metadata collector:', updateResult.error);
-    } else {
-      await submitForm();
+    try {
+      const sdkResult = await runThirdPartySdk(collector.output.config, shouldSucceed);
+      const updateResult =
+        sdkResult && 'error' in sdkResult
+          ? updater({ code: 'METADATA_PROCESSING_ERROR', message: sdkResult.error })
+          : updater(sdkResult.value);
+
+      if (updateResult && 'error' in updateResult) {
+        setError(updateResult.error?.message || 'Update error');
+      } else {
+        await submitForm();
+      }
+    } catch (error) {
+      console.error('Error processing metadata collector:', error);
+      setError('Metadata processing failed');
+    } finally {
+      setIsLoading(false);
     }
-
-    setIsLoading(false);
   }
🤖 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 `@javascript/reactjs-todo-davinci/client/components/davinci-client/metadata.js`
around lines 64 - 81, Update handleContinue to wrap the runThirdPartySdk,
updater, and submitForm sequence in try/catch/finally. Catch rejected SDK calls
or thrown updater errors, surface the failure through setError, and ensure
setIsLoading(false) runs in finally so both actions are re-enabled.
javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js (1)

15-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add policy-independent tests that run in CI.

Both new E2E suites are skipped with TBD flow IDs, so CI does not exercise image URL filtering or metadata success/failure continuation.

  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js#L15-L36: retain the policy-backed placeholder, but add runnable component coverage for allowed, malformed, and unsafe href values.
  • javascript/reactjs-todo-davinci/e2e/davinci-metadata.spec.js#L15-L36: retain the policy-backed placeholder, but add runnable component coverage for successful updates, returned update errors, and rejected SDK calls.
🤖 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 `@javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js` around lines 15 -
36, Add runnable, policy-independent component coverage while retaining the
skipped policy-backed tests in
javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js lines 15-36: cover
allowed, malformed, and unsafe href values. Also add runnable coverage in
javascript/reactjs-todo-davinci/e2e/davinci-metadata.spec.js lines 15-36 for
successful metadata updates, returned update errors, and rejected SDK calls,
using the existing image and metadata test symbols.
🤖 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 `@javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js`:
- Around line 111-116: Update the alert text assertions in the FIDO error test
to avoid requiring an exact match against the alert container, which also
includes the Try Again button. Use toContainText for both failure assertions, or
target the alert’s inner error-message div while preserving the existing
expected messages.

---

Nitpick comments:
In
`@javascript/reactjs-todo-davinci/client/components/davinci-client/metadata.js`:
- Around line 64-81: Update handleContinue to wrap the runThirdPartySdk,
updater, and submitForm sequence in try/catch/finally. Catch rejected SDK calls
or thrown updater errors, surface the failure through setError, and ensure
setIsLoading(false) runs in finally so both actions are re-enabled.

In `@javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js`:
- Around line 15-36: Add runnable, policy-independent component coverage while
retaining the skipped policy-backed tests in
javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js lines 15-36: cover
allowed, malformed, and unsafe href values. Also add runnable coverage in
javascript/reactjs-todo-davinci/e2e/davinci-metadata.spec.js lines 15-36 for
successful metadata updates, returned update errors, and rejected SDK calls,
using the existing image and metadata test symbols.
🪄 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: 3f0ae4e5-1d46-45ef-bf00-3105bc033830

📥 Commits

Reviewing files that changed from the base of the PR and between 360d26f and 19c58da.

📒 Files selected for processing (10)
  • javascript/reactjs-todo-davinci/README.md
  • javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/form.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/image.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/metadata.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/readonly.js
  • javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js
  • javascript/reactjs-todo-davinci/e2e/davinci-metadata.spec.js
  • javascript/reactjs-todo-davinci/package.json

Comment thread javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js Outdated

@ancheetah ancheetah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Left some comments. Idk how I feel about including metadata and image e2e tests. I feel this duplicates what's already in the sdk repo.

*/
function describeFidoError(fidoError) {
if (fidoError.type === 'fido_error') {
return fidoError.message || 'Your device or browser could not complete this request.';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we return fidoError.code instead so that we can assert a specific error in the e2e test? For example, if the prompt is cancelled, you should get a NotAllowedError code.
Example:
https://github.com/ForgeRock/ping-javascript-sdk/blob/main/e2e/davinci-suites/src/fido.test.ts#L239

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

describeFidoError now returns { message, code }, exposed via data-error-code on the alert. I've added assertions on it in both failure tests, matching the pattern SDK e2e suite.
Thanks!

Comment on lines +73 to +74
setError(describeFidoError(response));
console.error('Fido error:', response);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If there is an error, we still need to update the collector with that error and send it to DaVinci. Are we doing that here?
https://github.com/ForgeRock/ping-javascript-sdk/blob/main/e2e/davinci-app/components/fido.ts#L33-L37

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right, the error branch now calls updater(response) and send it to DaVinci.
Thanks for pointing this out.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe I'm reading it wrong but the error branch still does not appear to submit the error value to DaVinci. i.e. it only calls updater and does not call submitForm(). Perhaps we can refactor the error and success branches. They should both update and call submit form so these bits of logic can be pulled out.

@SteinGabriel SteinGabriel Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, you're right. I now moved the update+submit logic into a shared updateAndSubmit helper used by both branches. The error branch now calls submitForm() as well.
Thanks for pointing this out.

"@forgerock/oidc-client": "latest",
"@forgerock/sdk-utilities": "latest",
"@forgerock/protect": "latest",
"@forgerock/sdk-utilities": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need sdk utilities package?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, @forgerock/sdk-utilities itself is pre-existing, used for makeOidcConfig/makeDavinciConfig. For some reason it got automatically reordered at some point. I restored it back to how it was before.

"webpack-dev-server": "^5.1.0"
},
"dependencies": {
"@forgerock/davinci-client": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you want to test this with a beta you can grab it from here:
ForgeRock/ping-javascript-sdk#730 (comment)

Please mark this PR with DO NOT MERGE label so we don't accidentally merge it before the 2.2 release.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's what I've done for local testing. I used pkg.pr.new to install the SDK from that PR.
The "do not merge" label was applied when this PR was created. It'll be merged only after these features are released.

@SteinGabriel
SteinGabriel force-pushed the SDKS-5102 branch 2 times, most recently from a4a267a to 4d19084 Compare July 30, 2026 21:25

@vatsalparikh vatsalparikh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The hardcoded redreictUri prevents user configured redirectUri overrides. I found this was an issue while testing. We should move the hardcoded or default value up (i.e., move redirectUri above) so that any spread from rawConfig.oidc (i.e., move rawConfig.oidc below) which is the user defined value takes precedence.

redirectUri: `${window.location.origin}/callback.html`,

@SteinGabriel

Copy link
Copy Markdown
Contributor Author

The hardcoded redreictUri prevents user configured redirectUri overrides. I found this was an issue while testing. We should move the hardcoded or default value up (i.e., move redirectUri above) so that any spread from rawConfig.oidc (i.e., move rawConfig.oidc below) which is the user defined value takes precedence.

redirectUri: `${window.location.origin}/callback.html`,

Nice catch! Moved the default redirectUri above the ...rawConfig.oidc spread, so a user configured value now takes precedence instead of being overwritten.
Thanks for catching this.

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

🧹 Nitpick comments (1)
javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js (1)

14-33: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add coverage for the unknown_error branch.

The changed e2e cases cover only fido_error with NotAllowedError. Add a focused component or unit test that supplies type: 'unknown_error' and verifies the generic message and preserved code from describeFidoError.

🤖 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 `@javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js`
around lines 14 - 33, Add a focused unit or component test for describeFidoError
that passes type 'unknown_error' with a code and verifies it returns the generic
unexpected-error message while preserving that code.
🤖 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 `@javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js`:
- Around line 11-27: Replace the placeholder imageFlowAcrValue with a
deterministic DaVinci flow fixture that emits an IMAGE collector whose
output.href uses an unsafe scheme. Update the test to assert the fixture’s
unsafe href is present before verifying no anchor wraps the image, or move the
unsafe-href behavior into a focused component test so the assertion cannot pass
when href is absent.

---

Nitpick comments:
In `@javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js`:
- Around line 14-33: Add a focused unit or component test for describeFidoError
that passes type 'unknown_error' with a code and verifies it returns the generic
unexpected-error message while preserving that code.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9834c6df-e282-4001-bc5e-02b640079057

📥 Commits

Reviewing files that changed from the base of the PR and between 19c58da and 0488c65.

📒 Files selected for processing (4)
  • javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js
  • javascript/reactjs-todo-davinci/client/constants.js
  • javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js

Comment thread javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js
cerebrl
cerebrl previously approved these changes Aug 10, 2026

@ancheetah ancheetah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Few more comments on FIDO implementation.

'Your device or browser could not complete this request.',
);
// Assert the specific WebAuthn failure reason surfaced by the SDK
await expect(page.getByRole('alert')).toHaveAttribute('data-error-code', 'NotAllowedError');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of asserting an alert from the application, we should assert that the error node in the flow was reached. In the e2e flow this node should output an error message on the screen with the error code. This tests that we sent the correct error payload to DaVinci and they routed us to an error node.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right, this was meant to be a temporary change while the Fido errors PR was still in development. Thanks for catching this.

Updated both failure tests to assert the DaVinci error node's alert instead of FidoComponent's own local one, plus that Try Again disappears once the flow advances. Ran both live against a pkg.pr.new build of #730 and confirmed the literal copy: 'FIDO Registration Error - NotAllowedError' / 'FIDO Authentication Error - NotAllowedError', matching the SDK's own fido.test.ts assertion approach.

Comment thread javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js 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: 1

🤖 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 `@javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js`:
- Around line 81-82: Update the FIDO error handling around describeFidoError to
pass response.error, the typed error payload, so the correct message and
data-error-code are produced. Keep response unchanged as the argument to
updateAndSubmit.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 29c42400-cafd-4016-8aef-f681b6f84262

📥 Commits

Reviewing files that changed from the base of the PR and between 0488c65 and a4bafb2.

📒 Files selected for processing (3)
  • javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js
  • javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js

Comment thread javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js Outdated
ancheetah
ancheetah previously approved these changes Aug 11, 2026

@ancheetah ancheetah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks great! Thanks Gabriel

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

🧹 Nitpick comments (1)
javascript/reactjs-todo-davinci/client/components/davinci-client/image.js (1)

18-24: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add passing component tests for the URL policy.

The image e2e suite is skipped. Add focused tests for valid http: and https: URLs, rejected javascript:, data:, and ftp: schemes, and malformed values. These tests do not require a DaVinci policy and will prevent sanitizer regressions.

🤖 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 `@javascript/reactjs-todo-davinci/client/components/davinci-client/image.js`
around lines 18 - 24, เพิ่ม focused component tests for parseSafeHref covering
valid http: and https: URLs, rejecting javascript:, data:, and ftp: schemes, and
returning null for malformed values. Keep the tests independent of any DaVinci
policy and assert the sanitizer’s accepted or rejected output directly.
🤖 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.

Nitpick comments:
In `@javascript/reactjs-todo-davinci/client/components/davinci-client/image.js`:
- Around line 18-24: เพิ่ม focused component tests for parseSafeHref covering
valid http: and https: URLs, rejecting javascript:, data:, and ftp: schemes, and
returning null for malformed values. Keep the tests independent of any DaVinci
policy and assert the sanitizer’s accepted or rejected output directly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 821f5d8e-0ad2-4a10-86f7-a9de04d79643

📥 Commits

Reviewing files that changed from the base of the PR and between c2223ee and 9872171.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • javascript/reactjs-todo-davinci/README.md
  • javascript/reactjs-todo-davinci/client/components/davinci-client/fido.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/form.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/image.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/metadata.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/readonly.js
  • javascript/reactjs-todo-davinci/client/constants.js
  • javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js
🚧 Files skipped from review as they are similar to previous changes (6)
  • javascript/reactjs-todo-davinci/README.md
  • javascript/reactjs-todo-davinci/client/constants.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/form.js
  • javascript/reactjs-todo-davinci/e2e/davinci-fido.spec.js
  • javascript/reactjs-todo-davinci/client/components/davinci-client/readonly.js
  • javascript/reactjs-todo-davinci/e2e/davinci-image.spec.js

@vatsalparikh
vatsalparikh dismissed their stale review August 12, 2026 22:34

The changes I requested have been addressed.

I did a cursory review of the PR but didn't go into details, so dismissing my review.

@SteinGabriel SteinGabriel added the do not merge Do not merge label Aug 12, 2026

@ancheetah ancheetah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some new suggestions for the FIDO component

Comment on lines +81 to +86
* Details: `fidoClient.register`/`authenticate` return a typed
* `GenericError` on failure. Its `type` field ('fido_error' vs
* 'unknown_error') lets the flow distinguish an expected WebAuthn/browser
* failure from an unexpected internal one, rather than parsing a message
* string. `code` (e.g. `NotAllowedError`) is surfaced as a data attribute
* so e2e tests can assert on the specific WebAuthn failure reason.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Technically the only type of GenericError the FIDO API can return is fido_error I believe. Also, let's not refer to it as a "client", that was a mistake in my typing. Let's call it an API. I would also remove the mention of e2e tests and have something like this:

The FIDO API register() and authenticate() methods return a GenericError on failure with type fido_error. The error code determines if it was a DOM exception (e.g. NotAllowedError) vs internal error (UnknownError). You may choose to handle this error client side, or send the error to DaVinci to reach an error branch configured in your flow. To send the error to DaVinci, update the collector with the error and submit it by calling davincClient.next().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Rewrote this comment with your suggested wording, and updated describeFidoError's JSDoc to match.
Thanks!

@@ -24,6 +44,16 @@ export default function FidoComponent({ collector, updater, submitForm }) {
const [hasAttempted, setHasAttempted] = useState(false); // for registration auto-trigger
const fidoClient = fido();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we rename fidoClient to fidoApi?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. Thanks!

ancheetah
ancheetah previously approved these changes Sep 3, 2026

@ancheetah ancheetah left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

FIDO changes look good. Thanks Gabriel!

feat(reactjs-todo-davinci): branch FIDO2 error UI on typed error contract

chore(reactjs-todo-davinci): temporarily depend on davinci-client PR #727 build for MetadataCollector

feat(reactjs-todo-davinci): add MetadataCollector component

test(reactjs-todo-davinci): add image/metadata e2e specs, extend fido error assertion

fix(reactjs-todo-davinci): import getMetadataError from SDK utils subpath

fix(reactjs-todo-davinci): sanitize ImageCollector href scheme before render

fix(reactjs-todo-davinci): build MetadataError literal, drop removed getMetadataError import

fix(reactjs-todo-davinci): redact metadata payload display, flag unsafe storage of sensitive data

test(reactjs-todo-davinci): assert positive fido_error copy instead of negative check

fix(reactjs-todo-davinci): log error details with labeled console.error, matching codebase convention

docs(reactjs-todo-davinci): add ImageCollector, MetadataCollector to README

feat(reactjs-todo-davinci): redesign MetadataCollector around third-party SDK invocation

fix(e2e): use toContainText for fido alert assertions

fix(davinci): report fido error to updater before local display

chore(reactjs-todo-davinci): revert unnecessary dependency reorder

test(reactjs-todo-davinci): trim e2e specs to sample-specific coverage, drop duplicate metadata spec

fix(davinci): submit fido error to davinci via shared update-and-submit helper

test(e2e): assert davinci error node reached with literal error copy
@SteinGabriel SteinGabriel removed the do not merge Do not merge label Sep 16, 2026
@SteinGabriel
SteinGabriel merged commit c6dbc82 into main Sep 16, 2026
48 of 49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants