Skip to content

feat(oidc-client): add oidc session check with response type of id_token and none#682

Open
vatsalparikh wants to merge 4 commits into
mainfrom
sdks-5003
Open

feat(oidc-client): add oidc session check with response type of id_token and none#682
vatsalparikh wants to merge 4 commits into
mainfrom
sdks-5003

Conversation

@vatsalparikh

@vatsalparikh vatsalparikh commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

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

Implementation Decisions

  • I am returning ANY valid session for response type id_token. This is how it has been implemented in https://github.com/ForgeRock/oidcSessionCheck/blob/d321e1124d9cc87a188103e4e5c0f8ff13078557/sessionCheckFrame.src.js#L70. We can discuss about whether we need to be strict about verifying a user by subject / id_token in storage. In that case, subject / id_token will be required, which might restrict the use cases for session check
  • id_token param is a fragment (not query param) for security purposes, so that it is not sent with server requests and is somewhat secure compared to query params
  • state param is not echoed back for response type none which is expected. I did test it though, and so I haven’t added state sending or validation for response type none
  • Added logging but avoided logging any tokens / claims

How to test

  • Build and start the oidc app with pnpm nx build oidc-app && pnpm nx serve oidc-app
  • Load the http://localhost:8443/ping-am page and Login (Background)
  • Clicking on Session Check (none) and Session Check (id_token) buttons should return empty and claims fields respectively
  • Even if the token is invalid and the user is logged in, both buttons return valid sessions
  • Only when the user is logged out, session check fails

Recording

Screen.Recording.2026-06-09.at.7.32.41.AM.mov

Summary by CodeRabbit

  • New Features

    • Added a user-facing session check API supporting silent (prompt=none) and id_token modes with optional subject validation.
  • Enhancements

    • Session-check delivery via iframe or fetch, hash-fragment merging, exact redirect-URI matching, and improved error mappings.
    • Public types and client API updated to return typed session-check results.
    • UI: session-check buttons added to test app pages.
  • Tests

    • Expanded unit and e2e coverage for success/failure paths, JWT/nonce/state validation, and timeouts.
  • Documentation

    • README updated with examples and expected outcomes.

@changeset-bot

changeset-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 086ce08

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@forgerock/iframe-manager Minor
@forgerock/oidc-client Minor
@forgerock/davinci-client Minor
@forgerock/device-client Minor
@forgerock/journey-client Minor
@forgerock/protect Minor
@forgerock/sdk-types Minor
@forgerock/sdk-utilities Minor
@forgerock/sdk-logger Minor
@forgerock/sdk-oidc Minor
@forgerock/sdk-request-middleware Minor
@forgerock/storage Minor

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OIDC session status checking via a new user.session() method supporting prompt=none flows (response_type=none and response_type=id_token), enhances iframe-manager for hash/redirect matching, implements effect-based orchestration and RTK mutations, integrates into the OIDC client, and adds unit/E2E tests plus test-app UI buttons.

Changes

Session Check Feature Implementation

Layer / File(s) Summary
Session types and public API contract
packages/oidc-client/src/lib/session.types.ts, packages/oidc-client/src/types.ts, packages/oidc-client/api-report/oidc-client.api.md, packages/oidc-client/api-report/oidc-client.types.api.md
Adds SessionCheckResponseType, SessionCheckOptions, and SessionCheckSuccess types, updates API reports and barrel exports to expose user.session() and session-check RTK typings.
iframe-manager hash params and redirect URI matching
packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.ts, packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.test.ts
GetParamsFromIFrameOptions gains includeHashParams and resolveOnRedirectUri; getParamsByRedirect merges optional hash params, matches origin+pathname, prioritizes error params, and tests updated for timeouts and matching behavior.
Session micro orchestration and RTK endpoint
packages/oidc-client/src/lib/session.micros.ts, packages/oidc-client/src/lib/session.micros.test.ts, packages/oidc-client/src/lib/oidc.api.ts
Implements sessionCheckNoneµ and sessionCheckIdTokenµ with storage reads, URL builders, iframe/fetch dispatch, JWT decoding/validation, adds dispatchSessionCheckFetchµ, and inserts sessionCheckIframe/sessionCheckFetch RTK mutations; includes unit tests for builders, dispatch, validation, and error mappings.
OIDC client integration and utils
packages/oidc-client/src/lib/client.store.ts, packages/oidc-client/src/lib/client.store.test.ts, packages/oidc-client/src/lib/client.store.utils.ts, packages/oidc-client/package.json
Adds user.session(options?) to the client API, selects micros by responseType, validates well-known authorization_endpoint, introduces runMicroExit utility and refactors existing methods to use it, updates package deps to include jose.
E2E tests and test app support
e2e/oidc-suites/src/session.spec.ts, e2e/oidc-suites/src/utils/login.ts, e2e/oidc-app/src/utils/oidc-app.ts, e2e/oidc-app/src/ping-am/index.html, e2e/oidc-app/src/ping-one/index.html
Playwright tests cover prompt=none and id_token success/failure modes (login_required, nonce/state/subject mismatches, iframe timeout). Adds loginPingAm helper, defensive UI wiring, and session-check buttons in test apps.
Workspace configuration and release metadata
pnpm-workspace.yaml, .changeset/brave-foxes-dance.md
Adds jose to workspace catalog (^6.0.0) and adds a changeset entry documenting the new session-check API for a minor release.

