Skip to content

Conversation

@ryanbas21
Copy link
Collaborator

@ryanbas21 ryanbas21 commented Oct 21, 2025

JIRA Ticket

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

Description

migrate old mock api to repo

Summary by CodeRabbit

Release Notes

  • New Features

    • Added mock authentication API server for testing end-to-end authentication workflows.
  • Tests

    • Enhanced test suite configuration and updated authentication flow tests with new journey parameters.
    • Updated test environment setup and credential management.
  • Chores

    • Updated Node version requirement from 24 to 22.
    • Added development dependency for enhanced Express integration.

@changeset-bot
Copy link

changeset-bot bot commented Oct 21, 2025

⚠️ No Changeset found

Latest commit: 5dd2420

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Oct 21, 2025

Walkthrough

A new end-to-end mock API service is introduced for authentication testing, configured within the monorepo using Nx. Updates are made to existing test suites to use the mock API, journey configuration is normalized to handle baseUrl trailing slashes, and test credentials are changed to reference local mock instances instead of ForgeBlocks infrastructure.

Changes

Cohort / File(s) Summary
am-mock-api configuration
e2e/am-mock-api/.babelrc, e2e/am-mock-api/.eslintrc.json, e2e/am-mock-api/package.json, e2e/am-mock-api/project.json, e2e/am-mock-api/tsconfig.json, e2e/am-mock-api/tsconfig.app.json, e2e/am-mock-api/tsconfig.spec.json
New configuration files for the am-mock-api Nx project, including Babel, ESLint, package manifest, build targets, and TypeScript configurations with support for both app and test compilation.
am-mock-api source implementation
e2e/am-mock-api/src/app/app.auth.js, e2e/am-mock-api/src/app/constants.js, e2e/am-mock-api/src/app/env.config.js, e2e/am-mock-api/src/app/response.registration.js, e2e/am-mock-api/src/app/responses.js, e2e/am-mock-api/src/app/routes.auth.js, e2e/am-mock-api/src/app/routes.resource.js, e2e/am-mock-api/src/app/wait.js, e2e/am-mock-api/src/index.js
Core Express mock API implementation providing OAuth, OIDC, and step-up authentication flows. Includes authentication routes, resource endpoints with authorization, mock response payloads for various callback types, environment configuration, and a middleware for delay simulation.
am-mock-api environment configs
e2e/am-mock-api/src/environments/environment.ts, e2e/am-mock-api/src/environments/environment.prod.ts
TypeScript environment exports for development and production modes with AM URL, realm paths, OAuth client configuration, and journey names.
Root-level monorepo updates
package.json, tsconfig.json, .node-version
Added @nx/express dev dependency, updated watch script to use Nx Vite integration, added am-mock-api project reference to TypeScript config, and downgraded Node.js version from 24 to 22.
journey-app configuration
e2e/journey-app/main.ts, e2e/journey-app/server-configs.ts
Updated journey name parameterization to derive from URL query parameter, refactored server configuration to include localhost-based mock server alongside existing ForgeBlocks endpoint.
playwright test orchestration
e2e/journey-suites/playwright.config.ts
Added am-mock-api as a web server dependency in test configuration on port 9443, alongside the existing journey-app server.
journey test updates
e2e/journey-suites/src/choice-confirm-poll.test.ts, e2e/journey-suites/src/custom-paths.test.ts, e2e/journey-suites/src/email-suspend.test.ts, e2e/journey-suites/src/login.test.ts, e2e/journey-suites/src/otp-register.test.ts, e2e/journey-suites/src/registration.test.ts
Appended &clientId=tenant parameter to test navigation URLs for journey routing consistency.
test credentials
e2e/journey-suites/src/utils/demo-user.ts
Changed username from 'demouser' to 'sdkuser' and password from complex string to 'password' to align with mock API credentials.
davinci test enhancement
e2e/davinci-suites/src/phone-number-field.test.ts
Added visibility assertion for "SMS/Voice MFA Registered" message after phone number submission.
journey-client normalization
packages/journey-client/src/lib/client.store.ts, packages/journey-client/src/lib/client.store.test.ts
Introduced baseUrl normalization to ensure serverConfig.baseUrl always ends with a trailing slash. Added test cases validating normalization with and without context paths.

Sequence Diagram(s)

sequenceDiagram
    participant Test as e2e Test
    participant JourneyApp as Journey App
    participant MockAPI as am-mock-api
    participant RealAM as Real AM (LIVE)

    alt LIVE Mode
        Test->>JourneyApp: Navigate with clientId=tenant
        JourneyApp->>MockAPI: POST /authenticate
        MockAPI->>MockAPI: authorizeApp() - fetch AM token
        MockAPI->>RealAM: POST /authenticate (with token)
        RealAM-->>MockAPI: Session token
        MockAPI-->>JourneyApp: Auth response
    else Non-LIVE (Mock) Mode
        Test->>JourneyApp: Navigate with clientId=tenant
        JourneyApp->>MockAPI: POST /authenticate
        MockAPI->>MockAPI: Match authIndexValue & callbacks
        MockAPI-->>JourneyApp: Mock response (e.g., initialBasicLogin)
    end
    
    JourneyApp->>MockAPI: POST /tokenExchange
    MockAPI-->>JourneyApp: OAuth tokens

    alt Authorization Required
        JourneyApp->>MockAPI: GET /resource/ig/authz-by-txn
        MockAPI->>MockAPI: Check auth header/cookie
        alt Authorization Success
            MockAPI-->>JourneyApp: Resource access
        else Authorization Needed
            MockAPI-->>JourneyApp: 307 redirect with step-up URL
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • High-density authentication logic: Routes in routes.auth.js and routes.resource.js contain extensive conditional branching across ~20 different endpoints with multiple auth flows (OAuth, OIDC, SAML, step-up), callback handling, and middleware variants.
  • Large mock response library: responses.js defines 40+ exported constants with complex nested structures for various authentication scenarios; requires validation that payloads match expected AM/OIDC formats.
  • Cross-cutting configuration: Environment and path configuration flows affect multiple endpoints; changes to env.config.js or constants.js propagate throughout mock API.
  • Repetitive but scattered test updates: Query parameter additions across 6 test files follow the same pattern but are distributed across multiple suites.
  • Integration complexity: Mock API integrates with real AM in LIVE mode and must correctly simulate real auth flows in non-LIVE mode; requires understanding of both paths.

Areas requiring extra attention during review:

  • Authentication flow branching logic in routes.auth.js POST /authenticate handler—verify all authIndexValue variants and callback sequences return appropriate mock responses
  • Authorization middleware in routes.resource.js—confirm FORGEOPS mode bypassing and token validation logic
  • Step-up URL construction in responses.js—verify advice embedding and URL format compatibility with client expectations
  • baseUrl normalization in client.store.ts—ensure trailing slash addition doesn't break URLs with trailing paths
  • Mock response payloads—validate structure matches latest AM/OIDC callback format specifications
  • Playwright server configuration in playwright.config.ts—confirm am-mock-api port 9443 doesn't conflict with existing services

Suggested reviewers

  • cerebrl
  • spetrov

Poem

🐰 A mock API hops into the test suite,
With OAuth flows and OIDC to boot,
Step-ups and redirects in every state,
Now e2e testing is truly first-rate! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: migrate-old-mock-api' directly aligns with the main change of migrating the old mock API into the repository, though the hyphenation style is unconventional.
Description check ✅ Passed The description includes the JIRA ticket link and a brief summary of the migration, but lacks implementation details about the mock API structure, configuration, or testing approach.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch migrate-am-mock-api

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc3da80 and 5dd2420.

📒 Files selected for processing (8)
  • e2e/davinci-suites/src/phone-number-field.test.ts (1 hunks)
  • e2e/journey-app/main.ts (3 hunks)
  • e2e/journey-suites/src/choice-confirm-poll.test.ts (2 hunks)
  • e2e/journey-suites/src/custom-paths.test.ts (1 hunks)
  • e2e/journey-suites/src/email-suspend.test.ts (1 hunks)
  • e2e/journey-suites/src/login.test.ts (1 hunks)
  • e2e/journey-suites/src/otp-register.test.ts (1 hunks)
  • e2e/journey-suites/src/registration.test.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • e2e/journey-suites/src/email-suspend.test.ts
  • e2e/journey-suites/src/custom-paths.test.ts
  • e2e/journey-suites/src/registration.test.ts
  • e2e/journey-suites/src/choice-confirm-poll.test.ts
  • e2e/journey-suites/src/login.test.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: cerebrl
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: e2e/journey-app/main.ts:83-87
Timestamp: 2025-10-27T17:55:33.855Z
Learning: In the e2e/journey-app and similar e2e test applications in this repository, XSS hardening and similar production security practices are not required since these are exclusively test/development applications.
🧬 Code graph analysis (1)
e2e/journey-app/main.ts (1)
packages/journey-client/src/lib/client.store.ts (1)
  • journey (45-194)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: pr
🔇 Additional comments (4)
e2e/journey-app/main.ts (2)

21-21: LGTM! Clean extraction of journey name.

Extracting the journey name from URL parameters with a sensible default improves code maintainability and ensures consistency throughout the authentication flow.


58-58: LGTM! Consistent journey name usage.

Using the extracted journeyName variable for both the initial start and post-logout restart ensures consistency throughout the authentication lifecycle and provides a single source of truth.

Also applies to: 82-82

e2e/journey-suites/src/otp-register.test.ts (2)

14-14: LGTM! Consistent tenant scoping.

The addition of the clientId=tenant parameter aligns with the mock API migration and is consistent with similar updates across other test files in the journey-suites.


38-44: Remove this TODO comment as it's based on incorrect assumptions.

The commented assertions don't fail due to mock API unavailability—they fail because the application code doesn't log the OTP authentication URI and success message to the console. The QRCode utility extracts this data from mock API callbacks but doesn't emit it to console, and no logging statements exist in the davinci-app for these specific values. Simply migrating the mock API won't enable these assertions; the application itself needs code changes to log these messages.

Likely an incorrect or invalid review comment.


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.

@ryanbas21 ryanbas21 force-pushed the migrate-am-mock-api branch from fde9406 to 9116a55 Compare October 21, 2025 18:23
@nx-cloud
Copy link
Contributor

nx-cloud bot commented Oct 21, 2025

View your CI Pipeline Execution ↗ for commit 5dd2420

Command Status Duration Result
nx run-many -t build --no-agents ✅ Succeeded <1s View ↗
nx affected -t build lint test e2e-ci ✅ Succeeded 1m 11s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-13 16:17:20 UTC

nx-cloud[bot]

This comment was marked as outdated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 22

🧹 Nitpick comments (2)
e2e/am-mock-api/.eslintrc.json (1)

17-28: Consider simplifying the overrides configuration.

The configuration has three separate override blocks for file patterns, but all have empty rules. Since they inherit from the base config, you could consolidate them into a single override.

Apply this diff to simplify:

   {
-    "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
-    "rules": {}
-  },
-  {
-    "files": ["*.ts", "*.tsx"],
-    "rules": {}
-  },
-  {
-    "files": ["*.js", "*.jsx"],
+    "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
     "rules": {}
   }
e2e/am-mock-api/src/app/responses.js (1)

70-76: Defensive URL handling in helpers (Tree URL/header and Txn header).

Mirror the same fallback to avoid crashes when Referer is absent.

