Skip to content

SDKS-5067: Standardize SDK Configuration#118

Open
SteinGabriel wants to merge 1 commit into
mainfrom
SDKS-5067
Open

SDKS-5067: Standardize SDK Configuration#118
SteinGabriel wants to merge 1 commit into
mainfrom
SDKS-5067

Conversation

@SteinGabriel

@SteinGabriel SteinGabriel commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

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

Migrates SDK credentials out of environment variables and into a per-app
config.json file using the unified SDK configuration schema. All three
JavaScript sample apps (reactjs-todo-davinci, reactjs-todo-oidc,
reactjs-todo-journey) now accept a structured JSON config object detected and
mapped to internal config automatically by the factory discriminator.

Changes

reactjs-todo-davinci

  • constants.js — replaces WEB_OAUTH_CLIENT/SCOPE/WELLKNOWN_URL env
    vars with CONFIG imported from config.json; falls back to SDK_CONFIG
    env var (JSON string) for e2e/CI
  • config.example.json — new committed template for the unified SDK config
    shape
  • config.test.json / config.test.fido.json — committed test fixtures
    replacing hardcoded Playwright env vars
  • playwright.config.ts — uses SDK_CONFIG: JSON.stringify(testConfig)
    instead of individual credential vars
  • webpack.config.js — removes WEB_OAUTH_CLIENT/SCOPE/WELLKNOWN_URL;
    injects SDK_CONFIG
  • .env.example — removes SDK credential vars; adds migration note
  • .gitignore — adds config.json

reactjs-todo-oidc

  • constants.js — same pattern as davinci; preserves SERVER env var
    (PingAM/PingOne display-name logic)
  • config.example.json — new committed template
  • config.test.pingam.json / config.test.pingone.json — per-server test
    fixtures
  • playwright.config.ts — uses SDK_CONFIG per project config
  • webpack.config.js — same removals/additions as davinci
  • .env.example, .gitignore, README.md, client/README.md — updated

reactjs-todo-journey

  • constants.js — Vite JSON import (import.meta.env.VITE_SDK_CONFIG
    override for CI)
  • config.example.json — new committed template
  • config.test.json — committed test fixture
  • playwright.config.js — uses VITE_SDK_CONFIG: JSON.stringify(testConfig)
  • .env.example, .gitignore, README.md — updated

Tests

  • All three apps' Playwright e2e configs verified against new
    SDK_CONFIG/VITE_SDK_CONFIG injection pattern
  • Existing e2e suites pass with migrated config (webpack apps have a
    pre-existing babel-loader/validateOptions failure at bc9ebef unrelated
    to this change)

How to test

1. Local dev setup

Copy config.example.jsonconfig.json in each app root, fill in
clientId, discoveryEndpoint, scopes, redirectUri. Copy .env.example
.env, fill remaining runtime vars. Run npm run start:reactjs-todo-dv
(or journey/oidc variant) from javascript/. Verify auth flow completes.

2. E2E run

Run npm run e2e --workspace reactjs-todo-davinci, --workspace reactjs-todo-journey, and --workspace reactjs-todo-oidc from
javascript/. All suites should pass. Confirm config.json is not committed
(gitignored).

3. Verify backward-compat

Confirm no WEB_OAUTH_CLIENT, SCOPE, or WELLKNOWN_URL (or VITE_
variants) remain in .env.example, webpack.config.js, or Playwright
configs.

Summary by CodeRabbit

Release Notes

  • Documentation

    • Updated setup instructions to configure OIDC credentials via JSON config files instead of environment variables.
    • Simplified .env examples to focus only on runtime settings (API URL, debug flags, port).
  • Chores

    • Enhanced build and test configuration to support the new configuration workflow.
    • Added SDK utilities dependency for configuration management across all applications.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Three React todo sample apps (davinci, journey, oidc) migrate OIDC/SDK configuration from individual environment variables (WEB_OAUTH_CLIENT, SCOPE, WELLKNOWN_URL) to a unified config.json file. A new @forgerock/sdk-utilities dependency provides makeOidcConfig, makeDavinciConfig, and makeJourneyConfig helpers. Build tooling gains optional config.json fallback, and Playwright E2E configs inject SDK_CONFIG from test JSON files.

Changes

SDK Config Migration to config.json