Sequence Diagrams

sequenceDiagram
  participant App
  participant OidcClient as oidc() client
  participant SessionMicro as sessionCheckNoneµ/IdTokenµ
  participant StorageClient
  participant IFrameDispatch as sessionCheckIframe RTK
  participant IFrameManager
  participant AuthorizationServer as IdP

  App->>OidcClient: user.session({responseType: 'none'})
  OidcClient->>SessionMicro: call with config + options
  SessionMicro->>StorageClient: read stored idToken
  StorageClient-->>SessionMicro: idToken (or null)
  SessionMicro->>SessionMicro: build authorize URL (prompt=none)
  SessionMicro->>IFrameDispatch: dispatch iframe/fetch mutation with url
  IFrameDispatch->>IFrameManager: getParamsByRedirect()
  IFrameManager->>AuthorizationServer: load authorize endpoint in iframe
  AuthorizationServer-->>IFrameManager: redirect to redirectUri
  IFrameManager-->>IFrameDispatch: extracted params
  IFrameDispatch-->>SessionMicro: return params
  SessionMicro-->>OidcClient: SessionCheckSuccess {mode:'none'} or GenericError
  OidcClient-->>App: return result
Loading
sequenceDiagram
  participant App
  participant OidcClient as oidc() client
  participant SessionMicro as sessionCheckIdTokenµ
  participant StorageClient
  participant IFrameDispatch
  participant IFrameManager
  participant AuthorizationServer as IdP
  participant JWTDecoder as jose

  App->>OidcClient: user.session({responseType: 'id_token'})
  OidcClient->>SessionMicro: call (generates nonce,state)
  SessionMicro->>StorageClient: read stored idToken (hint)
  SessionMicro->>SessionMicro: build authorize URL with nonce,state
  SessionMicro->>IFrameDispatch: dispatch iframe mutation
  IFrameDispatch->>IFrameManager: getParamsByRedirect()
  IFrameManager->>AuthorizationServer: load authorize endpoint
  AuthorizationServer-->>IFrameManager: redirect with id_token
  IFrameManager-->>IFrameDispatch: return id_token + state
  SessionMicro->>JWTDecoder: decode id_token
  JWTDecoder-->>SessionMicro: claims
  SessionMicro->>OidcClient: SessionCheckSuccess {mode:'id_token', claims}
  OidcClient-->>App: return result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • cerebrl
  • ancheetah
  • SteinGabriel

Poem

🐰 I hopped in an iframe, quiet and spry,
Checked nonce and state as the id tokens fly.
Hashes and redirects, parsed neat and slow,
Session found or not — now the tests all know.
Hooray for small hops that make checks grow!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The pull request description includes implementation decisions, testing instructions, and a recording link, but lacks proper structure following the repository template. Reorganize the description to follow the template: add a JIRA ticket section at the top, then provide the Description section. Move implementation decisions and testing details into the Description section for clarity.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding OIDC session check support with response_type modes for id_token and none.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sdks-5003

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.

@nx-cloud

nx-cloud Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 086ce08

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

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-15 23:59:18 UTC

@vatsalparikh vatsalparikh changed the title feat(oidc-client): add oidc session check with response type of id_to… feat(oidc-client): add oidc session check with response type of id_token and none Jun 9, 2026
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

@pkg-pr-new

pkg-pr-new Bot commented Jun 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

@forgerock/davinci-client

pnpm add https://pkg.pr.new/@forgerock/davinci-client@682

@forgerock/device-client

pnpm add https://pkg.pr.new/@forgerock/device-client@682

@forgerock/journey-client

pnpm add https://pkg.pr.new/@forgerock/journey-client@682

@forgerock/oidc-client

pnpm add https://pkg.pr.new/@forgerock/oidc-client@682

@forgerock/protect

pnpm add https://pkg.pr.new/@forgerock/protect@682

@forgerock/sdk-types

pnpm add https://pkg.pr.new/@forgerock/sdk-types@682