Apply this diff:

 export const createTreeStepUpUrl = (url) => {
   // Grab the client's desired AM URL
-  const referer = new URL(url);
-  const amUrl = referer.searchParams.get('amUrl');
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
+  const amUrl = referer.searchParams.get('amUrl');
@@
 export const createTxnStepUpHeader = (url) => {
   // Grab the client's desired AM URL
-  const referer = new URL(url);
-  const amUrl = referer.searchParams.get('amUrl') || AM_URL;
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
+  const amUrl = referer.searchParams.get('amUrl') || AM_URL;
@@
 export const createTreeStepUpHeader = (url) => {
   // Grab the client's desired AM URL
-  const referer = new URL(url);
-  const amUrl = referer.searchParams.get('amUrl') || AM_URL;
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
+  const amUrl = referer.searchParams.get('amUrl') || AM_URL;

Also applies to: 88-99, 101-112

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b110df and 9116a55.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • e2e/am-mock-api/.babelrc (1 hunks)
  • e2e/am-mock-api/.eslintrc.json (1 hunks)
  • e2e/am-mock-api/package.json (1 hunks)
  • e2e/am-mock-api/project.json (1 hunks)
  • e2e/am-mock-api/src/app/app.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/constants.js (1 hunks)
  • e2e/am-mock-api/src/app/env.config.js (1 hunks)
  • e2e/am-mock-api/src/app/response.registration.js (1 hunks)
  • e2e/am-mock-api/src/app/responses.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.resource.js (1 hunks)
  • e2e/am-mock-api/src/app/wait.js (1 hunks)
  • e2e/am-mock-api/src/environments/environment.prod.ts (1 hunks)
  • e2e/am-mock-api/src/environments/environment.ts (1 hunks)
  • e2e/am-mock-api/src/index.js (1 hunks)
  • e2e/am-mock-api/tsconfig.app.json (1 hunks)
  • e2e/am-mock-api/tsconfig.json (1 hunks)
  • e2e/am-mock-api/tsconfig.spec.json (1 hunks)
  • package.json (2 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
e2e/am-mock-api/src/index.js (2)
e2e/am-mock-api/src/app/app.auth.js (1)
  • authorizeApp (16-36)
e2e/am-mock-api/src/app/env.config.js (2)
  • MOCK_PORT (62-62)
  • MOCK_PORT (62-62)
e2e/am-mock-api/src/app/app.auth.js (3)
e2e/am-mock-api/src/app/routes.resource.js (2)
  • response (47-55)
  • response (70-70)
e2e/am-mock-api/src/app/env.config.js (4)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
e2e/am-mock-api/src/app/routes.auth.js (2)
  • un (258-258)
  • pw (266-266)
e2e/am-mock-api/src/app/routes.resource.js (5)
e2e/am-mock-api/src/app/env.config.js (8)
  • FORGEOPS (67-67)
  • FORGEOPS (67-67)
  • AM_PORT (61-61)
  • AM_PORT (61-61)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/app.auth.js (3)
  • response (18-24)
  • session (14-14)
  • session (14-14)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/routes.auth.js (2)
  • baz (57-59)
  • baz (57-59)
e2e/am-mock-api/src/app/responses.js (12)
  • authByTxnResponse (124-132)
  • authByTxnResponse (124-132)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpUrl (51-68)
  • createTxnStepUpUrl (51-68)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpUrl (70-86)
  • createTreeStepUpUrl (70-86)
  • authByTreeResponse (114-122)
  • authByTreeResponse (114-122)
e2e/am-mock-api/src/app/env.config.js (1)
e2e/am-mock-api/src/app/responses.js (6)
  • realm (96-96)
  • realm (109-109)
  • amUrl (55-55)
  • amUrl (73-73)
  • amUrl (91-91)
  • amUrl (104-104)
e2e/am-mock-api/src/environments/environment.prod.ts (1)
e2e/am-mock-api/src/environments/environment.ts (1)
  • environment (1-9)
e2e/am-mock-api/src/environments/environment.ts (1)
e2e/am-mock-api/src/environments/environment.prod.ts (1)
  • environment (1-3)
e2e/am-mock-api/src/app/routes.auth.js (4)
e2e/am-mock-api/src/app/env.config.js (4)
  • USERS (71-71)
  • USERS (71-71)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/constants.js (2)
  • authPaths (11-66)
  • authPaths (11-66)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/responses.js (38)
  • authSuccess (45-49)
  • authSuccess (45-49)
  • pingProtectInitialize (313-368)
  • pingProtectInitialize (313-368)
  • MetadataMarketPlaceInitialize (1205-1250)
  • MetadataMarketPlaceInitialize (1205-1250)
  • initialBasicLogin (198-215)
  • initialBasicLogin (198-215)
  • recaptchaEnterpriseCallback (1310-1349)
  • recaptchaEnterpriseCallback (1310-1349)
  • authFail (40-43)
  • authFail (40-43)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • otpQRCodeCallbacks (500-584)
  • otpQRCodeCallbacks (500-584)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackSaml (604-621)
  • redirectCallbackSaml (604-621)
  • redirectCallback (586-603)
  • redirectCallback (586-603)
  • pingProtectEvaluate (288-311)
  • pingProtectEvaluate (288-311)
  • requestDeviceProfile (673-700)
  • requestDeviceProfile (673-700)
  • noSessionSuccess (424-424)
  • noSessionSuccess (424-424)
  • oauthTokens (13-20)
  • oauthTokens (13-20)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpired (31-38)
  • oauthTokensExpired (31-38)
  • redirectUrl (57-57)
  • redirectUrl (75-75)
  • userInfo (665-671)
  • userInfo (665-671)
e2e/am-mock-api/src/app/responses.js (2)
e2e/am-mock-api/src/app/routes.auth.js (5)
  • url (547-547)
  • redirectUrl (453-455)
  • redirectUrl (461-463)
  • redirectUrl (470-472)
  • redirectUrl (513-513)
e2e/am-mock-api/src/app/env.config.js (6)
  • amUrl (49-49)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • RESOURCE_URL (69-69)
  • RESOURCE_URL (69-69)
  • realm (36-36)
🪛 Biome (2.1.2)
e2e/am-mock-api/src/app/response.registration.js

[error] 10-224: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/index.js

[error] 9-10: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 11-12: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 12-13: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 13-14: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 14-15: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 15-16: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 16-17: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 17-18: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 18-19: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 19-20: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/app.auth.js

[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 11-12: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 13-14: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 15-36: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/routes.resource.js

[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 11-12: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 12-13: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 13-14: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 14-22: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 22-23: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 23-24: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 63-191: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/env.config.js

[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 59-60: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 60-61: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 61-62: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 63-64: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 64-65: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 65-66: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 66-67: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 67-68: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 68-69: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 69-70: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 70-71: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/constants.js

[error] 10-66: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/wait.js

[error] 12-15: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/routes.auth.js

[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 11-12: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 12-13: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 13-51: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 51-52: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 52-53: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 56-59: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 60-644: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

e2e/am-mock-api/src/app/responses.js

[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)


[error] 12-20: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 21-29: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 30-38: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 39-43: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 44-49: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 50-68: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 69-86: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 87-99: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 100-112: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 113-122: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 123-132: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 133-150: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 151-165: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 165-176: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 176-196: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 197-215: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 216-234: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 235-264: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 265-275: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 276-286: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 287-311: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 312-368: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 369-383: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 384-398: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 399-422: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 423-424: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 425-437: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 438-485: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 486-498: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 499-584: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 585-603: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 603-621: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 621-639: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 639-651: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 651-663: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 664-671: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 672-700: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 701-1033: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 1035-1122: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 1123-1203: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 1204-1250: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 1251-1308: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)


[error] 1309-1349: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: pr
🔇 Additional comments (9)
e2e/am-mock-api/.babelrc (1)

1-3: LGTM!

Standard Nx Babel configuration with appropriate preset and polyfill strategy.

package.json (1)

65-65: LGTM!

Addition of @nx/express aligns with the new e2e mock API project and maintains version consistency with other Nx dependencies at 21.2.3.

tsconfig.json (1)

73-75: LGTM!

The project reference correctly integrates the new e2e/am-mock-api into the TypeScript build configuration.

e2e/am-mock-api/tsconfig.spec.json (1)

1-9: LGTM!

Standard test configuration with appropriate module format and file inclusion patterns.

e2e/am-mock-api/src/app/response.registration.js (1)

11-224: LGTM: Comprehensive registration flow mock data.

The mock response structure provides thorough coverage of the registration flow with various callback types (username validation, password policies, KBA, terms and conditions, etc.). This will enable robust e2e testing.

e2e/am-mock-api/tsconfig.json (1)

1-13: LGTM: Standard TypeScript project reference configuration.

The composite project structure correctly delegates to app and spec configurations.

e2e/am-mock-api/src/app/constants.js (1)

11-66: LGTM: Well-organized authentication path configuration.

The authPaths object provides a clear categorization of authentication endpoints across different realms and variants, which will facilitate consistent routing in the mock API.

e2e/am-mock-api/tsconfig.app.json (1)

4-4: Verify intended output directory configuration before applying changes.

The outDir mismatch between tsconfig.app.json ("../../dist/out-tsc") and project.json ("e2e/am-mock-api/dist") exists, but this pattern is already present in other e2e projects (protect-app, davinci-app). Before proceeding with the suggested fix, confirm:

  1. Whether Nx's @nx/js:tsc executor respects project.json outputPath as authoritative or if tsconfig.app.json outDir takes precedence
  2. Whether this inconsistency is intentional or a widespread issue across the workspace
  3. Whether the current build configuration works as expected

If the current setup is verified as working, no change is needed. If changes are required, align all e2e projects' output configurations consistently.

e2e/am-mock-api/src/app/routes.resource.js (1)

159-170: Case mismatch fix is correct, but suggested solution is wrong—isLive does not exist.

The case mismatch at line 160 is a real bug: env.NODE_ENV === 'live' should match the uppercase 'LIVE' used everywhere else (lines 27, 43, 67, etc.). However, the variable isLive does not exist in the codebase and cannot be used.

Correct fix:

-  if (env.NODE_ENV === 'live') {
+  if (env.NODE_ENV === 'LIVE') {

Likely an incorrect or invalid review comment.

import request from 'superagent';
import { AM_URL, REALM_PATH } from './env.config.js';

export let session;
Copy link

@coderabbitai coderabbitai bot Oct 21, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid mutable module-level state.

Exporting a mutable session variable that gets modified in authorizeApp can lead to race conditions if multiple authorization attempts occur, and makes the module harder to test. Consider returning the session from the function and letting the caller manage state.

Refactor to avoid shared mutable state:

-export let session;
-
 export async function authorizeApp({ un, pw }) {
   try {
     const response = await request
       .post(`${AM_URL}/json/realms/${REALM_PATH}/authenticate`)
       .set('Content-Type', 'application/json')
       .set('Accept-API-Version', 'resource=2.0, protocol=1.0')
       .set('X-OpenAM-Username', un)
       .set('X-OpenAM-Password', pw)
       .send({});
 
-    session = response.body;
+    const session = response.body;
 
     console.log(`REST app identity token: ${session.tokenId}`);
 
     return session;
   } catch (error) {

Then update callers to store the returned session locally.

🧰 Tools
🪛 Biome (2.1.2)

[error] 13-14: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/app.auth.js around line 14, the module currently
exports a mutable top-level variable "session" which is set by authorizeApp;
refactor authorizeApp to return the session object instead of mutating exported
state and remove the exported mutable variable. Update all callers to accept and
store the returned session locally (or pass it through callers) so state is
owned by the caller and not shared across the module, and remove any direct
imports/assignments to the old exported "session". Ensure tests and call sites
are updated accordingly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

where is this exported session used that moving into the module won't break it?

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Search for imports of 'session' from app.auth.js
echo "=== Searching for imports of 'session' from app.auth ==="
rg -n -C3 "import.*session.*from.*app\.auth" e2e/am-mock-api/

echo ""
echo "=== Searching for any imports from app.auth.js ==="
rg -n -C3 "from ['\"].*app\.auth" e2e/am-mock-api/

echo ""
echo "=== Searching for direct references to 'session' in am-mock-api ==="
rg -n -C3 "\bsession\b" e2e/am-mock-api/src/ --type js

echo ""
echo "=== Checking index.js for potential usage ==="
cat e2e/am-mock-api/src/index.js

Length of output: 7601


@ryanbas21, the exported session variable is imported and used in e2e/am-mock-api/src/app/routes.resource.js at line 13:

import { session } from './app.auth.js';

It's then accessed in three places within that file to set authentication headers when making requests to the AM service:

  1. Line 54 - in the authorization middleware: .set('iPlanetDirectoryPro', session.tokenId)
  2. Line 77 - for OAuth introspect validation: .set('iPlanetDirectoryPro', session.tokenId)
  3. Line 85 - for session validation: .set('iPlanetDirectoryPro', session.tokenId)

The current flow works like this:

  1. index.js calls authorizeApp() (without awaiting it) when NODE_ENV === 'LIVE'
  2. authorizeApp() sets the module-level session variable
  3. Later, when routes in routes.resource.js are hit, they access session.tokenId from the shared module state

To refactor this without breaking it, you would need to:

  1. Make index.js await authorizeApp() and store the result
  2. Pass the session to resourceRoutes(app, session) (and potentially authRoutes if needed)
  3. Update the default export in routes.resource.js to accept a session parameter: export default function (app, session) { ... }
  4. Remove the import of session from app.auth.js in routes.resource.js

Would you like me to provide a concrete refactoring example?

Comment on lines +31 to +35
} catch (error) {
console.warn('\n###################################################');
console.warn('WARNING: REST app user for Step Up/Txn Auth missing');
console.warn('###################################################\n');
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Propagate authentication failures to caller.

The catch block only logs a warning without throwing or returning an error indicator. Callers cannot determine whether authentication succeeded or failed, potentially leading to undefined behavior when accessing the session.

Apply this diff to signal failure:

   } catch (error) {
     console.warn('\n###################################################');
     console.warn('WARNING: REST app user for Step Up/Txn Auth missing');
     console.warn('###################################################\n');
+    throw error; // or return null/undefined to signal failure
   }
 }
📝 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
} catch (error) {
console.warn('\n###################################################');
console.warn('WARNING: REST app user for Step Up/Txn Auth missing');
console.warn('###################################################\n');
}
} catch (error) {
console.warn('\n###################################################');
console.warn('WARNING: REST app user for Step Up/Txn Auth missing');
console.warn('###################################################\n');
throw error; // or return null/undefined to signal failure
}
🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/app.auth.js around lines 31 to 35, the catch block
only logs a warning and does not propagate the authentication failure to
callers; update the catch block to propagate the error by either rethrowing the
caught error (throw error) after logging or return a clear failure indicator
(eg. return null/false or an object with success:false) so callers can detect
and handle authentication failure; ensure the chosen approach is consistent with
surrounding code (promise rejection vs return value) and include the original
error details when propagating.

* of the MIT license. See the LICENSE file for details.
*/

import { env } from 'process';
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

ESM vs. CommonJS: configure modules so Biome and Node agree.

Biome parse errors suggest these files are treated as scripts. Either mark this package as ESM or switch to require/module.exports.

Add a package.json in e2e/am-mock-api/:

+// e2e/am-mock-api/package.json
+{
+  "name": "am-mock-api",
+  "private": true,
+  "type": "module"
+}

Alternatively, rename files to .mjs or configure Biome to parse ESM (sourceType: module). Based on learnings.

Also applies to: 60-71


🏁 Script executed:

#!/bin/bash
# Confirm Biome is parsing these files as scripts (look for the errors)
rg -n "Illegal use of an import declaration outside of a module" -g "!.git"

Length of output: 0


I need to gather more information about the actual state of the codebase to verify if the Biome errors mentioned in the review actually exist.


🏁 Script executed:

#!/bin/bash
# Check if e2e/am-mock-api/package.json exists
if [ -f "e2e/am-mock-api/package.json" ]; then
  echo "=== e2e/am-mock-api/package.json EXISTS ==="
  cat "e2e/am-mock-api/package.json"
else
  echo "=== e2e/am-mock-api/package.json DOES NOT EXIST ==="
fi

echo ""
echo "=== Directory structure of e2e/am-mock-api ==="
find "e2e/am-mock-api" -type f -name "*.json" -o -name "*.js" -o -name "*.mjs" | head -20

echo ""
echo "=== Content of env.config.js ==="
if [ -f "e2e/am-mock-api/src/app/env.config.js" ]; then
  cat "e2e/am-mock-api/src/app/env.config.js"
else
  echo "File not found"
fi

echo ""
echo "=== Check for Biome config ==="
if [ -f "biome.json" ] || [ -f "biome.jsonc" ]; then
  echo "Found Biome config"
  [ -f "biome.json" ] && cat "biome.json" || cat "biome.jsonc"
else
  echo "No Biome config found at root"
fi

Length of output: 4594


Fix module type mismatch: ESM syntax requires "type": "module".

The package.json specifies "type": "commonjs", but env.config.js uses ESM syntax (import/export statements). This will fail at runtime.

Note: The referenced Biome parse errors do not appear to be reported—the actual issue is the configuration mismatch.

Update e2e/am-mock-api/package.json:

{
  "name": "am-mock-api",
  "version": "0.0.0",
  "private": true,
  "description": "",
  "keywords": [],
  "license": "ISC",
  "author": "",
-  "type": "commonjs",
+  "type": "module",
  "main": "./index.js",
  ...
}

Alternatively, convert all files to CommonJS syntax (require/module.exports).

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (2.1.2)

[error] 10-11: Illegal use of an import declaration outside of a module

not allowed inside scripts

(parse)

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/env.config.js around line 11, the file uses ESM
import/export syntax while e2e/am-mock-api/package.json is set to "type":
"commonjs"; fix by either updating package.json to "type": "module" (so ESM
imports are valid) or convert this file to CommonJS (replace `import { env }
from 'process'` with a require and switch any exports to module.exports) and
ensure all other files in the package follow the same module style.

Comment on lines +13 to +15
export default function wait(req, res, next) {
setTimeout(() => next(), delay);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix the module system mismatch.

The file uses ES6 export syntax (export default), but the package.json declares "type": "commonjs". This will cause a runtime error in Node.js.

Apply this diff to use CommonJS syntax:

-export default function wait(req, res, next) {
+module.exports = function wait(req, res, next) {
   setTimeout(() => next(), delay);
-}
+};

Alternatively, if you want to use ES6 modules throughout the project, change the package.json:

-  "type": "commonjs",
+  "type": "module",

Note: Switching to ES6 modules will require updating all .js files in the project to use ES6 import/export syntax.

📝 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
export default function wait(req, res, next) {
setTimeout(() => next(), delay);
}
module.exports = function wait(req, res, next) {
setTimeout(() => next(), delay);
};
🧰 Tools
🪛 Biome (2.1.2)

[error] 12-15: Illegal use of an export declaration outside of a module

not allowed inside scripts

(parse)

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/wait.js around lines 13 to 15, the file uses ES6
export syntax (`export default`) while package.json is `"type": "commonjs"`,
causing a runtime error; replace the ES6 export with CommonJS by exporting the
function with module.exports = wait and keep the function declaration as-is (or
convert any imports/exports in this file to CommonJS require/module.exports if
needed) so the module format matches the project config.

Comment on lines +1 to +3
export const environment = {
production: true,
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Production environment configuration is incomplete.

The production environment only defines the production flag, but the development environment (environment.ts) includes several critical configuration properties: AM_URL, REALM_PATH, WEB_OAUTH_CLIENT, JOURNEY_LOGIN, JOURNEY_REGISTER, and API_URL. Code that imports this environment configuration will fail at runtime when accessing missing properties.

Apply this diff to include all required properties:

 export const environment = {
+  AM_URL: 'https://openam-crbrl-01.forgeblocks.com/am/',
+  REALM_PATH: 'alpha',
+  WEB_OAUTH_CLIENT: 'WebOAuthClient',
+  JOURNEY_LOGIN: 'UsernamelessWebAuthn',
+  JOURNEY_REGISTER: 'Registration',
+  API_URL: 'http://localhost:9443',
-  production: true,
+  production: 'production',
 };

Note: Update the URLs and configuration values as appropriate for your production environment.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/environments/environment.prod.ts around lines 1 to 3, the
production export only sets production: true while the dev environment defines
AM_URL, REALM_PATH, WEB_OAUTH_CLIENT, JOURNEY_LOGIN, JOURNEY_REGISTER, and
API_URL; add these missing properties to the exported environment object with
production-appropriate values (replace with your real production URLs/ids), e.g.
include AM_URL, REALM_PATH, WEB_OAUTH_CLIENT, JOURNEY_LOGIN, JOURNEY_REGISTER,
and API_URL alongside production: true so any code that reads those keys at
runtime does not break.

JOURNEY_LOGIN: 'UsernamelessWebAuthn',
JOURNEY_REGISTER: 'Registration',
API_URL: 'http://localhost:9443',
production: 'development',
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix type mismatch: production should be a boolean.

The production property is set to the string 'development', but the related environment.prod.ts file shows this should be a boolean value. This type inconsistency could cause runtime errors if the code performs boolean checks.

Apply this diff:

-  production: 'development',
+  production: false,
📝 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
production: 'development',
production: false,
🤖 Prompt for AI Agents
In e2e/am-mock-api/src/environments/environment.ts around line 8, the production
property is incorrectly set to the string 'development'; change it to the
boolean false to match the type used in environment.prod.ts and ensure any
runtime boolean checks work correctly. Update the value only (production: false)
so the file's shape and typings remain consistent with the prod environment
file.

Comment on lines +29 to +37
app.use(
cors({
exposedHeaders: ['www-authenticate'],
credentials: true,
origin: function (origin, callback) {
return callback(null, true);
},
}),
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Tighten CORS policy for the mock API.

The CORS configuration allows all origins by unconditionally returning true in the origin callback. Even for a mock API, this creates unnecessary exposure if the server is accessible beyond localhost.

Apply this diff to restrict to localhost origins:

 app.use(
   cors({
     exposedHeaders: ['www-authenticate'],
     credentials: true,
-    origin: function (origin, callback) {
-      return callback(null, true);
-    },
+    origin: function (origin, callback) {
+      // Allow requests with no origin (like mobile apps or curl) or localhost
+      if (!origin || /^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:\d+)?$/.test(origin)) {
+        return callback(null, true);
+      }
+      return callback(new Error('Not allowed by CORS'));
+    },
   }),
 );
📝 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
app.use(
cors({
exposedHeaders: ['www-authenticate'],
credentials: true,
origin: function (origin, callback) {
return callback(null, true);
},
}),
);
app.use(
cors({
exposedHeaders: ['www-authenticate'],
credentials: true,
origin: function (origin, callback) {
// Allow requests with no origin (like mobile apps or curl) or localhost
if (!origin || /^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:\d+)?$/.test(origin)) {
return callback(null, true);
}
return callback(new Error('Not allowed by CORS'));
},
}),
);


app.get('/healthcheck', (req, res) => res.status(200).send('ok'));

env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Remove global disabling of TLS certificate verification.

Setting NODE_TLS_REJECT_UNAUTHORIZED=0 disables certificate validation for all outbound HTTPS requests from this process, creating a man-in-the-middle vulnerability. While this may be acceptable for an isolated mock server in a test environment, it should be clearly documented and ideally scoped more narrowly.

Consider one of these alternatives:

  1. If certificate validation must be disabled for specific requests, use per-request agent configuration with superagent's .disableTLSCerts() method
  2. If this is truly necessary for the mock environment, add a prominent comment explaining why and ensure the mock server runs in complete isolation
  3. Use self-signed certificates properly configured in the Node.js trust store
-env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
+// TODO: Configure proper certificates or use per-request TLS options

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/index.js around line 55, remove the global disabling of
TLS certificate verification (env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0) and
instead either: 1) scope certificate skipping to only the required requests
using per-request agent/config (e.g., superagent's per-request disableTLSCerts
or equivalent), 2) if disabling is unavoidable for this mock, keep the global
change out of production by adding a prominent comment explaining why, gating it
behind an explicit test-only flag and ensuring the mock runs in complete
isolation, or 3) preferably configure and trust a self-signed certificate in
Node’s trust store so TLS validation remains enabled.

@codecov-commenter
Copy link

codecov-commenter commented Oct 21, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 18.80%. Comparing base (fa3d434) to head (5dd2420).
⚠️ Report is 54 commits behind head on main.

❌ Your project status has failed because the head coverage (18.80%) is below the target coverage (40.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #431      +/-   ##
==========================================
+ Coverage   18.52%   18.80%   +0.27%     
==========================================
  Files         138      140       +2     
  Lines       27402    27626     +224     
  Branches      963      980      +17     
==========================================
+ Hits         5076     5194     +118     
- Misses      22326    22432     +106     
Files with missing lines Coverage Δ
packages/journey-client/src/lib/client.store.ts 92.78% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 21, 2025

Open in StackBlitz

@forgerock/davinci-client

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/davinci-client@431

@forgerock/oidc-client

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/oidc-client@431

@forgerock/protect

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/protect@431

@forgerock/sdk-types

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/sdk-types@431

@forgerock/sdk-utilities

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/sdk-utilities@431

@forgerock/iframe-manager

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/iframe-manager@431

@forgerock/sdk-logger

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/sdk-logger@431

@forgerock/sdk-oidc

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/sdk-oidc@431

@forgerock/sdk-request-middleware

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/sdk-request-middleware@431

@forgerock/storage

pnpm add https://pkg.pr.new/ForgeRock/ping-javascript-sdk/@forgerock/storage@431

commit: 5dd2420

@github-actions
Copy link
Contributor

github-actions bot commented Oct 21, 2025

Deployed f30f2ee to https://ForgeRock.github.io/ping-javascript-sdk/pr-431/f30f2eeb024a42fd634a9ce32dd3830264ed4bef branch gh-pages in ForgeRock/ping-javascript-sdk

@github-actions
Copy link
Contributor

github-actions bot commented Oct 21, 2025

📦 Bundle Size Analysis

📦 Bundle Size Analysis

🚨 Significant Changes

🔻 @forgerock/journey-client - 0.0 KB (-82.0 KB, -100.0%)

📊 Minor Changes

📈 @forgerock/journey-client - 82.2 KB (+0.2 KB)

➖ No Changes

@forgerock/device-client - 9.2 KB
@forgerock/oidc-client - 22.9 KB
@forgerock/protect - 150.1 KB
@forgerock/sdk-utilities - 7.5 KB
@forgerock/sdk-types - 8.0 KB
@forgerock/storage - 1.4 KB
@forgerock/sdk-logger - 1.6 KB
@forgerock/iframe-manager - 2.4 KB
@forgerock/sdk-request-middleware - 4.5 KB
@forgerock/sdk-oidc - 2.6 KB
@forgerock/davinci-client - 38.9 KB


13 packages analyzed • Baseline from latest main build

Legend

🆕 New package
🔺 Size increased
🔻 Size decreased
➖ No change

ℹ️ How bundle sizes are calculated
  • Current Size: Total gzipped size of all files in the package's dist directory
  • Baseline: Comparison against the latest build from the main branch
  • Files included: All build outputs except source maps and TypeScript build cache
  • Exclusions: .map, .tsbuildinfo, and .d.ts.map files

🔄 Updated automatically on each push to this PR

@ryanbas21 ryanbas21 force-pushed the migrate-am-mock-api branch from 9116a55 to f200156 Compare November 4, 2025 21:34
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (11)
e2e/am-mock-api/src/environments/environment.prod.ts (1)

1-3: Production environment configuration remains incomplete.

This issue was previously flagged: the production environment only defines production: true, while the development environment includes critical properties (AM_URL, REALM_PATH, WEB_OAUTH_CLIENT, JOURNEY_LOGIN, JOURNEY_REGISTER, API_URL) that runtime code will expect. This will cause runtime failures when code attempts to access these missing properties.

e2e/am-mock-api/src/app/wait.js (1)

13-15: Module system mismatch flagged in previous review.

The ES6 export syntax incompatibility with the CommonJS package.json configuration has already been identified in the previous review.

e2e/am-mock-api/src/app/constants.js (1)

11-11: Module system mismatch affects this file.

This file uses ES6 export syntax while package.json declares "type": "commonjs". The same issue has been flagged in other files in this package. Update e2e/am-mock-api/package.json to "type": "module" to resolve this for all affected files.

e2e/am-mock-api/src/app/routes.resource.js (5)

27-29: Host comparison bug previously identified.

The comparison of req.hostname to the full URL in FORGEOPS has been flagged in the previous review with detailed remediation steps.


47-56: Unguarded external call previously identified.

The missing try/catch and timeout handling for the superagent POST call has been flagged in the previous review with suggested fixes.


71-95: Missing error handling for OAuth introspection and SSO validation previously identified.

The lack of error handling and timeouts for external authentication calls has been comprehensively documented in the previous review.


121-130: Missing Referer guard and deprecated API previously identified.

The missing null check for req.headers.referer and the deprecated res.send(401, null) syntax have been flagged in the previous review.


145-154: Missing Referer guard and deprecated API previously identified.

The same issues with Referer header handling and deprecated response API have been flagged for this code block in the previous review.

e2e/am-mock-api/src/app/responses.js (3)

11-11: Module system mismatch previously identified.

The ES6 import syntax incompatibility with the CommonJS package.json configuration has been flagged in the previous review.


51-68: Debug log and unsafe URL parsing previously identified.

The noisy console.log and unguarded new URL(url) call have been flagged in the previous review with suggested fixes.


88-99: Guard against invalid URL in header construction.

The unguarded new URL(url) will throw if url is falsy or malformed.

Apply this diff:

 export const createTxnStepUpHeader = (url) => {
   // Grab the client's desired AM URL
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl') || AM_URL;
🧹 Nitpick comments (1)
e2e/journey-app/main.ts (1)

47-47: Consider using ES6 object property shorthand.

Since the property name matches the variable name, you can simplify config: config to just config.

Apply this diff:

-  const journeyClient = await journey({ config: config, requestMiddleware });
+  const journeyClient = await journey({ config, requestMiddleware });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9116a55 and f200156.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (27)
  • .claude/settings.local.json (1 hunks)
  • e2e/am-mock-api/.babelrc (1 hunks)
  • e2e/am-mock-api/.eslintrc.json (1 hunks)
  • e2e/am-mock-api/package.json (1 hunks)
  • e2e/am-mock-api/project.json (1 hunks)
  • e2e/am-mock-api/src/app/app.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/constants.js (1 hunks)
  • e2e/am-mock-api/src/app/env.config.js (1 hunks)
  • e2e/am-mock-api/src/app/response.registration.js (1 hunks)
  • e2e/am-mock-api/src/app/responses.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.resource.js (1 hunks)
  • e2e/am-mock-api/src/app/wait.js (1 hunks)
  • e2e/am-mock-api/src/environments/environment.prod.ts (1 hunks)
  • e2e/am-mock-api/src/environments/environment.ts (1 hunks)
  • e2e/am-mock-api/src/index.js (1 hunks)
  • e2e/am-mock-api/tsconfig.app.json (1 hunks)
  • e2e/am-mock-api/tsconfig.json (1 hunks)
  • e2e/am-mock-api/tsconfig.spec.json (1 hunks)
  • e2e/journey-app/main.ts (3 hunks)
  • e2e/journey-app/server-configs.ts (1 hunks)
  • e2e/journey-suites/playwright.config.ts (1 hunks)
  • e2e/journey-suites/src/basic.test.ts (1 hunks)
  • package.json (2 hunks)
  • packages/journey-client/src/lib/journey.store.test.ts (1 hunks)
  • packages/journey-client/src/lib/journey.store.ts (2 hunks)
  • tsconfig.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .claude/settings.local.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • e2e/am-mock-api/src/index.js
  • e2e/am-mock-api/.babelrc
  • e2e/am-mock-api/tsconfig.json
  • e2e/am-mock-api/tsconfig.spec.json
  • e2e/am-mock-api/src/app/env.config.js
  • e2e/am-mock-api/src/app/app.auth.js
  • e2e/am-mock-api/src/app/routes.auth.js
  • e2e/am-mock-api/package.json
  • e2e/am-mock-api/src/environments/environment.ts
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-27T17:55:33.855Z
Learnt from: cerebrl
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: e2e/journey-app/main.ts:83-87
Timestamp: 2025-10-27T17:55:33.855Z
Learning: In the e2e/journey-app and similar e2e test applications in this repository, XSS hardening and similar production security practices are not required since these are exclusively test/development applications.

Applied to files:

  • e2e/journey-suites/src/basic.test.ts
  • packages/journey-client/src/lib/journey.store.test.ts
📚 Learning: 2025-10-28T14:44:26.883Z
Learnt from: ryanbas21
Repo: ForgeRock/ping-javascript-sdk PR: 427
File: .github/workflows/ci-fork.yml:50-56
Timestamp: 2025-10-28T14:44:26.883Z
Learning: Nx CLI accepts multiple targets with the short `-t` flag as space-separated tokens (e.g., `nx affected -t lint test build`) and also supports comma-separated values with the long form `--targets=` (e.g., `nx affected --targets=lint,test,build`). Both syntaxes are valid.

Applied to files:

  • e2e/am-mock-api/project.json
  • package.json
📚 Learning: 2025-10-22T15:14:00.044Z
Learnt from: ryanbas21
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: packages/journey-client/src/lib/callbacks/name-callback.ts:9-15
Timestamp: 2025-10-22T15:14:00.044Z
Learning: In packages/journey-client, callback classes are internal implementation details not part of the public API. The callbacks barrel (src/lib/callbacks/index.ts) intentionally only exports the base JourneyCallback class. Internal code imports concrete callback classes directly from their individual files (e.g., factory.ts, journey-client.ts).

Applied to files:

  • packages/journey-client/src/lib/journey.store.ts
🧬 Code graph analysis (6)
e2e/am-mock-api/src/environments/environment.prod.ts (1)
e2e/am-mock-api/src/environments/environment.ts (1)
  • environment (1-9)
packages/journey-client/src/lib/journey.store.ts (2)
packages/journey-client/src/lib/config.types.ts (1)
  • JourneyClientConfig (11-15)
packages/journey-client/src/lib/journey.store.utils.ts (1)
  • createJourneyStore (21-44)
packages/journey-client/src/lib/journey.store.test.ts (2)
packages/journey-client/src/lib/config.types.ts (1)
  • JourneyClientConfig (11-15)
packages/journey-client/src/lib/journey.store.ts (1)
  • journey (45-194)
e2e/journey-app/main.ts (1)
packages/journey-client/src/lib/journey.store.ts (1)
  • journey (45-194)
e2e/am-mock-api/src/app/routes.resource.js (5)
e2e/am-mock-api/src/app/env.config.js (8)
  • FORGEOPS (67-67)
  • FORGEOPS (67-67)
  • AM_PORT (61-61)
  • AM_PORT (61-61)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/app.auth.js (3)
  • response (18-24)
  • session (14-14)
  • session (14-14)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/routes.auth.js (2)
  • baz (57-59)
  • baz (57-59)
e2e/am-mock-api/src/app/responses.js (12)
  • authByTxnResponse (124-132)
  • authByTxnResponse (124-132)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpUrl (51-68)
  • createTxnStepUpUrl (51-68)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpUrl (70-86)
  • createTreeStepUpUrl (70-86)
  • authByTreeResponse (114-122)
  • authByTreeResponse (114-122)
e2e/am-mock-api/src/app/responses.js (2)
e2e/am-mock-api/src/app/routes.auth.js (5)
  • url (547-547)
  • redirectUrl (453-455)
  • redirectUrl (461-463)
  • redirectUrl (470-472)
  • redirectUrl (513-513)
e2e/am-mock-api/src/app/env.config.js (6)
  • amUrl (49-49)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • RESOURCE_URL (69-69)
  • RESOURCE_URL (69-69)
  • realm (36-36)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Mend Code Security Check
  • GitHub Check: pr
🔇 Additional comments (10)
package.json (2)

37-37: LGTM: Watch script updated for Vite integration.

The watch script change integrates Nx with Vite-based watching, which aligns with the Vite dependency in the project.


65-65: LGTM: @nx/express dependency added for mock API support.

The addition of @nx/express at version 21.2.3 correctly enables Express integration within Nx tooling, supporting the new e2e mock API infrastructure.

packages/journey-client/src/lib/journey.store.ts (2)

25-43: LGTM: baseUrl normalization correctly implemented.

The normalizeConfig helper ensures that baseUrl always has a trailing slash, which is essential for correct URL resolution when using context paths (e.g., /am). The implementation correctly:

  • Checks for the presence of serverConfig.baseUrl
  • Adds a trailing slash only when missing
  • Returns the original config if already normalized

59-63: LGTM: Config normalization properly applied.

The normalized config is correctly applied both when creating the store and when dispatching setConfig, ensuring consistent URL handling throughout the journey client.

packages/journey-client/src/lib/journey.store.test.ts (1)

241-298: LGTM: Comprehensive test coverage for baseUrl normalization.

The new test suite thoroughly validates the normalizeConfig behavior across three important scenarios:

  1. Adding a trailing slash when missing for URLs with context paths
  2. Preserving an existing trailing slash
  3. Handling URLs without context paths

All tests correctly verify that the final request URL is properly constructed.

e2e/am-mock-api/tsconfig.app.json (1)

1-13: LGTM: Standard TypeScript configuration for Express application.

The TypeScript configuration is appropriate for a Node/Express-based mock API:

  • Node16 module system aligns with modern Node.js practices
  • ES6 target is suitable for server-side code
  • Proper type definitions for Node.js and Express
  • Excludes test files from compilation
tsconfig.json (1)

79-81: LGTM: Project reference added for am-mock-api.

The addition of the ./e2e/am-mock-api project reference correctly integrates the new mock API into the TypeScript composite project structure.

e2e/am-mock-api/src/app/response.registration.js (2)

69-99: Verify: Is the commented NumberAttributeInputCallback intentional?

There's a large block of commented-out code for a NumberAttributeInputCallback (age field). If this callback is not needed for the registration flow tests, consider removing it entirely to keep the codebase clean. If it's intended for future use, consider adding a TODO comment explaining why it's disabled.


11-224: LGTM: Mock registration response structure is well-defined.

The mock registration data comprehensively covers a typical user registration flow with appropriate callbacks for:

  • Username validation with policies
  • Personal information collection
  • Email with validation
  • Preference checkboxes
  • Password with strength policies
  • Security questions (KBA)
  • Terms and conditions

The structure correctly follows AM callback patterns for e2e testing.

e2e/journey-suites/src/basic.test.ts (1)

26-27: LGTM: Hardcoded test credentials are appropriate for e2e mock environment.

Replacing the imported credentials with hardcoded values ('sdkuser' and 'password') is acceptable for end-to-end tests against a mock API. This simplifies the test setup and makes the test more explicit about the test data being used.

Comment on lines +70 to +86
export const createTreeStepUpUrl = (url) => {
// Grab the client's desired AM URL
const referer = new URL(url);
const amUrl = referer.searchParams.get('amUrl');
// Create the redirect URL
const redirectUrl = new URL(amUrl || AM_URL);
redirectUrl.searchParams.set('goto', `${RESOURCE_URL}/ig`);
redirectUrl.searchParams.set('realm', '/');
redirectUrl.searchParams.set('authIndexType', 'composite_advice');
redirectUrl.searchParams.set(
'authIndexValue',
// eslint-disable-next-line max-len
'%3CAdvices%3E%3CAttributeValuePair%3E%3CAttribute%20name=%22AuthenticateToServiceConditionAdvice%22/%3E%3CValue%3E/sdk:ConfirmPassword%3C/Value%3E%3C/AttributeValuePair%3E%3C/Advices%3E',
);

return redirectUrl.toString();
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Apply the same URL parsing resilience as createTxnStepUpUrl.

This function has the same vulnerability as createTxnStepUpUrl (flagged in previous review): new URL(url) throws if url is falsy or invalid. Apply the same defensive pattern suggested for the other function.

Apply this diff:

 export const createTreeStepUpUrl = (url) => {
   // Grab the client's desired AM URL
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl');
🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/responses.js around lines 70 to 86, new URL(url) can
throw for falsy/invalid input; make the same defensive change used in
createTxnStepUpUrl: attempt to construct the referer inside a try/catch (or
check truthiness) and if it fails set referer to new URL(AM_URL) (or another
safe default), then read amUrl from referer.searchParams and continue building
redirectUrl as before; this prevents exceptions on bad/missing url input while
preserving existing behavior.

Comment on lines +101 to +112
export const createTreeStepUpHeader = (url) => {
// Grab the client's desired AM URL
const referer = new URL(url);
const amUrl = referer.searchParams.get('amUrl') || AM_URL;

// Base 64 of {"AuthenticateToServiceConditionAdvice":["/sdk:ConfirmPassword"]}
const advices =
'eyJBdXRoZW50aWNhdGVUb1NlcnZpY2VDb25kaXRpb25BZHZpY2UiOlsiL3NkazpDb25maXJtUGFzc3dvcmQiXX0=';
const realm = '/';
const headerValue = `SSOADVICE realm="${realm}",advices="${advices}",am_uri="${amUrl}"`;
return headerValue;
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against invalid URL in header construction.

The unguarded new URL(url) will throw if url is falsy or malformed.

Apply this diff:

 export const createTreeStepUpHeader = (url) => {
   // Grab the client's desired AM URL
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl') || AM_URL;
📝 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
export const createTreeStepUpHeader = (url) => {
// Grab the client's desired AM URL
const referer = new URL(url);
const amUrl = referer.searchParams.get('amUrl') || AM_URL;
// Base 64 of {"AuthenticateToServiceConditionAdvice":["/sdk:ConfirmPassword"]}
const advices =
'eyJBdXRoZW50aWNhdGVUb1NlcnZpY2VDb25kaXRpb25BZHZpY2UiOlsiL3NkazpDb25maXJtUGFzc3dvcmQiXX0=';
const realm = '/';
const headerValue = `SSOADVICE realm="${realm}",advices="${advices}",am_uri="${amUrl}"`;
return headerValue;
};
export const createTreeStepUpHeader = (url) => {
// Grab the client's desired AM URL
const safe = url || 'http://localhost/';
const referer = new URL(safe);
const amUrl = referer.searchParams.get('amUrl') || AM_URL;
// Base 64 of {"AuthenticateToServiceConditionAdvice":["/sdk:ConfirmPassword"]}
const advices =
'eyJBdXRoZW50aWNhdGVUb1NlcnZpY2VDb25kaXRpb25BZHZpY2UiOlsiL3NkazpDb25maXJtUGFzc3dvcmQiXX0=';
const realm = '/';
const headerValue = `SSOADVICE realm="${realm}",advices="${advices}",am_uri="${amUrl}"`;
return headerValue;
};
🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/responses.js around lines 101 to 112 the call new
URL(url) is unguarded and will throw for falsy or malformed input; wrap the URL
parsing in a try/catch (or validate with a safe URL parse) and if parsing fails
fall back to using AM_URL as the amUrl (or a sensible default), then continue to
build and return the headerValue; ensure referer.searchParams.get is only
accessed when parsing succeeded and that the function never throws for bad
input.

Comment on lines 40 to 46
{
command: 'pnpm nx serve am-mock-api',
port: 5829,
ignoreHTTPSErrors: true,
reuseExistingServer: !process.env.CI,
cwd: workspaceRoot,
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Port conflict: am-mock-api and journey-app both configured for port 5829.

Both web servers are configured to use port 5829:

  • Line 35: journey-app on port 5829
  • Line 42: am-mock-api on port 5829

Two separate server processes cannot listen on the same port simultaneously. This will cause the second server to fail to start with an "EADDRINUSE" error.

Apply this diff to assign a different port to am-mock-api:

     {
       command: 'pnpm nx serve am-mock-api',
-      port: 5829,
+      port: 9443,
       ignoreHTTPSErrors: true,
       reuseExistingServer: !process.env.CI,
       cwd: workspaceRoot,
     },

Ensure that the journey-app is also configured to make requests to http://localhost:9443 (or whichever port you choose) for the mock AM API endpoints.

📝 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
{
command: 'pnpm nx serve am-mock-api',
port: 5829,
ignoreHTTPSErrors: true,
reuseExistingServer: !process.env.CI,
cwd: workspaceRoot,
},
{
command: 'pnpm nx serve am-mock-api',
port: 9443,
ignoreHTTPSErrors: true,
reuseExistingServer: !process.env.CI,
cwd: workspaceRoot,
},
🤖 Prompt for AI Agents
In e2e/journey-suites/playwright.config.ts around lines 40 to 46, the
am-mock-api server is configured to use port 5829 which conflicts with
journey-app (also 5829). Change the am-mock-api port to a different one (e.g.,
9443) in this block and update any related start/command args if necessary; then
ensure journey-app configuration/fixtures point to the mock AM API at
http://localhost:9443 (or whichever new port you pick) so tests call the correct
mock endpoint.

nx-cloud[bot]

This comment was marked as outdated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
e2e/davinci-suites/src/phone-number-field.test.ts (1)

109-111: Consider applying consistent assertion patterns across similar tests.

The phone device registration test uses .toPass() for retry logic, but the email device test (line 66) uses a direct toBeVisible() assertion without retries. If timing issues necessitate retry logic here, the email registration likely benefits from the same pattern.

Apply this diff to make the email test consistent:

-    await expect(page.getByText('EMAIL MFA Registered')).toBeVisible();
+    await expect(
+      async () => await expect(page.getByText('EMAIL MFA Registered')).toBeVisible(),
+    ).toPass();

Alternatively, verify whether the timing difference between phone and email registration is intentional and document the reason if so.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f200156 and 0a56dac.

📒 Files selected for processing (2)
  • e2e/davinci-suites/src/phone-number-field.test.ts (1 hunks)
  • e2e/journey-suites/playwright.config.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Mend Code Security Check
  • GitHub Check: pr
🔇 Additional comments (1)
e2e/journey-suites/playwright.config.ts (1)

40-46: Port conflict resolved and configuration verified.

The port configuration is correct: journey-app runs on 5829 while am-mock-api runs on 9443. Verification confirms journey-app is properly configured in e2e/journey-app/server-configs.ts (line 12) to call the mock AM API at http://localhost:9443/am. No downstream issues identified.

nx-cloud[bot]

This comment was marked as outdated.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We should probably .gitignore this as well, yeah?


const config = serverConfigs[searchParams.get('clientId') || 'basic'];

const tree = searchParams.get('tree') ?? 'UsernamePassword';
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm using journey and not tree in all the tests I've migrated over. Let's stick with that since "tree" is an outdated term.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

journey conflicts with the variable journey we can use a variation of journey if you prefer that?

Comment on lines 109 to 111
await expect(
async () => await expect(page.getByText('SMS/Voice MFA Registered')).toBeVisible(),
).toPass();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you mean to commit this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i was debugging a test error i can remove.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems this wasn't removed. Can you remove it?

Comment on lines 10 to 15
basic: {
serverConfig: {
baseUrl: 'https://openam-sdks.forgeblocks.com/am/',
baseUrl: 'http://localhost:9443/am',
},
realmPath: '/alpha',
realmPath: 'root',
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we have a different config object for the Mock API, rather than replacing our shared test tenant?

Comment on lines 26 to 27
await page.getByLabel('User Name').fill('sdkuser');
await page.getByLabel('Password').fill('password');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this accidentally committed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no this was the user we had to use to make the test pass with mockapi

@@ -7,7 +7,6 @@

import { expect, test } from '@playwright/test';
import { asyncEvents } from './utils/async-events.js';
import { username, password } from './utils/demo-user.js';

test('Test happy paths on test page', async ({ page }) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the "switch" that allows us to define the use of Mock vs Live server depending on the test run?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't understand this question? If your asking for parity between the mock api and our tenant, have we ever had that?

@ryanbas21 ryanbas21 force-pushed the migrate-am-mock-api branch from 0a56dac to 5ff6bd8 Compare November 5, 2025 16:59
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (12)
e2e/am-mock-api/src/index.js (3)

43-48: Hardcoded credentials must be removed.

This issue was previously flagged but remains unaddressed. Hardcoded credentials pose a security risk even in test environments.


29-37: CORS policy allows all origins.

This issue was previously flagged. The permissive CORS configuration should be tightened to localhost origins only.


55-55: TLS certificate verification is globally disabled.

This issue was previously flagged. Consider scoping certificate skipping to specific requests or using properly configured certificates.

e2e/am-mock-api/src/app/app.auth.js (2)

14-14: Mutable module-level state is problematic.

This issue was previously discussed. The exported mutable session variable can lead to race conditions and makes testing difficult. The conversation identified that routes.resource.js imports this variable.


31-35: Authentication failures are not propagated.

This issue was previously flagged. The catch block only logs a warning without throwing or returning an error indicator, preventing callers from detecting authentication failures.

e2e/am-mock-api/src/app/routes.resource.js (3)

14-74: Fix LIVE gating: hostname comparison is broken and the policy URL is malformed.

req.hostname returns default.forgeops.petrov.ca, but FORGEOPS is https://…; equality/inequality checks will never behave as intended, so LIVE requests skip auth enforcement. On top of that, ${req.protocol}://${req.host}:${AM_PORT} double-inserts the port (req.host already holds host:port, or is undefined), yielding invalid resource URLs. Parse FORGEOPS once (FORGEOPS_HOST) and compare hostnames, and build fullURL with req.get('host') (or req.hostname) without re-appending AM_PORT. This is critical for LIVE authorization to work. -->


47-80: Guard superagent calls—network failures currently crash the handler.

Both the policy evaluate call and the OAuth/SSO validation paths await superagent without try/catch or timeouts. Any network error or slow AM host turns into an unhandled rejection, tearing down the request (or the process under load). Wrap those awaits in try/catch, add .timeout({ response: 5000, deadline: 15000 }), and return a 5xx/401 instead of letting the exception propagate. -->


120-131: Don’t assume Referer exists.

req.headers.referer.includes('json') and the subsequent redirect/header builders dereference an optional header and feed it to new URL(...). Missing/invalid referers throw here, breaking the route. Please guard with a safe default (empty string or AM_URL) before calling .includes or createTxnStepUp*. -->

e2e/am-mock-api/src/app/routes.auth.js (3)

55-55: Drop the password log.

Printing USERS[0].pw leaks credentials to stdout/logs. Even in mocks this is a security smell—delete the log or hide the secret. -->


449-474: Handle missing Referer before constructing URLs.

new URL(req.get('Referer')) throws when the header is absent/invalid, which is common in automated tests. Add a fallback (e.g., derive from req.protocol/req.get('host')) before instantiating URL. -->


541-546: Cookie domain detection never matches localhost.

req.url is just the path, so this branch always chooses example.com, breaking local cookies. Use req.hostname (or req.get('host')) instead. -->

e2e/am-mock-api/src/app/responses.js (1)

51-112: All step-up helpers need safe URL parsing.

Each helper still calls new URL(url) (and one logs to stdout). When Referer is missing or malformed, these throw—exactly the crash observed in routes.resource/IG flows. Remove the debug console.log, validate the input (fallback to AM_URL/RESOURCE_URL), and only read searchParams when parsing succeeds. -->

🧹 Nitpick comments (2)
e2e/journey-app/utils/delete-webauthn-device.ts (1)

14-16: Consider parallel deletion for better performance.

Sequential deletion with await in a loop can be slow when multiple devices exist. Using Promise.all() would execute deletions in parallel.

Apply this diff to parallelize deletions:

-for (const device of devices) {
-  await dc.webAuthn.delete({ userId, realm, device });
-}
+await Promise.all(
+  devices.map(device => dc.webAuthn.delete({ userId, realm, device }))
+);
packages/journey-client/src/lib/client.store.ts (1)

25-43: Consider edge case handling for robustness.

The normalization logic handles the primary use cases well. For additional robustness, consider handling edge cases such as:

  • Empty string baseUrl ('''/')
  • Multiple trailing slashes ('http://test.com//')

However, since this is a private helper and the primary use cases are covered, these edge cases may be better handled through upstream validation of the config object.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ff6bd8 and 1e7af4e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (28)
  • e2e/am-mock-api/.babelrc (1 hunks)
  • e2e/am-mock-api/.eslintrc.json (1 hunks)
  • e2e/am-mock-api/package.json (1 hunks)
  • e2e/am-mock-api/project.json (1 hunks)
  • e2e/am-mock-api/src/app/app.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/constants.js (1 hunks)
  • e2e/am-mock-api/src/app/env.config.js (1 hunks)
  • e2e/am-mock-api/src/app/response.registration.js (1 hunks)
  • e2e/am-mock-api/src/app/responses.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.resource.js (1 hunks)
  • e2e/am-mock-api/src/app/wait.js (1 hunks)
  • e2e/am-mock-api/src/environments/environment.prod.ts (1 hunks)
  • e2e/am-mock-api/src/environments/environment.ts (1 hunks)
  • e2e/am-mock-api/src/index.js (1 hunks)
  • e2e/am-mock-api/tsconfig.app.json (1 hunks)
  • e2e/am-mock-api/tsconfig.json (1 hunks)
  • e2e/am-mock-api/tsconfig.spec.json (1 hunks)
  • e2e/davinci-suites/src/phone-number-field.test.ts (1 hunks)
  • e2e/journey-app/main.ts (2 hunks)
  • e2e/journey-app/server-configs.ts (1 hunks)
  • e2e/journey-app/utils/delete-webauthn-device.ts (1 hunks)
  • e2e/journey-suites/playwright.config.ts (1 hunks)
  • e2e/journey-suites/src/login.test.ts (0 hunks)
  • package.json (2 hunks)
  • packages/journey-client/src/lib/client.store.test.ts (1 hunks)
  • packages/journey-client/src/lib/client.store.ts (2 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • e2e/journey-suites/src/login.test.ts
🚧 Files skipped from review as they are similar to previous changes (12)
  • e2e/davinci-suites/src/phone-number-field.test.ts
  • e2e/am-mock-api/src/app/response.registration.js
  • e2e/am-mock-api/tsconfig.app.json
  • e2e/am-mock-api/package.json
  • e2e/am-mock-api/tsconfig.spec.json
  • e2e/am-mock-api/.babelrc
  • e2e/am-mock-api/src/app/wait.js
  • e2e/journey-app/server-configs.ts
  • e2e/am-mock-api/src/environments/environment.ts
  • e2e/journey-suites/playwright.config.ts
  • e2e/journey-app/main.ts
  • e2e/am-mock-api/src/environments/environment.prod.ts
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-28T14:44:26.883Z
Learnt from: ryanbas21
Repo: ForgeRock/ping-javascript-sdk PR: 427
File: .github/workflows/ci-fork.yml:50-56
Timestamp: 2025-10-28T14:44:26.883Z
Learning: Nx CLI accepts multiple targets with the short `-t` flag as space-separated tokens (e.g., `nx affected -t lint test build`) and also supports comma-separated values with the long form `--targets=` (e.g., `nx affected --targets=lint,test,build`). Both syntaxes are valid.

Applied to files:

  • package.json
  • e2e/am-mock-api/project.json
📚 Learning: 2025-10-22T15:14:00.044Z
Learnt from: ryanbas21
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: packages/journey-client/src/lib/callbacks/name-callback.ts:9-15
Timestamp: 2025-10-22T15:14:00.044Z
Learning: In packages/journey-client, callback classes are internal implementation details not part of the public API. The callbacks barrel (src/lib/callbacks/index.ts) intentionally only exports the base JourneyCallback class. Internal code imports concrete callback classes directly from their individual files (e.g., factory.ts, journey-client.ts).

Applied to files:

  • packages/journey-client/src/lib/client.store.ts
📚 Learning: 2025-10-27T17:55:33.855Z
Learnt from: cerebrl
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: e2e/journey-app/main.ts:83-87
Timestamp: 2025-10-27T17:55:33.855Z
Learning: In the e2e/journey-app and similar e2e test applications in this repository, XSS hardening and similar production security practices are not required since these are exclusively test/development applications.

Applied to files:

  • packages/journey-client/src/lib/client.store.test.ts
🧬 Code graph analysis (9)
e2e/journey-app/utils/delete-webauthn-device.ts (1)
packages/device-client/src/lib/device.store.ts (1)
  • deviceClient (27-358)
e2e/am-mock-api/src/app/env.config.js (1)
e2e/am-mock-api/src/app/responses.js (6)
  • realm (96-96)
  • realm (109-109)
  • amUrl (55-55)
  • amUrl (73-73)
  • amUrl (91-91)
  • amUrl (104-104)
e2e/am-mock-api/src/app/routes.resource.js (5)
e2e/am-mock-api/src/app/env.config.js (8)
  • FORGEOPS (67-67)
  • FORGEOPS (67-67)
  • AM_PORT (61-61)
  • AM_PORT (61-61)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/app.auth.js (3)
  • response (18-24)
  • session (14-14)
  • session (14-14)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/routes.auth.js (2)
  • baz (57-59)
  • baz (57-59)
e2e/am-mock-api/src/app/responses.js (12)
  • authByTxnResponse (124-132)
  • authByTxnResponse (124-132)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpUrl (51-68)
  • createTxnStepUpUrl (51-68)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpUrl (70-86)
  • createTreeStepUpUrl (70-86)
  • authByTreeResponse (114-122)
  • authByTreeResponse (114-122)
packages/journey-client/src/lib/client.store.ts (2)
packages/journey-client/src/lib/config.types.ts (1)
  • JourneyClientConfig (11-15)
packages/journey-client/src/lib/client.store.utils.ts (1)
  • createJourneyStore (21-44)
packages/journey-client/src/lib/client.store.test.ts (2)
packages/journey-client/src/lib/config.types.ts (1)
  • JourneyClientConfig (11-15)
packages/journey-client/src/lib/client.store.ts (1)
  • journey (45-194)
e2e/am-mock-api/src/app/routes.auth.js (4)
e2e/am-mock-api/src/app/env.config.js (4)
  • USERS (71-71)
  • USERS (71-71)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/constants.js (2)
  • authPaths (11-66)
  • authPaths (11-66)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/responses.js (44)
  • txnAuthz (640-651)
  • txnAuthz (640-651)
  • treeAuthz (652-663)
  • treeAuthz (652-663)
  • authSuccess (45-49)
  • authSuccess (45-49)
  • initialLoginWithEmailResponse (217-234)
  • initialLoginWithEmailResponse (217-234)
  • nameCallback (166-176)
  • nameCallback (166-176)
  • MetadataMarketPlaceInitialize (1205-1250)
  • MetadataMarketPlaceInitialize (1205-1250)
  • initialBasicLogin (198-215)
  • initialBasicLogin (198-215)
  • recaptchaEnterpriseCallback (1310-1349)
  • recaptchaEnterpriseCallback (1310-1349)
  • authFail (40-43)
  • authFail (40-43)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • otpQRCodeCallbacks (500-584)
  • otpQRCodeCallbacks (500-584)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackSaml (604-621)
  • redirectCallbackSaml (604-621)
  • passwordCallback (277-286)
  • passwordCallback (277-286)
  • redirectCallback (586-603)
  • redirectCallback (586-603)
  • requestDeviceProfile (673-700)
  • requestDeviceProfile (673-700)
  • noSessionSuccess (424-424)
  • noSessionSuccess (424-424)
  • oauthTokens (13-20)
  • oauthTokens (13-20)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpired (31-38)
  • oauthTokensExpired (31-38)
  • redirectUrl (57-57)
  • redirectUrl (75-75)
  • userInfo (665-671)
  • userInfo (665-671)
e2e/am-mock-api/src/app/app.auth.js (2)
e2e/am-mock-api/src/app/routes.resource.js (2)
  • response (47-55)
  • response (70-70)
e2e/am-mock-api/src/app/env.config.js (4)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
e2e/am-mock-api/src/app/responses.js (2)
e2e/am-mock-api/src/app/routes.auth.js (5)
  • url (547-547)
  • redirectUrl (453-455)
  • redirectUrl (461-463)
  • redirectUrl (470-472)
  • redirectUrl (513-513)
e2e/am-mock-api/src/app/env.config.js (6)
  • amUrl (49-49)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • RESOURCE_URL (69-69)
  • RESOURCE_URL (69-69)
  • realm (36-36)
e2e/am-mock-api/src/index.js (2)
e2e/am-mock-api/src/app/app.auth.js (1)
  • authorizeApp (16-36)
e2e/am-mock-api/src/app/env.config.js (2)
  • MOCK_PORT (62-62)
  • MOCK_PORT (62-62)
🪛 Gitleaks (8.29.0)
e2e/am-mock-api/src/app/routes.auth.js

[high] 194-194: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Mend Code Security Check
🔇 Additional comments (11)
e2e/journey-app/utils/delete-webauthn-device.ts (3)

3-7: LGTM! Clean type-safe initialization.

The use of Parameters<typeof deviceClient>[0] provides excellent type inference while avoiding duplication. The function signature is clear and the initialization is straightforward.


8-12: Verify silent error handling is acceptable.

The function returns early without logging or propagating errors when device retrieval fails. While this might be intentional for a cleanup utility, it could make debugging test failures difficult if device deletion silently fails.

Consider whether errors should be logged or at least made visible for debugging:

 const devices = await dc.webAuthn.get({ userId, realm });

 if (!devices || 'error' in devices || !devices.length) {
+  if ('error' in devices) {
+    console.warn('Failed to retrieve WebAuthn devices for cleanup:', devices.error);
+  }
   return;
 }

14-16: Verify that deletion failures can be ignored.

The delete operations can return error objects (per the device client API), but the code doesn't check the return values. This means individual deletion failures are silently ignored. Confirm this is acceptable for this e2e cleanup utility.

If any deletion failures should be surfaced, consider:

for (const device of devices) {
  const result = await dc.webAuthn.delete({ userId, realm, device });
  if (result && 'error' in result) {
    console.warn('Failed to delete WebAuthn device:', result.error);
  }
}
packages/journey-client/src/lib/client.store.ts (1)

59-63: LGTM! Clean normalization implementation.

The config normalization is applied correctly before store creation and dispatch, ensuring all downstream code receives a consistent, normalized baseUrl.

packages/journey-client/src/lib/client.store.test.ts (1)

241-298: LGTM! Comprehensive test coverage for baseUrl normalization.

The test suite effectively validates the normalization logic across different baseUrl formats:

  • Adding trailing slash when absent
  • Preserving existing trailing slash
  • Handling baseUrl without context path

The integration testing approach is appropriate, as it verifies the observable behavior (correct URL construction) rather than testing implementation details.

package.json (2)

64-64: LGTM!

The addition of @nx/express aligns with the new Express-based mock API infrastructure introduced in this PR.


37-37: Verify the watch script change with git history and test watch command execution.

The watch script now targets vite:watch-deps instead of a potentially more general target. While this change is coordinated in nx.json's Vite plugin configuration, the only project.json discovered uses @nx/js:tsc (not Vite). This raises concerns:

  1. The vite:watch-deps target is auto-generated by @nx/vite/plugin for Vite-enabled projects only
  2. Non-Vite projects in the included scope (packages/**/**/*, e2e/**/**/*, tools/**/**/*) may not have this target
  3. Requires verification that non-Vite projects either skip gracefully or won't be affected by the watch command

Please verify:

  • What was the previous watch target (review git diff or commit history)
  • Test running pnpm watch to confirm it works for all projects in the monorepo
e2e/am-mock-api/.eslintrc.json (1)

1-30: LGTM!

The ESLint configuration follows standard patterns, properly extends the root configuration, and sets up appropriate ignore patterns for the mock API project.

e2e/am-mock-api/src/app/constants.js (1)

11-66: LGTM!

The authentication path definitions comprehensively cover various OAuth/OIDC flows, realm configurations, and session management endpoints needed for end-to-end testing scenarios.

e2e/am-mock-api/tsconfig.json (1)

1-13: LGTM!

Standard TypeScript project configuration using composite project references pattern.

tsconfig.json (1)

79-81: LGTM!

The new project reference properly integrates the mock API into the monorepo's TypeScript configuration.

Comment on lines +42 to +48
"lint": {
"options": {
"fix": true,
"ignore-path": ".eslintignore",
"args": ["**/*.ts"]
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Lint configuration excludes JavaScript files.

The lint target only includes TypeScript files (**/*.ts), but the project contains JavaScript files (e.g., index.js, routes.auth.js, routes.resource.js, app.auth.js). These files won't be linted with the current configuration.

Apply this diff to include JavaScript files:

     "lint": {
       "options": {
         "fix": true,
         "ignore-path": ".eslintignore",
-        "args": ["**/*.ts"]
+        "args": ["**/*.ts", "**/*.js"]
       }
     }
📝 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
"lint": {
"options": {
"fix": true,
"ignore-path": ".eslintignore",
"args": ["**/*.ts"]
}
}
"lint": {
"options": {
"fix": true,
"ignore-path": ".eslintignore",
"args": ["**/*.ts", "**/*.js"]
}
}
🤖 Prompt for AI Agents
In e2e/am-mock-api/project.json around lines 42 to 48, the lint args only target
TypeScript files ("**/*.ts"), so JavaScript files are omitted; update the args
to include JavaScript files as well (for example use a combined glob like
"**/*.{ts,js}" or add "**/*.js" alongside "**/*.ts") so the lint target picks up
.js files (keep existing options such as "fix" and "ignore-path" unchanged).

Comment on lines +21 to +58
// Ensure all domains are added to the security cert creation
app: process.env.NODE_ENV === 'LIVE' ? 'https://sdkapp.petrov.ca' : 'http://localhost',
forgeops: 'https://default.forgeops.petrov.ca',
mock: 'http://localhost',
resource: 'http://localhost',
};
const paths = {
am: '/am',
};
const ports = {
app: '8443',
forgeops: '443',
mock: '9443',
resource: '9443',
};
const realm = 'root';
const testUsers = [
{
// Already exists in forgeops...
pw: 'password',
un: 'sdkuser',
},
];

/**
* The below will be composed of the above values.
* Do not edit unless you know what you're doing.
*/
let amUrl;
let amPort;

if (env.LIVE) {
amUrl = origins.forgeops;
amPort = ports.forgeops;
} else {
amUrl = origins.mock;
amPort = ports.mock;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Stop mixing LIVE switches—this currently routes “LIVE” traffic to the mock AM URL.

With NODE_ENV='LIVE' (and no LIVE env var) the app picks the ForgeOps origin, but AM_URL keeps pointing at origins.mock because the later branch looks only at env.LIVE. Any “real” deployment will therefore call the mock AM host, breaking live auth. Conversely, setting LIVE="false" still activates the live branch because the string is truthy. Please collapse everything to a single boolean (e.g., const isLive = String(env.LIVE ?? env.NODE_ENV).toLowerCase() === 'live';) and reuse it for origins/ports/exports so live and non-live stay in sync. Also export the parsed ForgeOps hostname so callers stop comparing against the full URL (see routes.resource.js). -->

Comment on lines +159 to +189
app.get('/resource/rest/*', wait, authorization, async (req, res) => {
if (env.NODE_ENV === 'live') {
if (req.access.actions && req.access.actions.GET) {
res.json({ message: 'Successfully retrieved resource!' });
} else if (
req.access.advices &&
(req.access.advices.TransactionConditionAdvice ||
req.access.advices.AuthenticateToServiceConditionAdvice)
) {
res.json(req.access);
} else {
res.status(401).send();
}
} else {
if (
req.cookies.iPlanetDirectoryPro === 'abcd1234' &&
baz.canWithdraw &&
(req.headers['x-txid'] === authByTxnResponse.advices.TransactionConditionAdvice[0] ||
req.headers['x-tree'] ===
authByTreeResponse.advices.AuthenticateToServiceConditionAdvice[0])
) {
baz.canWithdraw = false;
res.json({ message: 'Successfully retrieved resource!' });
} else {
if (req.path.includes('authz-by-txn')) {
res.json(authByTxnResponse);
} else if (req.path.includes('authz-by-tree')) {
res.json(authByTreeResponse);
}
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

env.NODE_ENV === 'live' never hits when other code checks 'LIVE'.

Elsewhere you gate logic on 'LIVE' (uppercase). Here it’s lowercase, so LIVE requests fall through to the non-live branch, skipping policy outputs. Normalize once (e.g., reuse an isLive boolean from env.config). -->

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/app/routes.resource.js around lines 159 to 189, the
environment check uses env.NODE_ENV === 'live' while other code expects 'LIVE',
causing the live branch to never run; replace this direct lowercase comparison
with a normalized check (e.g., derive an isLive boolean once from env.NODE_ENV
by uppercasing or by reusing an existing env.config.isLive) and use that boolean
here so the live branch matches the rest of the codebase.

Comment on lines +43 to +48
if (env.NODE_ENV === 'LIVE') {
authorizeApp({
un: '9190fcce-d6d7-4473-9449-412f281f9bc6',
pw: '7fh9sj7*NP$%F6978',
});
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Authorization call should be awaited.

The authorizeApp call is not awaited, which could lead to race conditions if the mock routes depend on the session being established before handling requests. Consider awaiting the call or documenting that the session initializes asynchronously.

Apply this diff:

 if (env.NODE_ENV === 'LIVE') {
-  authorizeApp({
+  await authorizeApp({
     un: '9190fcce-d6d7-4473-9449-412f281f9bc6',
     pw: '7fh9sj7*NP$%F6978',
   });
 }

Note: This requires wrapping the initialization in an async IIFE or refactoring the startup logic.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In e2e/am-mock-api/src/index.js around lines 43 to 48, the authorizeApp call is
invoked but not awaited which can cause race conditions; wrap the startup in an
async IIFE (or convert the surrounding init function to async), await
authorizeApp(...) and handle potential errors (try/catch or .catch) so the mock
routes only start after authorization completes; ensure the server/router
initialization that depends on the session is executed after the awaited call.

@ryanbas21 ryanbas21 force-pushed the migrate-am-mock-api branch 2 times, most recently from 7803632 to 2a70f3f Compare November 11, 2025 18:38
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (17)
e2e/am-mock-api/src/environments/environment.ts (1)

8-8: Fix type mismatch: production should be false (boolean).

The production property is set to the string 'development', but based on environment.prod.ts it should be a boolean. This inconsistency can cause runtime errors if code performs boolean checks.

Apply this diff:

-  production: 'development',
+  production: false,
e2e/am-mock-api/src/app/env.config.js (2)

11-11: Fix module type mismatch: ESM syntax requires "type": "module".

The package.json specifies "type": "commonjs", but this file uses ESM syntax (import/export). This will cause runtime failures in Node.js.

Update e2e/am-mock-api/package.json:

-  "type": "commonjs",
+  "type": "module",

21-58: Consolidate LIVE environment detection to avoid routing inconsistencies.

The code mixes three forms of LIVE detection: env.LIVE, process.env.NODE_ENV === 'LIVE', and lowercase 'live' elsewhere. This causes mismatched behavior where LIVE traffic may route to mock AM URLs or vice versa.

Centralize to a single boolean check:

+const isLive = String(env.LIVE || env.NODE_ENV).toLowerCase() === 'live';
 const origins = {
-  app: process.env.NODE_ENV === 'LIVE' ? 'https://sdkapp.petrov.ca' : 'http://localhost',
+  app: isLive ? 'https://sdkapp.petrov.ca' : 'http://localhost',
   forgeops: 'https://default.forgeops.petrov.ca',
   mock: 'http://localhost',
   resource: 'http://localhost',
 };
 
 let amUrl;
 let amPort;
 
-if (env.LIVE) {
+if (isLive) {
   amUrl = origins.forgeops;
   amPort = ports.forgeops;
 } else {
   amUrl = origins.mock;
   amPort = ports.mock;
 }
 
 export const FORGEOPS = origins.forgeops;
+export const FORGEOPS_HOST = new URL(FORGEOPS).hostname;
e2e/am-mock-api/src/app/routes.resource.js (5)

27-29: Fix hostname comparison bug: comparing hostname to full URL.

req.hostname returns a hostname (e.g., default.forgeops.petrov.ca) while FORGEOPS is a full URL (https://default.forgeops.petrov.ca). The comparison will always fail, breaking LIVE logic.

Apply this diff:

-import { AM_URL, AM_PORT, FORGEOPS, REALM_PATH } from './env.config.js';
+import { AM_URL, AM_PORT, FORGEOPS_HOST, REALM_PATH } from './env.config.js';

-  if (env.NODE_ENV === 'LIVE' && req.hostname !== FORGEOPS) {
+  if (env.NODE_ENV === 'LIVE' && req.hostname !== FORGEOPS_HOST) {

47-56: Add error handling and timeouts for external policy evaluation calls.

Unguarded superagent calls can crash the server on network failures or hangs.

Apply this diff:

-    const response = await request
+    let response;
+    try {
+      response = await request
       .post(`${AM_URL}/json/${realms}/policies/?_action=evaluate`)
       .set('Content-Type', 'application/json')
       .set('Accept-API-Version', 'resource=2.1')
       .set('iPlanetDirectoryPro', session.tokenId)
+      .timeout({ response: 5000, deadline: 15000 })
-      .send(body);
+      .send(body);
+    } catch (err) {
+      console.error('Policy evaluate failed:', err.message);
+      req.access = {};
+      return res.status(502).send();
+    }

71-95: Add error handling and timeouts for OAuth introspection and SSO validation.

These external calls lack error handling and can crash or hang the server.

Wrap both OAuth introspection and SSO validation in try/catch blocks with timeouts:

       if (req.headers.authorization) {
         const authHeaderArr = req.headers.authorization.split(' ');
+        try {
         response = await request
           .post(`${AM_URL}/oauth2/introspect`)
           .set('Content-Type', 'application/json')
           .set('iPlanetDirectoryPro', session.tokenId)
           .set('Accept-API-Version', 'resource=1.2')
+          .timeout({ response: 5000, deadline: 15000 })
           .send({ token: authHeaderArr[1] });
+        } catch (e) {
+          console.error('Introspect failed:', e.message);
+          return res.status(502).send();
+        }
       } else {
+        try {
         response = await request
           .post(`${AM_URL}/json/sessions/?_action=validate`)
           .set('Content-Type', 'application/json')
           .set('iPlanetDirectoryPro', session.tokenId)
           .set('Accept-API-Version', 'resource=2.1, protocol=1.0')
+          .timeout({ response: 5000, deadline: 15000 })
           .send({ tokenId: req.cookies.iPlanetDirectoryPro });
+        } catch (e) {
+          console.error('SSO validate failed:', e.message);
+          return res.status(502).send();
+        }
       }

121-154: Guard against missing Referer header and use proper Express API.

req.headers.referer.includes('json') will throw if the header is absent; res.send(401, ...) is deprecated in Express.

Apply this diff to both occurrences (lines 121-130 and 145-154):

+        const referer = req.headers.referer || '';
         if (
-          req.headers['x-authenticate-response'] &&
           req.headers['x-authenticate-response'] === 'header' &&
-          req.headers.referer.includes('json')
+          referer.includes('json')
         ) {
-          res.setHeader('WWW-Authenticate', createTxnStepUpHeader(req.headers.referer));
+          res.setHeader('WWW-Authenticate', createTxnStepUpHeader(referer));
-          res.send(401, null);
+          res.sendStatus(401);
         } else {
-          res.redirect(307, createTxnStepUpUrl(req.headers.referer));
+          res.redirect(307, createTxnStepUpUrl(referer));
         }

159-189: Fix environment check case mismatch.

Line 160 uses lowercase 'live' while other code checks for uppercase 'LIVE', causing the live branch to never execute.

Replace the direct string comparison with a normalized check:

-  if (env.NODE_ENV === 'live') {
+  const isLive = String(env.LIVE || env.NODE_ENV).toLowerCase() === 'live';
+  if (isLive) {
e2e/am-mock-api/src/app/routes.auth.js (4)

55-55: Remove password logging to avoid leaking secrets.

This logs a clear-text test password unconditionally.

Apply this diff:

-console.log(`Your user password from 'env.config' file: ${USERS[0].pw}`);
+// Password logging removed to avoid leaking secrets in logs

449-475: Guard against missing Referer header.

new URL(req.get('Referer')) will throw if the header is missing or invalid.

Apply this diff to all three occurrences:

     if (req.url.includes('SAMLFailure')) {
-      const referrer = new URL(req.get('Referer'));
+      const refHdr = req.get('Referer') || `${req.protocol}://${req.headers.host}/`;
+      const referrer = new URL(refHdr);

541-546: Fix domain detection: use req.hostname instead of req.url.

req.url contains the path/query string, not the hostname. The check will never see 'localhost'.

Apply this diff:

-    const domain = req.url.includes('localhost') ? 'localhost' : 'example.com';
+    const domain = req.hostname === 'localhost' ? 'localhost' : 'example.com';

585-586: Fix typo: duplicated word in error message.

-        res.status(406).send('Middleware additions are missing missing.');
+        res.status(406).send('Middleware additions are missing.');
e2e/am-mock-api/src/app/responses.js (5)

11-11: Change "type" to "module" in package.json.

All source files use ESM syntax but the package is configured as CommonJS, causing parse errors.

Update e2e/am-mock-api/package.json:

-  "type": "commonjs",
+  "type": "module",

51-68: Remove debug log and guard URL parsing.

console.log(url) is noisy; new URL(url) throws if url is falsy/invalid.

Apply this diff:

 export const createTxnStepUpUrl = (url) => {
-  console.log(url);
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl');

70-86: Apply the same URL parsing resilience as createTxnStepUpUrl.

This function has the same vulnerability: new URL(url) throws on falsy/invalid input.

Apply this diff:

 export const createTreeStepUpUrl = (url) => {
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl');

88-99: Guard against invalid URL in createTxnStepUpHeader.

Unguarded new URL(url) will throw if url is falsy or malformed.

Apply this diff:

 export const createTxnStepUpHeader = (url) => {
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl') || AM_URL;

101-112: Guard against invalid URL in createTreeStepUpHeader.

Same issue: unguarded new URL(url) will throw for falsy/malformed input.

Apply this diff:

 export const createTreeStepUpHeader = (url) => {
-  const referer = new URL(url);
+  const safe = url || 'http://localhost/';
+  const referer = new URL(safe);
   const amUrl = referer.searchParams.get('amUrl') || AM_URL;
🧹 Nitpick comments (2)
e2e/am-mock-api/package.json (1)

10-18: Consider moving @types/express to devDependencies.

Type definitions for Express are only needed at build/compilation time, not at runtime. Moving @types/express to a devDependencies section (if one is added) will keep the production dependency tree cleaner and avoid installing unused types in production environments.

If a devDependencies section is added to this package.json, apply this diff:

  "dependencies": {
-   "@types/express": "^4.17.17",
    "body-parser": "^2.2.0",
    "cookie-parser": "^1.4.7",
    "cors": "^2.8.5",
    "express": "^4.21.2",
    "superagent": "^10.2.3",
    "uuid": "^13.0.0"
+ },
+ "devDependencies": {
+   "@types/express": "^4.17.17"
  }
packages/journey-client/src/lib/client.store.test.ts (1)

241-298: Good test coverage for baseUrl normalization.

The test suite properly validates the normalization behavior across different baseUrl configurations (without trailing slash, with trailing slash, and without context path). All assertions correctly verify the constructed URLs.

Note: The AI summary mentions "The same 'baseUrl normalization' test suite appears duplicated, resulting in two identical test blocks," but only one describe block is present in the provided code.

Optional refinement: Consider parameterizing these structurally identical tests using test.each to reduce duplication and improve maintainability:

  describe('baseUrl normalization', () => {
-   test('should add trailing slash to baseUrl without one', async () => {
-     const configWithoutSlash: JourneyClientConfig = {
-       serverConfig: {
-         baseUrl: 'http://localhost:9443/am',
-       },
-       realmPath: 'root',
-     };
-
-     const mockStepResponse: Step = { authId: 'test-auth-id', callbacks: [] };
-     mockFetch.mockResolvedValue(new Response(JSON.stringify(mockStepResponse)));
-
-     const client = await journey({ config: configWithoutSlash });
-     await client.start();
-
-     expect(mockFetch).toHaveBeenCalledTimes(1);
-     const request = mockFetch.mock.calls[0][0] as Request;
-     expect(request.url).toBe('http://localhost:9443/am/json/realms/root/authenticate');
-   });
-
-   test('should preserve trailing slash if already present', async () => {
-     const configWithSlash: JourneyClientConfig = {
-       serverConfig: {
-         baseUrl: 'http://localhost:9443/am/',
-       },
-       realmPath: 'root',
-     };
-
-     const mockStepResponse: Step = { authId: 'test-auth-id', callbacks: [] };
-     mockFetch.mockResolvedValue(new Response(JSON.stringify(mockStepResponse)));
-
-     const client = await journey({ config: configWithSlash });
-     await client.start();
-
-     expect(mockFetch).toHaveBeenCalledTimes(1);
-     const request = mockFetch.mock.calls[0][0] as Request;
-     expect(request.url).toBe('http://localhost:9443/am/json/realms/root/authenticate');
-   });
-
-   test('should work with baseUrl without context path', async () => {
-     const configNoContext: JourneyClientConfig = {
-       serverConfig: {
-         baseUrl: 'http://localhost:9443',
-       },
-       realmPath: 'root',
-     };
-
-     const mockStepResponse: Step = { authId: 'test-auth-id', callbacks: [] };
-     mockFetch.mockResolvedValue(new Response(JSON.stringify(mockStepResponse)));
-
-     const client = await journey({ config: configNoContext });
-     await client.start();
-
-     expect(mockFetch).toHaveBeenCalledTimes(1);
-     const request = mockFetch.mock.calls[0][0] as Request;
-     expect(request.url).toBe('http://localhost:9443/json/realms/root/authenticate');
-   });
+   test.each([
+     {
+       name: 'should add trailing slash to baseUrl without one',
+       baseUrl: 'http://localhost:9443/am',
+       expected: 'http://localhost:9443/am/json/realms/root/authenticate',
+     },
+     {
+       name: 'should preserve trailing slash if already present',
+       baseUrl: 'http://localhost:9443/am/',
+       expected: 'http://localhost:9443/am/json/realms/root/authenticate',
+     },
+     {
+       name: 'should work with baseUrl without context path',
+       baseUrl: 'http://localhost:9443',
+       expected: 'http://localhost:9443/json/realms/root/authenticate',
+     },
+   ])('$name', async ({ baseUrl, expected }) => {
+     const config: JourneyClientConfig = {
+       serverConfig: { baseUrl },
+       realmPath: 'root',
+     };
+
+     const mockStepResponse: Step = { authId: 'test-auth-id', callbacks: [] };
+     mockFetch.mockResolvedValue(new Response(JSON.stringify(mockStepResponse)));
+
+     const client = await journey({ config });
+     await client.start();
+
+     expect(mockFetch).toHaveBeenCalledTimes(1);
+     const request = mockFetch.mock.calls[0][0] as Request;
+     expect(request.url).toBe(expected);
+   });
  });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e7af4e and 2a70f3f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (28)
  • .node-version (1 hunks)
  • e2e/am-mock-api/.babelrc (1 hunks)
  • e2e/am-mock-api/.eslintrc.json (1 hunks)
  • e2e/am-mock-api/package.json (1 hunks)
  • e2e/am-mock-api/project.json (1 hunks)
  • e2e/am-mock-api/src/app/app.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/constants.js (1 hunks)
  • e2e/am-mock-api/src/app/env.config.js (1 hunks)
  • e2e/am-mock-api/src/app/response.registration.js (1 hunks)
  • e2e/am-mock-api/src/app/responses.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.resource.js (1 hunks)
  • e2e/am-mock-api/src/app/wait.js (1 hunks)
  • e2e/am-mock-api/src/environments/environment.prod.ts (1 hunks)
  • e2e/am-mock-api/src/environments/environment.ts (1 hunks)
  • e2e/am-mock-api/src/index.js (1 hunks)
  • e2e/am-mock-api/tsconfig.app.json (1 hunks)
  • e2e/am-mock-api/tsconfig.json (1 hunks)
  • e2e/am-mock-api/tsconfig.spec.json (1 hunks)
  • e2e/davinci-suites/src/phone-number-field.test.ts (1 hunks)
  • e2e/journey-app/main.ts (3 hunks)
  • e2e/journey-app/server-configs.ts (1 hunks)
  • e2e/journey-suites/playwright.config.ts (1 hunks)
  • e2e/journey-suites/src/login.test.ts (1 hunks)
  • package.json (2 hunks)
  • packages/journey-client/src/lib/client.store.test.ts (1 hunks)
  • packages/journey-client/src/lib/client.store.ts (2 hunks)
  • tsconfig.json (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • e2e/am-mock-api/.eslintrc.json
  • .node-version
🚧 Files skipped from review as they are similar to previous changes (17)
  • e2e/am-mock-api/tsconfig.json
  • e2e/am-mock-api/tsconfig.app.json
  • e2e/am-mock-api/src/app/constants.js
  • e2e/am-mock-api/src/app/app.auth.js
  • e2e/am-mock-api/src/app/wait.js
  • e2e/am-mock-api/project.json
  • package.json
  • e2e/journey-app/server-configs.ts
  • e2e/davinci-suites/src/phone-number-field.test.ts
  • e2e/am-mock-api/tsconfig.spec.json
  • e2e/journey-app/main.ts
  • packages/journey-client/src/lib/client.store.ts
  • tsconfig.json
  • e2e/am-mock-api/src/index.js
  • e2e/am-mock-api/.babelrc
  • e2e/am-mock-api/src/environments/environment.prod.ts
  • e2e/journey-suites/src/login.test.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-27T17:55:33.855Z
Learnt from: cerebrl
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: e2e/journey-app/main.ts:83-87
Timestamp: 2025-10-27T17:55:33.855Z
Learning: In the e2e/journey-app and similar e2e test applications in this repository, XSS hardening and similar production security practices are not required since these are exclusively test/development applications.

Applied to files:

  • packages/journey-client/src/lib/client.store.test.ts
🧬 Code graph analysis (6)
packages/journey-client/src/lib/client.store.test.ts (2)
packages/journey-client/src/lib/config.types.ts (1)
  • JourneyClientConfig (11-15)
packages/journey-client/src/lib/client.store.ts (1)
  • journey (45-194)
e2e/am-mock-api/src/environments/environment.ts (1)
e2e/am-mock-api/src/environments/environment.prod.ts (1)
  • environment (1-3)
e2e/am-mock-api/src/app/env.config.js (1)
e2e/am-mock-api/src/app/responses.js (6)
  • realm (96-96)
  • realm (109-109)
  • amUrl (55-55)
  • amUrl (73-73)
  • amUrl (91-91)
  • amUrl (104-104)
e2e/am-mock-api/src/app/routes.resource.js (5)
e2e/am-mock-api/src/app/env.config.js (8)
  • FORGEOPS (67-67)
  • FORGEOPS (67-67)
  • AM_PORT (61-61)
  • AM_PORT (61-61)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/app.auth.js (3)
  • response (18-24)
  • session (14-14)
  • session (14-14)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/routes.auth.js (2)
  • baz (57-59)
  • baz (57-59)
e2e/am-mock-api/src/app/responses.js (12)
  • authByTxnResponse (124-132)
  • authByTxnResponse (124-132)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpUrl (51-68)
  • createTxnStepUpUrl (51-68)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpUrl (70-86)
  • createTreeStepUpUrl (70-86)
  • authByTreeResponse (114-122)
  • authByTreeResponse (114-122)
e2e/am-mock-api/src/app/responses.js (2)
e2e/am-mock-api/src/app/routes.auth.js (5)
  • url (547-547)
  • redirectUrl (453-455)
  • redirectUrl (461-463)
  • redirectUrl (470-472)
  • redirectUrl (513-513)
e2e/am-mock-api/src/app/env.config.js (6)
  • amUrl (49-49)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • RESOURCE_URL (69-69)
  • RESOURCE_URL (69-69)
  • realm (36-36)
e2e/am-mock-api/src/app/routes.auth.js (4)
e2e/am-mock-api/src/app/env.config.js (4)
  • USERS (71-71)
  • USERS (71-71)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/constants.js (2)
  • authPaths (11-66)
  • authPaths (11-66)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/responses.js (66)
  • txnAuthz (640-651)
  • txnAuthz (640-651)
  • treeAuthz (652-663)
  • treeAuthz (652-663)
  • initialMiscCallbacks (266-275)
  • initialMiscCallbacks (266-275)
  • initialPlatformLogin (236-264)
  • initialPlatformLogin (236-264)
  • authSuccess (45-49)
  • authSuccess (45-49)
  • initialLoginWithEmailResponse (217-234)
  • initialLoginWithEmailResponse (217-234)
  • nameCallback (166-176)
  • nameCallback (166-176)
  • pingProtectInitialize (313-368)
  • pingProtectInitialize (313-368)
  • selectIdPCallback (439-485)
  • selectIdPCallback (439-485)
  • MetadataMarketPlaceInitialize (1205-1250)
  • MetadataMarketPlaceInitialize (1205-1250)
  • initialBasicLogin (198-215)
  • initialBasicLogin (198-215)
  • recaptchaEnterpriseCallback (1310-1349)
  • recaptchaEnterpriseCallback (1310-1349)
  • authFail (40-43)
  • authFail (40-43)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • otpQRCodeCallbacks (500-584)
  • otpQRCodeCallbacks (500-584)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackSaml (604-621)
  • redirectCallbackSaml (604-621)
  • textInputCallback (177-196)
  • textInputCallback (177-196)
  • passwordCallback (277-286)
  • passwordCallback (277-286)
  • messageCallback (400-422)
  • messageCallback (400-422)
  • pollingCallback (426-437)
  • pollingCallback (426-437)
  • secondFactorChoiceCallback (385-398)
  • secondFactorChoiceCallback (385-398)
  • secondFactorCallback (487-498)
  • secondFactorCallback (487-498)
  • redirectCallback (586-603)
  • redirectCallback (586-603)
  • pingProtectEvaluate (288-311)
  • pingProtectEvaluate (288-311)
  • noSessionSuccess (424-424)
  • noSessionSuccess (424-424)
  • oauthTokens (13-20)
  • oauthTokens (13-20)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpired (31-38)
  • oauthTokensExpired (31-38)
  • redirectUrl (57-57)
  • redirectUrl (75-75)
  • userInfo (665-671)
  • userInfo (665-671)
  • wellKnownForgeRock (702-1033)
  • wellKnownForgeRock (702-1033)
  • newPiWellKnown (1124-1203)
  • newPiWellKnown (1124-1203)
🪛 Gitleaks (8.29.0)
e2e/am-mock-api/src/app/routes.auth.js

[high] 194-194: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: pr
🔇 Additional comments (3)
e2e/am-mock-api/package.json (1)

11-11: Good catch on the previous fix—@types/express is now correctly aligned with Express v4.

The @types/express version has been corrected to v4.17.17, which properly matches the installed Express v4.21.2 runtime. This resolves the prior critical incompatibility issue.

e2e/journey-suites/playwright.config.ts (1)

40-46: Based on the verification results, all integration points between the mock API server, journey-app configuration, and Playwright setup are correctly aligned:

  • The @nx/js:node executor runs the output of a build target, so pnpm nx serve am-mock-api will correctly build and start the mock API server
  • Journey-app is configured to use the correct endpoint at http://localhost:9443/am
  • The Playwright webServer configuration for port 9443 matches the expected endpoint
  • The reuseExistingServer: !process.env.CI pattern prevents server conflicts between local development and CI environments

The ignoreHTTPSErrors: true setting is unnecessary for an HTTP endpoint but harmless—it's only required for HTTPS certificate errors.

Port conflict resolved; mock API integration verified.

The port conflict from the previous review has been successfully addressed. The am-mock-api server now runs on port 9443 while journey-app remains on 5829, and journey-app is correctly configured to communicate with the mock API at http://localhost:9443/am.

Note: The ignoreHTTPSErrors: true flag is unnecessary since the endpoint uses HTTP rather than HTTPS. Consider removing it or adding a comment explaining if this is intentional for future HTTPS support.

e2e/am-mock-api/src/app/response.registration.js (1)

11-224: LGTM!

The registration mock response is well-structured and provides comprehensive coverage of the registration flow with appropriate callback types, validation policies, and prompts for e2e testing.

nx-cloud[bot]

This comment was marked as outdated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
e2e/journey-suites/src/login.test.ts (1)

10-10: Minor: Unrelated import order change.

The import order was changed from { username, password } to { password, username }. This appears unrelated to the main refactoring and doesn't affect functionality.

If this was an accidental change, consider reverting to maintain consistency with other test files (e.g., choice-confirm-poll.test.ts line 10 and no-session.test.ts line 10 still use { username, password }). Otherwise, consider applying the same alphabetical ordering across all test files for consistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a70f3f and 26c66a5.

📒 Files selected for processing (10)
  • e2e/journey-suites/src/choice-confirm-poll.test.ts (2 hunks)
  • e2e/journey-suites/src/custom-paths.test.ts (1 hunks)
  • e2e/journey-suites/src/device-profile.test.ts (1 hunks)
  • e2e/journey-suites/src/email-suspend.test.ts (1 hunks)
  • e2e/journey-suites/src/login.test.ts (1 hunks)
  • e2e/journey-suites/src/no-session.test.ts (2 hunks)
  • e2e/journey-suites/src/otp-register.test.ts (1 hunks)
  • e2e/journey-suites/src/protect.test.ts (1 hunks)
  • e2e/journey-suites/src/registration.test.ts (2 hunks)
  • e2e/journey-suites/src/request-middleware.test.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (9)
e2e/journey-suites/src/no-session.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/registration.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/custom-paths.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/protect.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/email-suspend.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/device-profile.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/choice-confirm-poll.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/login.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (2)
  • asyncEvents (7-76)
  • navigate (54-56)
e2e/journey-suites/src/request-middleware.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Mend Code Security Check
  • GitHub Check: pr
🔇 Additional comments (10)
e2e/journey-suites/src/otp-register.test.ts (1)

14-14: Tree-based navigation aligns with mock API

Switching the OTP registration flow to tree=TEST_OTPRegistration keeps this journey in sync with the new AM mock API routing. Looks good.

e2e/journey-suites/src/registration.test.ts (1)

14-26: Consistent tree routing update

Matching the navigate call and URL assertion to tree=Registration keeps this flow aligned with the tree-based journeys introduced by the mock API. Looks solid.

e2e/journey-suites/src/request-middleware.test.ts (1)

14-36: Tree parameter covers middleware flow

Updating both the navigation URL and assertion to tree=Login keeps this middleware scenario pointed at the correct journey under the new mock API structure. Good to go.

e2e/journey-suites/src/email-suspend.test.ts (1)

14-14: Email suspend journey hooked to tree route

The shift to tree=TEST_LoginSuspendEmail keeps this test aligned with the tree-based journeys. Looks correct.

e2e/journey-suites/src/protect.test.ts (1)

14-14: Protect flow routed via tree parameter

Using tree=TEST_Protect keeps this skipped protect scenario consistent with the migrated routing. No issues spotted.

e2e/journey-suites/src/device-profile.test.ts (1)

14-14: Device profile journey now uses tree routing

Pointing the device profile test at tree=TEST_DeviceProfile keeps it in sync with the rest of the tree-based migrations. Looks good.

e2e/journey-suites/src/choice-confirm-poll.test.ts (1)

14-14: LGTM! Consistent parameter migration from journey to tree.

The navigation and URL assertion have been updated consistently to use the tree query parameter instead of journey, aligning with the mock API migration.

Also applies to: 24-24

e2e/journey-suites/src/custom-paths.test.ts (1)

15-15: Parameter change looks good, but verify the skip status.

The navigation parameter change from journey to tree is consistent with the broader refactoring.

However, this test remains skipped with a comment stating "Skipping test until AM Mock API is available that supports custom paths" (line 12). Given that this PR is adding the mock API, please verify whether:

  1. The custom paths feature is intentionally not yet supported in the new mock API
  2. The test should now be enabled, or
  3. The skip comment should be updated to clarify the timeline
e2e/journey-suites/src/login.test.ts (1)

14-14: LGTM! Navigation updated to use tree parameter.

The navigation change from /?journey=Login to /?tree=Login is consistent with the mock API migration applied across other test files.

e2e/journey-suites/src/no-session.test.ts (1)

14-14: LGTM! Consistent parameter migration from journey to tree.

Both the navigation path and URL assertion have been updated consistently to use the tree query parameter instead of journey, maintaining the no-session=true parameter alongside it.

Also applies to: 24-24

nx-cloud[bot]

This comment was marked as outdated.

Copy link

@coderabbitai coderabbitai bot left a comment

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)
e2e/journey-app/main.ts (1)

21-21: Consider a more descriptive variable name to address the 'tree' vs 'journey' terminology concern.

Based on the past review comments, there's a preference for using 'journey' terminology instead of 'tree' since 'tree' is outdated. While journey conflicts with the imported function, alternative names like journeyName, authTree, or flowName could address both the namespace conflict and the terminology preference.

For example:

-const tree = searchParams.get('tree') ?? 'UsernamePassword';
+const journeyName = searchParams.get('tree') ?? 'UsernamePassword';

Then update references accordingly throughout the file (lines 59, 86).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26c66a5 and dcc6554.

📒 Files selected for processing (1)
  • e2e/journey-app/main.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
e2e/journey-app/main.ts (1)
packages/journey-client/src/lib/client.store.ts (1)
  • journey (45-194)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Mend Code Security Check
  • GitHub Check: pr
🔇 Additional comments (1)
e2e/journey-app/main.ts (1)

85-88: LGTM! Logout restart logic correctly preserves journey state.

The logout flow now properly restarts the journey using the same tree parameter and preserves the noSession query parameter, ensuring consistent behavior after logout. This mirrors the initial start call and maintains proper state management.


(async () => {
const journeyClient = await journey({ config, requestMiddleware });
const journeyClient = await journey({ config: config, requestMiddleware });
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Restore property shorthand syntax.

The change from config to config: config is unnecessary and verbose. Modern JavaScript/TypeScript supports property shorthand notation, which is more concise and idiomatic.

Apply this diff:

-  const journeyClient = await journey({ config: config, requestMiddleware });
+  const journeyClient = await journey({ config, requestMiddleware });
📝 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
const journeyClient = await journey({ config: config, requestMiddleware });
const journeyClient = await journey({ config, requestMiddleware });
🤖 Prompt for AI Agents
In e2e/journey-app/main.ts around line 52, the object passed to journey uses the
verbose property form "config: config" instead of the shorthand; change the call
to use property shorthand by passing "config" (i.e., replace the verbose
property with the concise "config") while keeping requestMiddleware as-is so the
call becomes journey({ config, requestMiddleware }).

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

migrate old mock api to repo

chore: fix-tests
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (15)
e2e/am-mock-api/src/app/app.auth.js (1)

14-36: Previously flagged issues remain unaddressed.

The mutable module-level session state (line 14) and the catch block that swallows errors (lines 31-35) were already identified in previous reviews. Please address those concerns before merging.

e2e/am-mock-api/src/app/env.config.js (1)

11-71: Previously flagged critical issues remain unaddressed.

The module type mismatch (ESM syntax with CommonJS package.json) and inconsistent LIVE environment detection (line 22 uses NODE_ENV, line 52 uses env.LIVE) were already identified as critical issues in previous reviews. Please resolve these before merging.

e2e/am-mock-api/src/app/wait.js (1)

13-15: Module system mismatch still present.

The ES6 export syntax (export default) remains incompatible with CommonJS module system. This critical issue was previously flagged but appears unresolved.

e2e/am-mock-api/src/app/routes.resource.js (5)

27-29: Host comparison bug: comparing hostname to full URL.

req.hostname returns a hostname like default.forgeops.petrov.ca, while FORGEOPS contains a full URL like https://default.forgeops.petrov.ca. This comparison will always fail, breaking the LIVE logic.


47-56: Add error handling and timeouts for external policy evaluation call.

The superagent POST to AM_URL is unguarded and can throw on network failures or hang indefinitely, crashing the server.


71-88: Add error handling and timeouts for OAuth introspection.

The OAuth introspection call lacks timeout and error handling, which can crash or hang the server on network failures.


121-130: Guard against missing Referer header and use proper 401 API.

req.headers.referer.includes('json') will throw if the Referer header is absent. Additionally, res.send(401, ...) is deprecated Express syntax.


159-189: Environment check uses lowercase 'live' instead of 'LIVE'.

The code checks env.NODE_ENV === 'live' (lowercase) while other parts of the codebase use 'LIVE' (uppercase), causing the live branch to never execute.

e2e/am-mock-api/src/app/routes.auth.js (3)

55-55: Remove password logging to avoid exposing secrets.

This console.log prints a clear-text password from the test configuration, which should not be logged even in test environments.


449-475: Guard against missing Referer header in accounts route.

new URL(req.get('Referer')) will throw if the Referer header is absent or invalid across all three branches (SAMLFailure, SAMLTest, and default).


585-586: Fix duplicated word in error message.

The error message contains "missing missing" - remove the duplicate word.

e2e/am-mock-api/src/app/responses.js (4)

51-58: Remove debug log and guard against invalid URL input.

console.log(url) adds noise, and new URL(url) will throw if url is falsy or malformed. Add defensive URL parsing.


70-86: Guard against invalid URL in createTreeStepUpUrl.

new URL(url) can throw for falsy or invalid input. Apply the same defensive pattern as suggested for createTxnStepUpUrl.


88-99: Guard against invalid URL in createTxnStepUpHeader.

new URL(url) is unguarded and will throw for falsy or malformed input.


101-112: Guard against invalid URL in createTreeStepUpHeader.

new URL(url) will throw if url is falsy or malformed. Add try/catch or validate input before parsing.

🧹 Nitpick comments (2)
e2e/am-mock-api/.eslintrc.json (1)

1-30: Simplify the ESLint configuration structure.

The configuration has some unconventional patterns that could be simplified:

  • Line 3: The top-level ignorePatterns: ["!**/*"] (negation pattern) is confusing and contradicts the override's explicit ignore patterns. This pattern typically isn't used at the top level.
  • Lines 17–28: The three overrides with empty rule sets ("rules": {}) for different file patterns are redundant and don't enforce any rules.

Since this is a test/dev mock API project, a permissive linting baseline is appropriate. However, the configuration could be clearer and more maintainable by removing unnecessary overrides and the confusing negation pattern.

Here's a simplified alternative:

{
  "extends": ["../../.eslintrc.json"],
  "overrides": [
    {
      "files": ["**/*"],
      "ignorePatterns": [
        "node_modules",
        "*.md",
        "LICENSE",
        ".babelrc",
        ".env*",
        ".bin",
        "dist",
        ".eslintignore"
      ]
    }
  ]
}

Alternatively, if no additional rules or ignores are needed beyond the parent config, you could simplify to:

{
  "extends": ["../../.eslintrc.json"]
}
e2e/journey-app/server-configs.ts (1)

10-21: Good approach addressing the previous feedback.

The addition of the separate tenant configuration preserves the original remote test tenant while allowing basic to use the local mock API. This addresses cerebrl's concern about replacing the shared test tenant.

Consider renaming these configurations for better clarity: basicmock (or local) and tenantremote (or keep tenant). This would make the purpose of each configuration immediately clear to developers.

Example refactor:

 export const serverConfigs: Record<string, JourneyClientConfig> = {
-  basic: {
+  mock: {
     serverConfig: {
       baseUrl: 'http://localhost:9443/am',
     },
     realmPath: 'root',
   },
-  tenant: {
+  remote: {
     serverConfig: {
       baseUrl: 'https://openam-sdks.forgeblocks.com/am',
     },
     realmPath: 'alpha',
   },
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54dfc81 and bc3da80.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (38)
  • .node-version (1 hunks)
  • e2e/am-mock-api/.babelrc (1 hunks)
  • e2e/am-mock-api/.eslintrc.json (1 hunks)
  • e2e/am-mock-api/package.json (1 hunks)
  • e2e/am-mock-api/project.json (1 hunks)
  • e2e/am-mock-api/src/app/app.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/constants.js (1 hunks)
  • e2e/am-mock-api/src/app/env.config.js (1 hunks)
  • e2e/am-mock-api/src/app/response.registration.js (1 hunks)
  • e2e/am-mock-api/src/app/responses.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.auth.js (1 hunks)
  • e2e/am-mock-api/src/app/routes.resource.js (1 hunks)
  • e2e/am-mock-api/src/app/wait.js (1 hunks)
  • e2e/am-mock-api/src/environments/environment.prod.ts (1 hunks)
  • e2e/am-mock-api/src/environments/environment.ts (1 hunks)
  • e2e/am-mock-api/src/index.js (1 hunks)
  • e2e/am-mock-api/tsconfig.app.json (1 hunks)
  • e2e/am-mock-api/tsconfig.json (1 hunks)
  • e2e/am-mock-api/tsconfig.spec.json (1 hunks)
  • e2e/davinci-suites/src/phone-number-field.test.ts (1 hunks)
  • e2e/journey-app/main.ts (3 hunks)
  • e2e/journey-app/server-configs.ts (1 hunks)
  • e2e/journey-suites/playwright.config.ts (1 hunks)
  • e2e/journey-suites/src/choice-confirm-poll.test.ts (2 hunks)
  • e2e/journey-suites/src/custom-paths.test.ts (1 hunks)
  • e2e/journey-suites/src/device-profile.test.ts (1 hunks)
  • e2e/journey-suites/src/email-suspend.test.ts (1 hunks)
  • e2e/journey-suites/src/login.test.ts (1 hunks)
  • e2e/journey-suites/src/no-session.test.ts (2 hunks)
  • e2e/journey-suites/src/otp-register.test.ts (1 hunks)
  • e2e/journey-suites/src/protect.test.ts (1 hunks)
  • e2e/journey-suites/src/registration.test.ts (2 hunks)
  • e2e/journey-suites/src/request-middleware.test.ts (2 hunks)
  • e2e/journey-suites/src/utils/demo-user.ts (1 hunks)
  • package.json (2 hunks)
  • packages/journey-client/src/lib/client.store.test.ts (1 hunks)
  • packages/journey-client/src/lib/client.store.ts (2 hunks)
  • tsconfig.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • e2e/am-mock-api/tsconfig.app.json
🚧 Files skipped from review as they are similar to previous changes (14)
  • e2e/journey-suites/src/choice-confirm-poll.test.ts
  • e2e/journey-suites/src/email-suspend.test.ts
  • e2e/am-mock-api/src/environments/environment.ts
  • e2e/journey-suites/src/login.test.ts
  • packages/journey-client/src/lib/client.store.ts
  • e2e/journey-suites/src/no-session.test.ts
  • packages/journey-client/src/lib/client.store.test.ts
  • e2e/am-mock-api/package.json
  • e2e/am-mock-api/src/index.js
  • e2e/am-mock-api/tsconfig.json
  • e2e/journey-app/main.ts
  • e2e/am-mock-api/project.json
  • .node-version
  • e2e/am-mock-api/src/environments/environment.prod.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: cerebrl
Repo: ForgeRock/ping-javascript-sdk PR: 430
File: e2e/journey-app/main.ts:83-87
Timestamp: 2025-10-27T17:55:33.855Z
Learning: In the e2e/journey-app and similar e2e test applications in this repository, XSS hardening and similar production security practices are not required since these are exclusively test/development applications.
📚 Learning: 2025-10-28T14:44:26.883Z
Learnt from: ryanbas21
Repo: ForgeRock/ping-javascript-sdk PR: 427
File: .github/workflows/ci-fork.yml:50-56
Timestamp: 2025-10-28T14:44:26.883Z
Learning: Nx CLI accepts multiple targets with the short `-t` flag as space-separated tokens (e.g., `nx affected -t lint test build`) and also supports comma-separated values with the long form `--targets=` (e.g., `nx affected --targets=lint,test,build`). Both syntaxes are valid.

Applied to files:

  • package.json
🧬 Code graph analysis (11)
e2e/journey-suites/src/request-middleware.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/utils/demo-user.ts (1)
e2e/am-mock-api/src/app/routes.auth.js (1)
  • username (119-119)
e2e/journey-suites/src/device-profile.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/am-mock-api/src/app/routes.auth.js (4)
e2e/am-mock-api/src/app/env.config.js (4)
  • USERS (71-71)
  • USERS (71-71)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/constants.js (2)
  • authPaths (11-66)
  • authPaths (11-66)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/responses.js (36)
  • initialPlatformLogin (236-264)
  • initialPlatformLogin (236-264)
  • authSuccess (45-49)
  • authSuccess (45-49)
  • nameCallback (166-176)
  • nameCallback (166-176)
  • MetadataMarketPlaceInitialize (1205-1250)
  • MetadataMarketPlaceInitialize (1205-1250)
  • initialBasicLogin (198-215)
  • initialBasicLogin (198-215)
  • recaptchaEnterpriseCallback (1310-1349)
  • recaptchaEnterpriseCallback (1310-1349)
  • authFail (40-43)
  • authFail (40-43)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • MetadataMarketPlacePingOneEvaluation (1252-1308)
  • otpQRCodeCallbacks (500-584)
  • otpQRCodeCallbacks (500-584)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackFailureSaml (622-639)
  • redirectCallbackSaml (604-621)
  • redirectCallbackSaml (604-621)
  • redirectCallback (586-603)
  • redirectCallback (586-603)
  • noSessionSuccess (424-424)
  • noSessionSuccess (424-424)
  • oauthTokens (13-20)
  • oauthTokens (13-20)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpiringSoon (22-29)
  • oauthTokensExpired (31-38)
  • oauthTokensExpired (31-38)
  • redirectUrl (57-57)
  • redirectUrl (75-75)
  • userInfo (665-671)
  • userInfo (665-671)
e2e/journey-suites/src/custom-paths.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/am-mock-api/src/app/app.auth.js (2)
e2e/am-mock-api/src/app/routes.resource.js (2)
  • response (47-55)
  • response (70-70)
e2e/am-mock-api/src/app/env.config.js (4)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
e2e/journey-suites/src/registration.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/journey-suites/src/protect.test.ts (1)
e2e/oidc-suites/src/utils/async-events.ts (1)
  • navigate (54-56)
e2e/am-mock-api/src/app/env.config.js (1)
e2e/am-mock-api/src/app/responses.js (6)
  • realm (96-96)
  • realm (109-109)
  • amUrl (55-55)
  • amUrl (73-73)
  • amUrl (91-91)
  • amUrl (104-104)
e2e/am-mock-api/src/app/routes.resource.js (5)
e2e/am-mock-api/src/app/env.config.js (8)
  • FORGEOPS (67-67)
  • FORGEOPS (67-67)
  • AM_PORT (61-61)
  • AM_PORT (61-61)
  • REALM_PATH (68-68)
  • REALM_PATH (68-68)
  • AM_URL (64-64)
  • AM_URL (64-64)
e2e/am-mock-api/src/app/app.auth.js (3)
  • response (18-24)
  • session (14-14)
  • session (14-14)
e2e/am-mock-api/src/app/wait.js (1)
  • wait (13-15)
e2e/am-mock-api/src/app/routes.auth.js (2)
  • baz (57-59)
  • baz (57-59)
e2e/am-mock-api/src/app/responses.js (12)
  • authByTxnResponse (124-132)
  • authByTxnResponse (124-132)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpHeader (88-99)
  • createTxnStepUpUrl (51-68)
  • createTxnStepUpUrl (51-68)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpHeader (101-112)
  • createTreeStepUpUrl (70-86)
  • createTreeStepUpUrl (70-86)
  • authByTreeResponse (114-122)
  • authByTreeResponse (114-122)
e2e/am-mock-api/src/app/responses.js (2)
e2e/am-mock-api/src/app/routes.auth.js (5)
  • url (547-547)
  • redirectUrl (453-455)
  • redirectUrl (461-463)
  • redirectUrl (470-472)
  • redirectUrl (513-513)
e2e/am-mock-api/src/app/env.config.js (6)
  • amUrl (49-49)
  • AM_URL (64-64)
  • AM_URL (64-64)
  • RESOURCE_URL (69-69)
  • RESOURCE_URL (69-69)
  • realm (36-36)
🪛 Gitleaks (8.29.0)
e2e/am-mock-api/src/app/routes.auth.js

[high] 194-194: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: pr
🔇 Additional comments (15)
e2e/davinci-suites/src/phone-number-field.test.ts (1)

109-111: Verify that including toPass() is intentional and clarify whether line 66 needs the same retry logic.

The toPass() pattern is established in the codebase (also used in otp-register.test.ts line 29) for handling flaky E2E tests. However, your previous review indicated this was debugging code to be removed. If this retry logic is now intentional for the SMS/Voice MFA check, clarify whether the EMAIL MFA assertion on line 66 should also be wrapped with toPass() for consistency, or if the simpler test flow justifies the difference.

e2e/am-mock-api/.babelrc (1)

1-3: LGTM! Standard Nx Babel configuration.

The Babel preset and useBuiltIns configuration are appropriate for the new e2e mock API project.

e2e/am-mock-api/tsconfig.spec.json (1)

1-9: LGTM! Standard TypeScript test configuration.

The test-specific compiler options and include patterns are appropriate for the e2e mock API test suite.

package.json (1)

37-37: LGTM! Appropriate updates for the new mock API.

The watch script refinement to vite:watch-deps and the addition of @nx/express devDependency align well with the Express-based mock API infrastructure being introduced.

Also applies to: 64-64

e2e/journey-suites/src/utils/demo-user.ts (1)

7-8: LGTM! Test credentials aligned with mock API.

The updated credentials (sdkuser/password) match the test user configuration in the mock API (e2e/am-mock-api/src/app/env.config.js line 41). The simplified password is appropriate for the e2e test environment.

e2e/am-mock-api/src/app/constants.js (1)

11-66: LGTM! Well-organized endpoint configuration.

The authPaths structure clearly organizes mock endpoints by type. This static configuration is appropriate for driving the mock API routing logic.

e2e/journey-suites/src/registration.test.ts (1)

14-14: LGTM! URL routing updated consistently.

The navigation and assertion updates from journey= to tree= parameter with clientId=tenant are consistent with the broader routing changes across the journey test suite.

Also applies to: 26-26

e2e/journey-suites/src/request-middleware.test.ts (1)

14-14: LGTM! Query parameter migration is consistent.

The navigation URL and corresponding assertion have been properly updated from journey=Login to tree=Login, maintaining consistency throughout the test.

Also applies to: 36-36

e2e/journey-suites/src/protect.test.ts (1)

14-14: LGTM! Parameter migration is correct.

The navigation URL has been correctly updated from journey=TEST_Protect to tree=TEST_Protect.

e2e/journey-suites/src/otp-register.test.ts (1)

14-14: LGTM! Parameter migration with clientId addition is correct.

The navigation URL has been properly updated from journey=TEST_OTPRegistration to tree=TEST_OTPRegistration&clientId=tenant.

tsconfig.json (1)

78-81: LGTM! Project reference properly added.

The new am-mock-api project has been correctly added to the TypeScript workspace references.

e2e/journey-suites/src/custom-paths.test.ts (1)

15-15: LGTM! Parameter migration with clientId addition is correct.

The navigation URL has been properly updated from journey=Login to tree=Login&clientId=tenant. Note that the test remains skipped pending custom paths support in the mock API.

e2e/journey-suites/src/device-profile.test.ts (1)

14-14: LGTM! Parameter migration is correct.

The navigation URL has been correctly updated from journey=TEST_DeviceProfile to tree=TEST_DeviceProfile.

e2e/journey-suites/playwright.config.ts (1)

40-46: LGTM! Mock API server properly configured.

The am-mock-api server is correctly configured on port 9443, resolving the previous port conflict issue. The configuration properly mirrors the journey-app setup with appropriate settings for HTTPS and server reuse.

e2e/am-mock-api/src/app/response.registration.js (1)

11-224: LGTM! Well-structured registration flow mock.

The mock registration response provides comprehensive callback coverage for e2e testing, including username validation, attribute inputs, password policies, KBA questions, and T&C acceptance.

test('Test happy paths on test page', async ({ page }) => {
const { clickButton, navigate } = asyncEvents(page);
await navigate('/?journey=TEST_LoginWithMiscCallbacks');
await navigate('/?tree=TEST_LoginWithMiscCallbacks&clientId=tenant');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a reason we changed all of these over to tree from journey? I'd like to retire the use of "tree".

Copy link
Collaborator

@cerebrl cerebrl left a comment

Choose a reason for hiding this comment

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

I left two comments, but they aren't blocking.

Comment on lines 109 to 111
await expect(
async () => await expect(page.getByText('SMS/Voice MFA Registered')).toBeVisible(),
).toPass();
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems this wasn't removed. Can you remove it?

@ryanbas21 ryanbas21 merged commit abc449e into main Nov 13, 2025
8 checks passed
@ryanbas21 ryanbas21 deleted the migrate-am-mock-api branch November 13, 2025 16:19
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