Layer / File(s) Summary
Config schema, example files, and gitignore
javascript/reactjs-todo-davinci/config.example.json, javascript/reactjs-todo-davinci/config.test.json, javascript/reactjs-todo-davinci/config.test.fido.json, javascript/reactjs-todo-davinci/.gitignore, javascript/reactjs-todo-journey/config.example.json, javascript/reactjs-todo-journey/config.test.json, javascript/reactjs-todo-journey/.gitignore, javascript/reactjs-todo-oidc/config.example.json, javascript/reactjs-todo-oidc/config.test.pingam.json, javascript/reactjs-todo-oidc/config.test.pingone.json, javascript/reactjs-todo-oidc/.gitignore
New config.example.json files define the oidc schema (clientId, discoveryEndpoint, scopes); test config JSON files add OIDC values with localhost redirectUri; .gitignore entries added for config.json in all three apps.
constants.js CONFIG refactoring + package deps
javascript/reactjs-todo-davinci/client/constants.js, javascript/reactjs-todo-davinci/package.json, javascript/reactjs-todo-journey/client/constants.js, javascript/reactjs-todo-journey/package.json, javascript/reactjs-todo-oidc/client/constants.js, javascript/reactjs-todo-oidc/package.json
Removes exported WEB_OAUTH_CLIENT, SCOPE, WELLKNOWN_URL constants; replaces the hard-coded CONFIG object with rawConfig loaded from SDK_CONFIG env JSON or config.json fallback, overriding oidc.redirectUri to window.location.origin/callback.html. @forgerock/sdk-utilities added to all three package.json files.
SDK utilities helpers in context and hook files
javascript/reactjs-todo-davinci/client/context/oidc.context.js, javascript/reactjs-todo-davinci/client/components/davinci-client/hooks/create-client.utils.js, javascript/reactjs-todo-journey/client/context/oidc.context.js, javascript/reactjs-todo-journey/client/components/journey/journey.hook.js, javascript/reactjs-todo-oidc/client/context/oidc.context.js
Imports makeOidcConfig, makeDavinciConfig, and makeJourneyConfig from @forgerock/sdk-utilities; wraps CONFIG in the appropriate helper before passing to client initializers. useInitOidcState parameter renamed from config to json in davinci and journey.
Build tooling: optional config.json fallback (Webpack + Vite)
javascript/reactjs-todo-davinci/webpack.config.js, javascript/reactjs-todo-oidc/webpack.config.js, javascript/reactjs-todo-journey/vite.config.js
Webpack configs gain fs-based NormalModuleReplacementPlugin to substitute config.example.json when config.json is absent, inject SDK_CONFIG via DefinePlugin, and remove old OAuth env injections. Vite config adds optionalConfigJson plugin that serves an empty virtual module when config.json is missing.
E2E/Playwright: inject SDK_CONFIG from test JSON files
javascript/reactjs-todo-davinci/playwright.config.ts, javascript/reactjs-todo-journey/playwright.config.js, javascript/reactjs-todo-journey/e2e/embedded-login.spec.js, javascript/reactjs-todo-oidc/playwright.config.ts
Playwright configs load test config JSON files and set SDK_CONFIG/VITE_SDK_CONFIG in webServer env via JSON.stringify, replacing prior hardcoded env vars. Journey e2e spec adds test.afterEach hook to clear localStorage, sessionStorage, and cookies.
Docs, .env.example, and README updates
javascript/reactjs-todo-davinci/README.md, javascript/reactjs-todo-davinci/.env.example, javascript/reactjs-todo-journey/README.md, javascript/reactjs-todo-journey/.env.example, javascript/reactjs-todo-oidc/README.md, javascript/reactjs-todo-oidc/.env.example, javascript/reactjs-todo-oidc/client/README.md
All three apps' READMEs add a "Configure SDK Credentials" section with config.json copy instructions; .env.example files remove OAuth placeholders and add guidance directing users to config.json.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • vatsalparikh
  • ryanbas21
  • cerebrl

Poem

🐇 Hop hop, no more env sprawl,
config.json answers the call!
makeOidcConfig wraps it neat,
three apps updated, oh how sweet.
The rabbit cheers: one schema to rule,
SDK credentials — finally cool! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% 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 'SDKS-5067: Standardize SDK Configuration' directly reflects the main objective of the PR, which is to standardize SDK configuration across three JavaScript applications by migrating from individual environment variables to a unified config.json file structure.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch SDKS-5067

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