@forgerock/sdk-utilities

pnpm add https://pkg.pr.new/@forgerock/sdk-utilities@682

@forgerock/iframe-manager

pnpm add https://pkg.pr.new/@forgerock/iframe-manager@682

@forgerock/sdk-logger

pnpm add https://pkg.pr.new/@forgerock/sdk-logger@682

@forgerock/sdk-oidc

pnpm add https://pkg.pr.new/@forgerock/sdk-oidc@682

@forgerock/sdk-request-middleware

pnpm add https://pkg.pr.new/@forgerock/sdk-request-middleware@682

@forgerock/storage

pnpm add https://pkg.pr.new/@forgerock/storage@682

commit: 086ce08

@codecov-commenter

codecov-commenter commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.99029% with 136 lines in your changes missing coverage. Please review.
✅ Project coverage is 21.97%. Comparing base (eafe277) to head (086ce08).
⚠️ Report is 31 commits behind head on main.

Files with missing lines Patch % Lines
packages/oidc-client/src/lib/oidc.api.ts 7.14% 104 Missing ⚠️
packages/sdk-utilities/src/lib/micro.utils.ts 5.00% 19 Missing ⚠️
packages/oidc-client/src/lib/client.store.ts 62.50% 9 Missing ⚠️
...s/iframe-manager/src/lib/iframe-manager.effects.ts 94.59% 2 Missing ⚠️
packages/oidc-client/src/types.ts 50.00% 1 Missing ⚠️
packages/sdk-utilities/src/index.ts 0.00% 1 Missing ⚠️

❌ Your project status has failed because the head coverage (21.97%) 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     #682      +/-   ##
==========================================
+ Coverage   18.07%   21.97%   +3.89%     
==========================================
  Files         155      157       +2     
  Lines       24398    25188     +790     
  Branches     1203     1475     +272     
==========================================
+ Hits         4410     5534    +1124     
+ Misses      19988    19654     -334     
Files with missing lines Coverage Δ
packages/oidc-client/src/lib/session.micros.ts 100.00% <100.00%> (ø)
packages/oidc-client/src/lib/session.types.ts 100.00% <100.00%> (ø)
packages/oidc-client/src/types.ts 12.50% <50.00%> (-1.79%) ⬇️
packages/sdk-utilities/src/index.ts 11.11% <0.00%> (-1.39%) ⬇️
...s/iframe-manager/src/lib/iframe-manager.effects.ts 93.75% <94.59%> (+92.80%) ⬆️
packages/oidc-client/src/lib/client.store.ts 43.05% <62.50%> (+15.35%) ⬆️
packages/sdk-utilities/src/lib/micro.utils.ts 5.00% <5.00%> (ø)
packages/oidc-client/src/lib/oidc.api.ts 51.30% <7.14%> (+4.10%) ⬆️

... and 13 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Deployed 0ccb932 to https://ForgeRock.github.io/ping-javascript-sdk/pr-682/0ccb9320451cfe01cecbf9e4879fb6b8db73cd90 branch gh-pages in ForgeRock/ping-javascript-sdk

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Analysis

📦 Bundle Size Analysis

🆕 New Packages

🆕 @forgerock/oidc-client - 35.2 KB (new)
🆕 @forgerock/sdk-types - 7.9 KB (new)
🆕 @forgerock/davinci-client - 53.8 KB (new)
🆕 @forgerock/sdk-utilities - 11.9 KB (new)
🆕 @forgerock/device-client - 0.0 KB (new)
🆕 @forgerock/device-client - 10.0 KB (new)
🆕 @forgerock/journey-client - 0.0 KB (new)
🆕 @forgerock/journey-client - 93.0 KB (new)
🆕 @forgerock/protect - 144.6 KB (new)
🆕 @forgerock/iframe-manager - 3.2 KB (new)
🆕 @forgerock/sdk-logger - 1.6 KB (new)
🆕 @forgerock/storage - 1.5 KB (new)
🆕 @forgerock/sdk-request-middleware - 4.6 KB (new)
🆕 @forgerock/sdk-oidc - 5.7 KB (new)


14 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

@vatsalparikh vatsalparikh marked this pull request as ready for review June 9, 2026 15:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
e2e/oidc-suites/src/session.spec.ts (1)

15-30: 💤 Low value

Consider base64url-encoding the fake signature for structural correctness.

The makeFakeJwt helper uses a plain string "fakesignature" for the third segment. While this may work when the SDK only validates the payload (nonce/sub/iat), a structurally correct JWT should have a base64url-encoded signature segment. Consider encoding it for better test fidelity.