javascript/reactjs-todo-journey/client/components/journey/journey.hook.js

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: ESLint configuration in --config is invalid:

  • Unexpected top-level property "__esModule".

    at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2177:19)
    at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3019:19)
    at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2984:21)
    at ConfigArrayFactory.loadFile (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2850:40)
    at createCLIConfigArray (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3660:35)
    at new CascadingConfigArrayFactory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3735:29)
    at new CLIEngine (/node_modules/eslint/lib/cli-engine/cli-engine.js:617:36)
    at new ESLint (/node_modules/eslint/lib/eslint/eslint.js:430:27)
    at Object.execute (/node_modules/eslint/lib/cli.js:410:24)
    at async main (/node_modules/eslint/bin/eslint.js:152:22)

javascript/reactjs-todo-journey/client/constants.js

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: ESLint configuration in --config is invalid:

  • Unexpected top-level property "__esModule".

    at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2177:19)
    at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3019:19)
    at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2984:21)
    at ConfigArrayFactory.loadFile (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2850:40)
    at createCLIConfigArray (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3660:35)
    at new CascadingConfigArrayFactory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3735:29)
    at new CLIEngine (/node_modules/eslint/lib/cli-engine/cli-engine.js:617:36)
    at new ESLint (/node_modules/eslint/lib/eslint/eslint.js:430:27)
    at Object.execute (/node_modules/eslint/lib/cli.js:410:24)
    at async main (/node_modules/eslint/bin/eslint.js:152:22)

javascript/reactjs-todo-journey/client/context/oidc.context.js

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: ESLint configuration in --config is invalid:

  • Unexpected top-level property "__esModule".

    at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2177:19)
    at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3019:19)
    at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2984:21)
    at ConfigArrayFactory.loadFile (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2850:40)
    at createCLIConfigArray (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3660:35)
    at new CascadingConfigArrayFactory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3735:29)
    at new CLIEngine (/node_modules/eslint/lib/cli-engine/cli-engine.js:617:36)
    at new ESLint (/node_modules/eslint/lib/eslint/eslint.js:430:27)
    at Object.execute (/node_modules/eslint/lib/cli.js:410:24)
    at async main (/node_modules/eslint/bin/eslint.js:152:22)

  • 3 others

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 and usage tips.

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

We should update reactjs-todo-login-widget's configuration too

@SteinGabriel SteinGabriel marked this pull request as draft June 11, 2026 23:41
@SteinGabriel SteinGabriel force-pushed the SDKS-5067 branch 5 times, most recently from feffca3 to 363e5dc Compare June 16, 2026 16:38
feat(reactjs-todo-oidc): migrate SDK config to config.json

feat(reactjs-todo-journey): migrate SDK config to config.json

feat(sample-apps): inject SDK config via env var for e2e, fall back to
config.json

fix(reactjs-todo-davinci): migrate fido playwright block to unified
config

fix(reactjs-todo-journey): replace deprecated assert with import
attribute

fix(reactjs-todo-oidc): remove REST_OAUTH vars from env.example, add CI
clarification

docs: update README setup sections to reflect config.json migration

feat(reactjs-todo-davinci): wire make*Config from sdk-utilities

feat(reactjs-todo-oidc): wire makeOidcConfig from sdk-utilities

feat(reactjs-todo-journey): wire make*Config from sdk-utilities

fix(sample-apps): derive redirectUri dynamically from window.location.origin
@SteinGabriel SteinGabriel marked this pull request as ready for review June 16, 2026 18:34
@SteinGabriel

Copy link
Copy Markdown
Contributor Author

We should update reactjs-todo-login-widget's configuration too

The login widget app uses @forgerock/login-widget, with its own configuration().set() API, not the OIDC/Journey/Davinci factory functions this ticket implements. I guess the unified config schema and "make config" utilities don't apply here at the moment. We might need a ticket for implementing this in the login framework repo as well, though.

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

Caution

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

⚠️ Outside diff range comments (1)
javascript/reactjs-todo-davinci/client/context/oidc.context.js (1)

34-63: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Missing json in useEffect dependency array.

The useEffect at line 34 uses the json parameter inside initOidcClient() (line 48) but omits json from the dependency array at line 63. This breaks the React hook contract: if json changes, the OIDC client will not be re-initialized with the new configuration. The reactjs-todo-journey version of this file correctly includes [json, oidcClient].