♻️ Proposed refinement
   const body = btoa(JSON.stringify(payload))
     .replace(/\+/g, '-')
     .replace(/\//g, '_')
     .replace(/=/g, '');
-  return `${header}.${body}.fakesignature`;
+  const signature = btoa('fake-signature-bytes')
+    .replace(/\+/g, '-')
+    .replace(/\//g, '_')
+    .replace(/=/g, '');
+  return `${header}.${body}.${signature}`;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/oidc-suites/src/session.spec.ts` around lines 15 - 30, The fake JWT's
signature segment is a plain string; update the makeFakeJwt helper to produce a
structurally correct base64url-encoded signature instead of "fakesignature".
Locate the makeFakeJwt function and replace the static third segment with a
base64url-encoded value (e.g., encode a constant like "fakesignature" using the
same btoa + replace(/\+/g,'-')/replace(/\//g,'_')/replace(/=/g,'') pattern used
for header and body) so the JWT has three properly encoded segments.
packages/oidc-client/src/lib/session.micros.ts (2)

25-39: ⚡ Quick win

Reconsider the error type for storage read failures.

The error mapping uses type: 'argument_error' for storage access failures. Storage read failures are typically infrastructure or I/O issues, not argument validation problems. Consider using type: 'unknown_error' or a more appropriate type that reflects the nature of storage access failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/oidc-client/src/lib/session.micros.ts` around lines 25 - 39, The
GenericError returned by readStoredIdTokenµ currently uses type:
'argument_error' which is misleading for storage/I/O failures; update the catch
mapper in readStoredIdTokenµ to use a more appropriate error type such as
'unknown_error' (or an I/O/infrastructure-specific type) so storageClient.get()
failures are classified correctly, keeping the same error and message fields;
ensure the change is applied to the catch block that constructs the GenericError
(referencing readStoredIdTokenµ, StorageClient<OauthTokens>, and GenericError).

206-235: ⚡ Quick win

Consider validating redirectUri presence in id_token mode.

While id_token mode resolves by detecting the id_token parameter rather than matching the redirect URI, the redirectUri is still included in the authorization request (line 161) and must be valid. Consider adding an early validation check similar to the one in sessionCheckNoneµ (lines 186-192) to fail fast if redirectUri is missing, preventing a confusing AS error or timeout.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/oidc-client/src/lib/session.micros.ts` around lines 206 - 235,
sessionCheckIdTokenµ currently proceeds to build the id_token URL without
ensuring a redirectUri is present, which can cause confusing AS errors; add the
same early validation used in sessionCheckNoneµ to fail fast: before calling
buildIdTokenUrl (or immediately after entering sessionCheckIdTokenµ) check for a
valid redirectUri (e.g. options?.redirectUri or the config field your code
expects) and throw/return a GenericError if missing, mirroring the validation
logic from sessionCheckNoneµ so callers get a clear, early error instead of an
AS timeout.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/oidc-app/src/utils/oidc-app.ts`:
- Around line 216-231: Replace the use of innerHTML in the session check button
handlers with safe DOM text insertion: instead of setting el.innerHTML use
createElement/textContent to build the nodes and set the JSON string into a text
node (or set el.textContent / the pre element's textContent) so untrusted values
from oidcClient.session?.check() are not interpreted as HTML; update both the
handler for 'session-check-btn' (that currently creates a div and sets innerHTML
with "Session Check (none)" and the JSON) and the handler for
'session-check-id-token-btn' (that sets innerHTML with "Session Check
(id_token)" and the JSON) to construct elements and assign textContent for the
JSON output before appending to the app element.

In `@packages/oidc-client/src/lib/oidc.api.ts`:
- Around line 211-219: The code unsafely casts
URL(req.url).searchParams.get('redirect_uri') to string when calling
iFrameManager().getParamsByRedirect; add a runtime null-check for the
redirect_uri value (derived from URL(req.url).searchParams.get('redirect_uri'))
before invoking iFrameManager().getParamsByRedirect (the resolveOnRedirectUri
parameter), and if it's missing handle it explicitly (throw an error, return a
failure response, or log and reject) so the call only receives a guaranteed
string; update the surrounding code path that builds/consumes redirect_uri
(e.g., buildNoneUrl usages) to maintain type safety and avoid the direct `as
string` cast.

---

Nitpick comments:
In `@e2e/oidc-suites/src/session.spec.ts`:
- Around line 15-30: The fake JWT's signature segment is a plain string; update
the makeFakeJwt helper to produce a structurally correct base64url-encoded
signature instead of "fakesignature". Locate the makeFakeJwt function and
replace the static third segment with a base64url-encoded value (e.g., encode a
constant like "fakesignature" using the same btoa +
replace(/\+/g,'-')/replace(/\//g,'_')/replace(/=/g,'') pattern used for header
and body) so the JWT has three properly encoded segments.

In `@packages/oidc-client/src/lib/session.micros.ts`:
- Around line 25-39: The GenericError returned by readStoredIdTokenµ currently
uses type: 'argument_error' which is misleading for storage/I/O failures; update
the catch mapper in readStoredIdTokenµ to use a more appropriate error type such
as 'unknown_error' (or an I/O/infrastructure-specific type) so
storageClient.get() failures are classified correctly, keeping the same error
and message fields; ensure the change is applied to the catch block that
constructs the GenericError (referencing readStoredIdTokenµ,
StorageClient<OauthTokens>, and GenericError).
- Around line 206-235: sessionCheckIdTokenµ currently proceeds to build the
id_token URL without ensuring a redirectUri is present, which can cause
confusing AS errors; add the same early validation used in sessionCheckNoneµ to
fail fast: before calling buildIdTokenUrl (or immediately after entering
sessionCheckIdTokenµ) check for a valid redirectUri (e.g. options?.redirectUri
or the config field your code expects) and throw/return a GenericError if
missing, mirroring the validation logic from sessionCheckNoneµ so callers get a
clear, early error instead of an AS timeout.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f1fa359c-8961-4f12-9227-9e66f943afc1

📥 Commits

Reviewing files that changed from the base of the PR and between 354a238 and e1b4cd2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • .changeset/brave-foxes-dance.md
  • e2e/oidc-app/src/ping-am/index.html
  • e2e/oidc-app/src/ping-one/index.html
  • e2e/oidc-app/src/utils/oidc-app.ts
  • e2e/oidc-suites/src/session.spec.ts
  • e2e/oidc-suites/src/utils/login.ts
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/package.json
  • packages/oidc-client/src/lib/client.store.test.ts
  • packages/oidc-client/src/lib/client.store.ts
  • packages/oidc-client/src/lib/oidc.api.ts
  • packages/oidc-client/src/lib/session.micros.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
  • packages/oidc-client/src/lib/session.types.ts
  • packages/oidc-client/src/types.ts
  • packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.test.ts
  • packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.ts
  • pnpm-workspace.yaml

Comment thread e2e/oidc-app/src/utils/oidc-app.ts
Comment thread packages/oidc-client/src/lib/oidc.api.ts Outdated
Comment thread packages/oidc-client/src/lib/session.micros.ts Outdated
Comment on lines +59 to +62
if ('error' in result && result.error) {
const errData = result.error as {
data?: { error?: string; message?: string; type?: string };
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why have this check if we can just handle it in the catch above? seems like we're duplicating error handling? We handle it as a Generic error and then update it as errData? This seems like it can be a singular pipe,

Micro.tryPromise({ 
  try: store-dispatch,
  catch: error 
}).pipe(
  Micro.mapError(fail),
  Micro.succeed(success)
);

We can also consider, do we want to "fail" here in session.micro.ts or do we want to allow the failure to be consumed later on in the pipeline? That way it's possible the session check here can be composed and handled uniquely when it needs to be? Again - similarly this is just me thinking in my head, and not something to specifically be addressed but i'm trying to break down my thought process in why I think to write the effectful pipelines as i'm suggesting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, using the pipe here!

Doing this with flatMap instead of mapError. RTK Query always resolves the promise successfully, even when the request fails, it just puts the failure inside the result as an error property { error: } . So mapError wouldn't catch it.

In response to failing here, I believe we are doing all error handling for generic error in respective functions instead of bubbling up. When we do work on unifying errors, we'll have something else than Generic Error and we can think about returning the exact error types then. I think this looks good for now.

Comment thread packages/oidc-client/src/lib/session.micros.ts Outdated
Comment thread packages/oidc-client/src/lib/session.micros.ts Outdated
Comment thread packages/oidc-client/src/lib/session.micros.ts Outdated

@cerebrl cerebrl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Left some comments after an initial review. I'll take a deeper look at your .micro.ts file soon.

Comment thread packages/oidc-client/src/lib/client.store.ts Outdated
Comment thread packages/oidc-client/src/lib/session.types.ts Outdated
Comment thread packages/oidc-client/src/lib/oidc.api.ts Outdated
Comment thread packages/oidc-client/src/lib/client.store.ts Outdated
Comment on lines +38 to +41
export interface SessionCheckSuccess {
/** Decoded id_token payload. Present only in id_token mode. */
claims?: Record<string, unknown>;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This may be a nitpick but I'm not a huge fan of types like this because {} checks as SessionCheckSuccess.

We should probably declare a specific type for when an id_token is valid so that we can drive through the type system.

Because the other member of the union is essentially an empty object, I wonder if we should declare a discriminator { success: boolean } | { success: boolean; claims: Record<string, unknown> }

This way we can tell if we have claims or not. it alleviates the {} type from bottom type check from passing by mistake

We probably could even type claims more strictly.

I just fear having {} as a type alias as a structured return type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Okay, it can seem a bit empty, I agree. I am using a shape like below now

export type SessionCheckSuccess = {
  responseType: SessionCheckResponseType;
  claims?: JWTPayload;
};

So the return will be something like

{
	responseType: 'none'
}

About using a discriminator, I don't think it is necessary. SessionCheckSuccess should be sufficient. Let me know if you feel otherwise.

I am using JWTPayload for claims now, so that should be good!

@ryanbas21 ryanbas21 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Requesting changes.

@cerebrl cerebrl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A few more comments.

Comment thread packages/oidc-client/src/lib/session.types.ts Outdated
Comment thread packages/oidc-client/src/lib/session.micros.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/oidc-app/src/utils/oidc-app.ts`:
- Around line 22-25: The displayError function currently injects JSON into the
DOM via errorEl.innerHTML which allows HTML injection; change it to create safe
text nodes instead by setting the element's textContent (or creating a child
text node) for the serialized error payload and avoid using innerHTML — update
the displayError function and the errorEl creation (referenced as displayError
and errorEl) so the error JSON is rendered via textContent to prevent XSS.

In `@packages/oidc-client/src/lib/session.types.ts`:
- Line 30: The SessionCheckSuccess type exposes decoded JWT payload as
JWTPayload which misleads callers into treating it as verified; change the type
in SessionCheckSuccess (and any exports referencing it) to a clearly untrusted
shape (e.g., claims: UnverifiedJwtPayload or claims: Record<string, unknown>)
and update usages in session.micros.ts (the code path that only calls
decodeJwt() and checks state/nonce/sub) so callers must explicitly verify
signatures/claims before making auth/identity decisions; ensure the new type
name and shape make it obvious these claims are unverified.
- Around line 19-27: Update the SessionCheckOptions type to a discriminated
union so that `subject` is only allowed when `responseType` is `'id_token'`:
replace the open interface `SessionCheckOptions` with two variants (one for
`responseType?: 'none' | undefined` that forbids `subject`, and one for
`responseType: 'id_token'` that permits `subject?: string`) and keep
`SessionCheckResponseType` as the discriminant; adjust any call sites (e.g.,
code paths in `client.store.ts` that call `sessionCheckNoneµ`) to satisfy the
new types if necessary. Ensure JSDoc/comments still reflect that `subject` is
id_token-only.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b25862b5-6334-4768-979b-c19377454717

📥 Commits

Reviewing files that changed from the base of the PR and between e1b4cd2 and af2e859.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • .changeset/brave-foxes-dance.md
  • e2e/oidc-app/src/ping-am/index.html
  • e2e/oidc-app/src/ping-one/index.html
  • e2e/oidc-app/src/utils/oidc-app.ts
  • e2e/oidc-suites/src/session.spec.ts
  • e2e/oidc-suites/src/utils/login.ts
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/package.json
  • packages/oidc-client/src/lib/client.store.test.ts
  • packages/oidc-client/src/lib/client.store.ts
  • packages/oidc-client/src/lib/client.store.utils.ts
  • packages/oidc-client/src/lib/oidc.api.ts
  • packages/oidc-client/src/lib/session.micros.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
  • packages/oidc-client/src/lib/session.types.ts
  • packages/oidc-client/src/types.ts
  • packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.test.ts
  • packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.ts
  • pnpm-workspace.yaml
✅ Files skipped from review due to trivial changes (3)
  • .changeset/brave-foxes-dance.md
  • packages/oidc-client/src/types.ts
  • pnpm-workspace.yaml
🚧 Files skipped from review as they are similar to previous changes (10)
  • e2e/oidc-app/src/ping-one/index.html
  • packages/oidc-client/src/lib/client.store.test.ts
  • e2e/oidc-suites/src/utils/login.ts
  • e2e/oidc-app/src/ping-am/index.html
  • packages/oidc-client/src/lib/oidc.api.ts
  • packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.test.ts
  • e2e/oidc-suites/src/session.spec.ts
  • packages/oidc-client/src/lib/session.micros.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
  • packages/sdk-effects/iframe-manager/src/lib/iframe-manager.effects.ts

Comment thread e2e/oidc-app/src/utils/oidc-app.ts
Comment thread packages/oidc-client/src/lib/session.types.ts
Comment thread packages/oidc-client/src/lib/session.types.ts Outdated
nx-cloud[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/oidc-client/src/lib/oidc.api.ts`:
- Around line 295-323: sessionCheckFetch currently collapses all response.error
cases into an auth error and assumes any success means 204; change it to: if
response.error exists and represents a transport/fetch-level failure (i.e., no
response available on response.meta or error.status is one of
FETCH_ERROR/TIMEOUT_ERROR/PARSING_ERROR) then return the original response.error
unchanged to preserve RTK Query transport semantics, otherwise (HTTP error
present) map the HTTP error to the existing login_required structure; on
success, inspect response.meta?.response?.status and only return { data: {
status: 204 } } when that status === 204, otherwise return a suitable
FetchBaseQueryError indicating unexpected session-check status. Ensure you
update the logic around response, response.error, and
response.meta.response.status inside sessionCheckFetch to implement these
branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1c0aef36-836e-4308-b6dc-9201b9327344

📥 Commits

Reviewing files that changed from the base of the PR and between af2e859 and f71bfff.

📒 Files selected for processing (8)
  • e2e/oidc-app/src/ping-am/index.html
  • e2e/oidc-app/src/ping-one/index.html
  • e2e/oidc-app/src/utils/oidc-app.ts
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/src/lib/oidc.api.ts
  • packages/oidc-client/src/lib/session.micros.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • e2e/oidc-app/src/ping-am/index.html
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md

Comment thread packages/oidc-client/src/lib/oidc.api.ts Outdated

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nx Cloud has identified a flaky task in your failed CI:

🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.

Nx Cloud View detailed reasoning in Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
e2e/oidc-app/src/utils/oidc-app.ts (1)

22-25: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop injecting session/error payloads via innerHTML; render with textContent instead.

Line 24 and session-check render paths (Lines 221, 230, 239) inject serialized payloads into HTML sinks. These values can include server-controlled fields and should be treated as untrusted.

Proposed patch
 function displayError(error: unknown) {
   const errorEl = document.createElement('div');
-  errorEl.innerHTML = `<p><strong>Error:</strong> <span class="error">${JSON.stringify(error, null, 2)}</span></p>`;
+  const p = document.createElement('p');
+  const strong = document.createElement('strong');
+  strong.textContent = 'Error:';
+  const span = document.createElement('span');
+  span.className = 'error';
+  span.textContent = JSON.stringify(error, null, 2);
+  p.append(strong, document.createTextNode(' '), span);
+  errorEl.appendChild(p);
   document.body.appendChild(errorEl);
 }
@@
-    el.innerHTML = `<p><strong>Session Check (none, iframe):</strong></p><pre id="session-check-result">${JSON.stringify(result, null, 2)}</pre>`;
+    const title = document.createElement('p');
+    const strong = document.createElement('strong');
+    strong.textContent = 'Session Check (none, iframe):';
+    title.appendChild(strong);
+    const pre = document.createElement('pre');
+    pre.id = 'session-check-result';
+    pre.textContent = JSON.stringify(result, null, 2);
+    el.append(title, pre);
@@
-    el.innerHTML = `<p><strong>Session Check (none, no redirect):</strong></p><pre id="session-check-no-redirect-result">${JSON.stringify(result, null, 2)}</pre>`;
+    const title = document.createElement('p');
+    const strong = document.createElement('strong');
+    strong.textContent = 'Session Check (none, no redirect):';
+    title.appendChild(strong);
+    const pre = document.createElement('pre');
+    pre.id = 'session-check-no-redirect-result';
+    pre.textContent = JSON.stringify(result, null, 2);
+    el.append(title, pre);
@@
-    el.innerHTML = `<p><strong>Session Check (id_token):</strong></p><pre id="session-check-id-token-result">${JSON.stringify(result, null, 2)}</pre>`;
+    const title = document.createElement('p');
+    const strong = document.createElement('strong');
+    strong.textContent = 'Session Check (id_token):';
+    title.appendChild(strong);
+    const pre = document.createElement('pre');
+    pre.id = 'session-check-id-token-result';
+    pre.textContent = JSON.stringify(result, null, 2);
+    el.append(title, pre);

Also applies to: 221-223, 229-231, 239-240

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/oidc-app/src/utils/oidc-app.ts` around lines 22 - 25, The UI currently
injects untrusted payloads via innerHTML (e.g., function displayError) which
risks XSS; update displayError and the session-check render paths referenced in
the comment to build DOM nodes and assign data using textContent (or
setAttribute) instead of innerHTML: create the surrounding elements (p, strong,
span) via document.createElement, set their textContent to the safe
JSON.stringify(output, null, 2) or individual fields, and append them to
document.body (or the target container); ensure no raw HTML strings are passed
into innerHTML anywhere in the displayError function or the session rendering
code paths.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/oidc-client/src/lib/oidc.api.ts`:
- Around line 297-320: sessionCheckFetch currently treats numeric HTTP failures
the same as transport/network errors; update the response mapping to distinguish
network/transport errors (when typeof responseError.status === 'string') from
HTTP errors (when status is a number). In the error return block (variables:
responseError, isNetworkError, errorData, message) set status to
responseError.status for HTTP errors and to 0 or a non-HTTP sentinel for network
errors; set data.error to 'session_check_error' and type to 'network_error' for
network/transport failures, but to 'login_required' and 'auth_error' for HTTP
401/403 auth failures (use responseError.status to decide), and derive message
from errorData.error_description or responseError.statusText accordingly so
outages aren’t reported as “not logged in” (preserve
GenericError/FetchBaseQueryError shapes). Ensure logger.error still logs
responseError.

---

Duplicate comments:
In `@e2e/oidc-app/src/utils/oidc-app.ts`:
- Around line 22-25: The UI currently injects untrusted payloads via innerHTML
(e.g., function displayError) which risks XSS; update displayError and the
session-check render paths referenced in the comment to build DOM nodes and
assign data using textContent (or setAttribute) instead of innerHTML: create the
surrounding elements (p, strong, span) via document.createElement, set their
textContent to the safe JSON.stringify(output, null, 2) or individual fields,
and append them to document.body (or the target container); ensure no raw HTML
strings are passed into innerHTML anywhere in the displayError function or the
session rendering code paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bccc04db-80fc-42ce-bba5-f5696bcae4ac

📥 Commits

Reviewing files that changed from the base of the PR and between f71bfff and 1eda94e.

📒 Files selected for processing (10)
  • e2e/oidc-app/src/ping-am/index.html
  • e2e/oidc-app/src/ping-one/index.html
  • e2e/oidc-app/src/utils/oidc-app.ts
  • packages/oidc-client/README.md
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/src/lib/client.store.test.ts
  • packages/oidc-client/src/lib/oidc.api.ts
  • packages/oidc-client/src/lib/session.micros.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • e2e/oidc-app/src/ping-one/index.html
  • e2e/oidc-app/src/ping-am/index.html
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/src/lib/session.micros.test.ts

Comment thread packages/oidc-client/src/lib/oidc.api.ts Outdated
@vatsalparikh vatsalparikh force-pushed the sdks-5003 branch 3 times, most recently from be134fd to bc03162 Compare June 12, 2026 20:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/oidc-client/src/lib/session.micros.test.ts`:
- Around line 179-189: The iframe-path test for sessionCheckNoneµ currently only
asserts success and dispatch calls but misses verifying the returned
SessionCheckSuccess payload; update the test for sessionCheckNoneµ to, after
confirming Micro.exitIsSuccess(exit), assert exit.value equals the expected
SessionCheckSuccess object ({ mode: 'none' })—use the same pattern as the
fetch-path test (check Micro.exitIsSuccess(exit) then
expect(exit.value).toStrictEqual({ mode: 'none' })) to ensure the iframe branch
returns the correct value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0639c678-93eb-4d1e-be3a-105a0e10a815

📥 Commits

Reviewing files that changed from the base of the PR and between 1eda94e and be134fd.

📒 Files selected for processing (10)
  • e2e/oidc-app/src/ping-am/index.html
  • e2e/oidc-app/src/ping-one/index.html
  • e2e/oidc-app/src/utils/oidc-app.ts
  • packages/oidc-client/README.md
  • packages/oidc-client/api-report/oidc-client.api.md
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/src/lib/client.store.test.ts
  • packages/oidc-client/src/lib/oidc.api.ts
  • packages/oidc-client/src/lib/session.micros.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
✅ Files skipped from review due to trivial changes (2)
  • e2e/oidc-app/src/ping-one/index.html
  • packages/oidc-client/README.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • e2e/oidc-app/src/ping-am/index.html
  • packages/oidc-client/api-report/oidc-client.types.api.md
  • packages/oidc-client/src/lib/client.store.test.ts
  • packages/oidc-client/src/lib/session.micros.ts
  • packages/oidc-client/src/lib/oidc.api.ts
  • e2e/oidc-app/src/utils/oidc-app.ts

Comment thread packages/oidc-client/src/lib/session.micros.test.ts

@cerebrl cerebrl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This looks good to me. Great job, Vatsal!

@vatsalparikh vatsalparikh force-pushed the sdks-5003 branch 6 times, most recently from 4bd0fed to 8628489 Compare June 15, 2026 22:43
@vatsalparikh vatsalparikh force-pushed the sdks-5003 branch 2 times, most recently from 05d53ad to 8c0043b Compare June 15, 2026 23:13
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