[major]

🔧 Proposed fix: Add `json` to the dependency array
  }, [oidcClient]);
+ }, [json, oidcClient]);
🤖 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/context/oidc.context.js` around lines
34 - 63, The useEffect hook starting at line 34 uses the json parameter inside
the initOidcClient function when calling makeOidcConfig(json), but json is
missing from the dependency array at line 63. Add json to the dependency array
alongside oidcClient so that when json changes, the OIDC client will be
re-initialized with the new configuration, ensuring the React hook contract is
followed.
🤖 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/constants.js`:
- Line 29: The rawConfig constant assignment does not handle errors when parsing
process.env.SDK_CONFIG, which will cause the entire module to fail loading if
the JSON is malformed. Wrap the JSON.parse call in a try-catch block, and if
parsing throws an error, fall back to using sdkConfigJson as the default value.
This ensures the application can still initialize even when SDK_CONFIG contains
invalid JSON.

In `@javascript/reactjs-todo-davinci/playwright.config.ts`:
- Line 3: The import statement for testFidoConfig is triggering a no-unused-vars
lint error because the variable is only referenced in commented code and not
actively used. Either remove the import statement for testFidoConfig entirely if
it is not needed, or uncomment and properly integrate the code that uses
testFidoConfig so the variable is actively referenced in the configuration.

In `@javascript/reactjs-todo-davinci/README.md`:
- Around line 65-70: The README.md file contains an inconsistency in the
redirect URI configuration examples, showing
https://localhost:8443/callback.html in one location and
http://localhost:8443/callback.html in another. Update the redirect URI in the
OIDC configuration example to use the same protocol (http or https) consistently
throughout the entire README file to prevent configuration errors during user
onboarding.

In `@javascript/reactjs-todo-journey/client/constants.js`:
- Around line 31-33: The JSON parsing of environment variables can cause module
load-time crashes if the JSON is malformed. In
javascript/reactjs-todo-journey/client/constants.js lines 31-33, wrap the
JSON.parse call for import.meta.env.VITE_SDK_CONFIG in a try/catch block and
fallback to sdkConfigJson on parse failure. Apply the same guarded
parse/fallback pattern in javascript/reactjs-todo-oidc/client/constants.js line
28 for process.env.SDK_CONFIG to ensure both modules gracefully handle invalid
JSON without crashing at load time.
- Around line 35-40: The CONFIG object in both files unconditionally overwrites
the redirectUri property, ignoring any pre-configured value from rawConfig. In
javascript/reactjs-todo-journey/client/constants.js at lines 35-40, modify the
oidc.redirectUri assignment to conditionally use the value from
rawConfig.oidc.redirectUri when it exists, falling back to the
window.location.origin-based URL only when it is missing or undefined. Apply the
identical conditional fallback pattern to
javascript/reactjs-todo-oidc/client/constants.js at lines 30-35 so that any
configured redirect URI in rawConfig is preserved instead of being clobbered.

In `@javascript/reactjs-todo-journey/vite.config.js`:
- Line 44: The current code uses new URL(...).pathname to construct a file path
for the config.json file, which is unreliable on Windows and other platforms due
to leading slashes and unencoded characters. Import the fileURLToPath function
from the built-in url module and replace the pathname-based approach in the
optionalConfigJson call with fileURLToPath(new URL('./config.json',
import.meta.url)) to ensure the path works correctly across all platforms when
checked by existsSync.

---

Outside diff comments:
In `@javascript/reactjs-todo-davinci/client/context/oidc.context.js`:
- Around line 34-63: The useEffect hook starting at line 34 uses the json
parameter inside the initOidcClient function when calling makeOidcConfig(json),
but json is missing from the dependency array at line 63. Add json to the
dependency array alongside oidcClient so that when json changes, the OIDC client
will be re-initialized with the new configuration, ensuring the React hook
contract is followed.
🪄 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

Run ID: 809bdce5-7376-4f24-8136-1a1fa2a83af3

📥 Commits

Reviewing files that changed from the base of the PR and between 6cac3c2 and 93a2e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (36)
  • javascript/reactjs-todo-davinci/.env.example
  • javascript/reactjs-todo-davinci/.gitignore
  • javascript/reactjs-todo-davinci/README.md
  • javascript/reactjs-todo-davinci/client/components/davinci-client/hooks/create-client.utils.js
  • javascript/reactjs-todo-davinci/client/constants.js
  • javascript/reactjs-todo-davinci/client/context/oidc.context.js
  • javascript/reactjs-todo-davinci/config.example.json
  • javascript/reactjs-todo-davinci/config.test.fido.json
  • javascript/reactjs-todo-davinci/config.test.json
  • javascript/reactjs-todo-davinci/package.json
  • javascript/reactjs-todo-davinci/playwright.config.ts
  • javascript/reactjs-todo-davinci/webpack.config.js
  • javascript/reactjs-todo-journey/.env.example
  • javascript/reactjs-todo-journey/.gitignore
  • javascript/reactjs-todo-journey/README.md
  • javascript/reactjs-todo-journey/client/components/journey/journey.hook.js
  • javascript/reactjs-todo-journey/client/constants.js
  • javascript/reactjs-todo-journey/client/context/oidc.context.js
  • javascript/reactjs-todo-journey/config.example.json
  • javascript/reactjs-todo-journey/config.test.json
  • javascript/reactjs-todo-journey/e2e/embedded-login.spec.js
  • javascript/reactjs-todo-journey/package.json
  • javascript/reactjs-todo-journey/playwright.config.js
  • javascript/reactjs-todo-journey/vite.config.js
  • javascript/reactjs-todo-oidc/.env.example
  • javascript/reactjs-todo-oidc/.gitignore
  • javascript/reactjs-todo-oidc/README.md
  • javascript/reactjs-todo-oidc/client/README.md
  • javascript/reactjs-todo-oidc/client/constants.js
  • javascript/reactjs-todo-oidc/client/context/oidc.context.js
  • javascript/reactjs-todo-oidc/config.example.json
  • javascript/reactjs-todo-oidc/config.test.pingam.json
  • javascript/reactjs-todo-oidc/config.test.pingone.json
  • javascript/reactjs-todo-oidc/package.json
  • javascript/reactjs-todo-oidc/playwright.config.ts
  • javascript/reactjs-todo-oidc/webpack.config.js

* PingOne environment, used to resolve authorization/token endpoints
*************************************************************************** */

const rawConfig = process.env.SDK_CONFIG ? JSON.parse(process.env.SDK_CONFIG) : sdkConfigJson;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard SDK_CONFIG parsing to prevent startup-time crashes.

Line 29 parses process.env.SDK_CONFIG without error handling; malformed JSON will throw during module load and hard-fail app initialization.

Proposed fix
-import sdkConfigJson from '../config.json';
+import sdkConfigJson from '../config.json';
@@
-const rawConfig = process.env.SDK_CONFIG ? JSON.parse(process.env.SDK_CONFIG) : sdkConfigJson;
+const rawConfig = (() => {
+  if (!process.env.SDK_CONFIG) return sdkConfigJson;
+  try {
+    return JSON.parse(process.env.SDK_CONFIG);
+  } catch (error) {
+    throw new Error(`Invalid SDK_CONFIG JSON: ${error.message}`);
+  }
+})();
🤖 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/constants.js` at line 29, The
rawConfig constant assignment does not handle errors when parsing
process.env.SDK_CONFIG, which will cause the entire module to fail loading if
the JSON is malformed. Wrap the JSON.parse call in a try-catch block, and if
parsing throws an error, fall back to using sdkConfigJson as the default value.
This ensures the application can still initialize even when SDK_CONFIG contains
invalid JSON.

@@ -1,4 +1,6 @@
import { defineConfig, devices } from '@playwright/test';
import testConfig from './config.test.json';
import testFidoConfig from './config.test.fido.json';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove or use testFidoConfig to fix the lint error.

testFidoConfig is currently unused because the only reference is inside commented code, which triggers no-unused-vars.

💡 Suggested fix
 import { defineConfig, devices } from '`@playwright/test`';
 import testConfig from './config.test.json';
-import testFidoConfig from './config.test.fido.json';
📝 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
import testFidoConfig from './config.test.fido.json';
import { defineConfig, devices } from '`@playwright/test`';
import testConfig from './config.test.json';
🧰 Tools
🪛 ESLint

[error] 3-3: 'testFidoConfig' is defined but never used.

(no-unused-vars)

🤖 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/playwright.config.ts` at line 3, The import
statement for testFidoConfig is triggering a no-unused-vars lint error because
the variable is only referenced in commented code and not actively used. Either
remove the import statement for testFidoConfig entirely if it is not needed, or
uncomment and properly integrate the code that uses testFidoConfig so the
variable is actively referenced in the configuration.

Source: Linters/SAST tools

Comment on lines +65 to +70
"oidc": {
"clientId": "<your-oauth-client-id>",
"discoveryEndpoint": "https://<your-domain>/.well-known/openid-configuration",
"scopes": ["openid", "profile", "email"],
"redirectUri": "https://localhost:8443/callback.html"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix redirect URI protocol mismatch in setup instructions.

Line 69 shows https://localhost:8443/callback.html, but the same README config/setup path uses http://localhost:8443/callback.html (Line 41). Align these to one value to avoid misconfiguration during onboarding.

🤖 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/README.md` around lines 65 - 70, The
README.md file contains an inconsistency in the redirect URI configuration
examples, showing https://localhost:8443/callback.html in one location and
http://localhost:8443/callback.html in another. Update the redirect URI in the
OIDC configuration example to use the same protocol (http or https) consistently
throughout the entire README file to prevent configuration errors during user
onboarding.

Comment on lines +31 to +33
const rawConfig = import.meta.env.VITE_SDK_CONFIG
? JSON.parse(import.meta.env.VITE_SDK_CONFIG)
: sdkConfigJson;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Both constants modules can hard-crash on malformed SDK_CONFIG JSON due to unguarded parse at module load.

  • javascript/reactjs-todo-journey/client/constants.js#L31-L33: wrap env JSON parsing in try/catch and fallback to sdkConfigJson on parse failure.
  • javascript/reactjs-todo-oidc/client/constants.js#L28-L28: apply the same guarded parse/fallback pattern for process.env.SDK_CONFIG.
📍 Affects 2 files
  • javascript/reactjs-todo-journey/client/constants.js#L31-L33 (this comment)
  • javascript/reactjs-todo-oidc/client/constants.js#L28-L28
🤖 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-journey/client/constants.js` around lines 31 - 33,
The JSON parsing of environment variables can cause module load-time crashes if
the JSON is malformed. In javascript/reactjs-todo-journey/client/constants.js
lines 31-33, wrap the JSON.parse call for import.meta.env.VITE_SDK_CONFIG in a
try/catch block and fallback to sdkConfigJson on parse failure. Apply the same
guarded parse/fallback pattern in
javascript/reactjs-todo-oidc/client/constants.js line 28 for
process.env.SDK_CONFIG to ensure both modules gracefully handle invalid JSON
without crashing at load time.

Comment on lines 35 to 40
export const CONFIG = {
clientId: WEB_OAUTH_CLIENT,
redirectUri: `${window.location.origin}/callback.html`,
scope: SCOPE,
serverConfig: {
wellknown: WELLKNOWN_URL,
...rawConfig,
oidc: {
...rawConfig.oidc,
redirectUri: `${window.location.origin}/callback.html`,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

The unified config’s oidc.redirectUri is ignored in both apps because it is always overwritten.

  • javascript/reactjs-todo-journey/client/constants.js#L35-L40: preserve rawConfig.oidc.redirectUri when present, and only fallback to ${window.location.origin}/callback.html when missing.
  • javascript/reactjs-todo-oidc/client/constants.js#L30-L35: apply the same conditional fallback to avoid clobbering configured redirect URIs.
📍 Affects 2 files
  • javascript/reactjs-todo-journey/client/constants.js#L35-L40 (this comment)
  • javascript/reactjs-todo-oidc/client/constants.js#L30-L35
🤖 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-journey/client/constants.js` around lines 35 - 40,
The CONFIG object in both files unconditionally overwrites the redirectUri
property, ignoring any pre-configured value from rawConfig. In
javascript/reactjs-todo-journey/client/constants.js at lines 35-40, modify the
oidc.redirectUri assignment to conditionally use the value from
rawConfig.oidc.redirectUri when it exists, falling back to the
window.location.origin-based URL only when it is missing or undefined. Apply the
identical conditional fallback pattern to
javascript/reactjs-todo-oidc/client/constants.js at lines 30-35 so that any
configured redirect URI in rawConfig is preserved instead of being clobbered.

strictPort: true,
},
plugins: [react()],
plugins: [react(), optionalConfigJson(new URL('./config.json', import.meta.url).pathname)],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the vite.config.js file
fd -t f "vite.config.js"

Repository: ForgeRock/sdk-sample-apps

Length of output: 177


🏁 Script executed:

# Read the vite.config.js file to see the full context
cat -n javascript/reactjs-todo-journey/vite.config.js

Repository: ForgeRock/sdk-sample-apps

Length of output: 1852


🏁 Script executed:

# Search for the optionalConfigJson function definition
rg -n "optionalConfigJson" --type js

Repository: ForgeRock/sdk-sample-apps

Length of output: 306


🌐 Web query:

fileURLToPath vs URL.pathname Node.js filesystem Windows

💡 Result:

You should always use fileURLToPath instead of URL.pathname when converting a file URL to a file system path in Node.js, particularly for cross-platform compatibility [1][2][3]. Using URL.pathname directly on Windows is problematic and will lead to errors because it treats the URL as a generic URI rather than a native file system path [4][5][3]. Specifically: 1. Incorrect Path Formatting: On Windows, a file URL like file:///C:/path/results in a pathname of /C:/path/ [1][2][3]. This leading slash causes Windows file system APIs to interpret the path as being relative to the current drive, often resulting in invalid paths like C:\C:\path\ [1][3]. 2. Lack of Decoding: URL.pathname does not correctly decode percent-encoded characters [2][6]. Characters like spaces (%20) or non-ASCII characters remain encoded, which prevents native file system modules (like fs) from locating the files correctly [5][2]. 3. Handling of UNC Paths: URL.pathname fails to correctly represent Windows UNC paths (e.g., file://nas/share), stripping important host information that fileURLToPath preserves as \nas\share [2][6]. In contrast, fileURLToPath from the node:url module is designed to handle these platform-specific differences [2][7]. It ensures that the output is a correctly formatted, absolute path string for the host operating system, handles percent-decoding, and correctly manages drive letters and UNC paths [2][7][6]. Whenever you need to convert an import.meta.url or other file URL into a path for operations like fs.readFileSync, use the following pattern: import { fileURLToPath } from 'node:url'; const filePath = fileURLToPath(import.meta.url);

Citations:


🏁 Script executed:

# Check if there are other instances of this pattern in the codebase
rg "new URL.*import.meta.url.*pathname" --type js

Repository: ForgeRock/sdk-sample-apps

Length of output: 212


Use fileURLToPath for the config file path check.

Passing new URL(...).pathname into existsSync is unreliable on Windows and other platforms. On Windows, URL.pathname adds a leading slash that produces invalid paths (e.g., /C:/path), and it fails to decode percent-encoded characters. This causes existsSync to incorrectly return false even when the file exists, forcing the empty virtual module fallback.

💡 Suggested fix
 import { defineConfig, loadEnv } from 'vite';
 import react from '`@vitejs/plugin-react`';
 import { existsSync } from 'fs';
+import { fileURLToPath } from 'url';
@@
 export default defineConfig(({ mode }) => {
   const env = loadEnv(mode, process.cwd(), '');
   const PORT = parseInt(env.VITE_PORT) || 8443;
+  const configJsonPath = fileURLToPath(new URL('./config.json', import.meta.url));
@@
-    plugins: [react(), optionalConfigJson(new URL('./config.json', import.meta.url).pathname)],
+    plugins: [react(), optionalConfigJson(configJsonPath)],
🤖 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-journey/vite.config.js` at line 44, The current code
uses new URL(...).pathname to construct a file path for the config.json file,
which is unreliable on Windows and other platforms due to leading slashes and
unencoded characters. Import the fileURLToPath function from the built-in url
module and replace the pathname-based approach in the optionalConfigJson call
with fileURLToPath(new URL('./config.json', import.meta.url)) to ensure the path
works correctly across all platforms when checked by existsSync.

@vatsalparikh

Copy link
Copy Markdown
Contributor

We should update reactjs-todo-login-widget's configuration too

The login widget app uses @forgerock/login-widget, with its own configuration().set() API, not the OIDC/Journey/Davinci factory functions this ticket implements. I guess the unified config schema and "make config" utilities don't apply here at the moment. We might need a ticket for implementing this in the login framework repo as well, though.

You're right, my bad. Login widget is unrelated here.

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.

2 participants