Skip to content

Derive the end session endpoint from the server's logout path - #43

Merged
madurangasiriwardena merged 1 commit into
thunder-id:mainfrom
madurangasiriwardena:fix-default-end-session-endpoint
Jul 30, 2026
Merged

Derive the end session endpoint from the server's logout path#43
madurangasiriwardena merged 1 commit into
thunder-id:mainfrom
madurangasiriwardena:fix-default-end-session-endpoint

Conversation

@madurangasiriwardena

@madurangasiriwardena madurangasiriwardena commented Jul 30, 2026

Copy link
Copy Markdown
Member

Purpose

OIDCDiscoveryConstants.Endpoints.END_SESSION defaulted to /oidc/logout, which the server does not serve. These baseUrl-derived defaults are used whenever OIDC discovery cannot be consumed, so in that situation signOut() sent the browser to an unrouted path and the request came back as 401 AUTH-4010 ("Authentication is required to access this resource") instead of starting the logout flow.

Every other derived default already matches the server (/oauth2/authorize, /oauth2/token, /oauth2/jwks, /oauth2/revoke, /oauth2/userinfo), and the discovery document advertises end_session_endpoint as <baseUrl>/oauth2/logout. END_SESSION was the one that didn't.

Reproduced against a local server:

  • GET /oidc/logout -> 401 AUTH-4010
  • GET /oauth2/logout -> 302 to the sign-out gate

Approach

  1. Point END_SESSION at /oauth2/logout, matching the advertised end_session_endpoint.
  2. Log a warning in loadOpenIDProviderConfiguration() on each of the three ways discovery can degrade (fetch threw, non-200 response, unparseable response). Previously all three were swallowed by bare catch {} blocks, the baseUrl fallback was cached behind op_config_initiated, and nothing surfaced. That silence is what made this hard to diagnose: sign-in still worked, because authorize/token resolve to the same paths either way, so END_SESSION was the only endpoint where the fallback diverged from reality.
  3. Add AuthenticationHelper.test.ts covering resolveEndpointsByBaseURL(), which had no test coverage. The existing getSignOutUrl() tests seed provider metadata directly, so they could not have caught this. Verified the new test fails against the old constant: expected 'https://localhost:8090/oidc/logout' to be 'https://localhost:8090/oauth2/logout'.

Note: SESSION_IFRAME is also wrong (/oidc/checksession is not served and check_session_iframe is never advertised), but there is no correct path to repoint it at, and it is threaded through the OIDCDiscoveryConstants type and resolveEndpointsExplicitly's required-endpoints list. Left for a separate change.

Related Issues

Related PRs

  • N/A

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
  • Tests provided. (Add links if there are any)
    • Unit Tests
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.

Security checks

  • Followed secure coding standards in WSO2 Secure Coding Guidelines
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

Summary by CodeRabbit

  • Bug Fixes
    • Improved OpenID Connect discovery handling by providing warning messages when configuration retrieval or endpoint processing fails.
    • Added reliable fallback endpoint resolution when discovery is unavailable.
    • Updated the default logout endpoint to use the standard OAuth2 logout path.
    • Ensured explicitly configured logout endpoints continue to take precedence over derived values.

The baseUrl-derived endpoint defaults are used whenever OIDC discovery
cannot be consumed, but END_SESSION pointed at /oidc/logout, which the
server does not serve. Sign-out then hit an unrouted path and came back
as a 401 instead of starting the logout flow.

Point it at /oauth2/logout, matching the end_session_endpoint advertised
in the discovery document, and log a warning whenever discovery is
skipped so the fallback is no longer silent.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

OIDC logout endpoint derivation now uses /oauth2/logout. AuthenticationHelper endpoint resolution tests cover defaults, overrides, and missing configuration. Discovery loading logs fetch and endpoint-resolution failures before applying existing base URL fallbacks.

Changes

OIDC endpoint resolution

Layer / File(s) Summary
Endpoint contract and resolution tests
packages/javascript/src/constants/OIDCDiscoveryConstants.ts, packages/javascript/src/__tests__/AuthenticationHelper.test.ts
The end-session endpoint uses /oauth2/logout, with tests covering derived endpoints, explicit overrides, and missing baseUrl errors.
Discovery fallback diagnostics
packages/javascript/src/ThunderIDJavaScriptClient.ts
OIDC discovery fetch and endpoint-processing failures emit warnings before falling back to base URL endpoint resolution.

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

Possibly related PRs

Suggested reviewers: brionmario

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: updating the end-session endpoint to the server’s logout path.
Description check ✅ Passed The description includes Purpose, Approach, Related Issues, Related PRs, Checklist, and Security checks, matching the template well.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/javascript/src/__tests__/AuthenticationHelper.test.ts (1)

62-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Protect the unchanged SESSION_IFRAME endpoint with an assertion.

This case claims to derive every endpoint but omits check_session_iframe. Add an assertion or rename the test so the coverage claim is accurate.

Suggested assertion
       expect(endpoints.issuer).toBe(BASE_URL);
+      expect(endpoints.check_session_iframe).toBe(`${BASE_URL}/oidc/checksession`);

This also protects the PR’s stated unchanged SESSION_IFRAME contract.

🤖 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/javascript/src/__tests__/AuthenticationHelper.test.ts` around lines
62 - 72, Update the resolveEndpointsByBaseURL() test to assert that
check_session_iframe retains the expected SESSION_IFRAME value, preserving the
unchanged endpoint contract while keeping the “derives every endpoint” coverage
claim accurate.
packages/javascript/src/ThunderIDJavaScriptClient.ts (1)

359-390: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression tests for the new discovery diagnostics.

The supplied tests do not exercise fetch failures, non-200 responses, or malformed discovery responses. Verify both logger.warn calls and that base-URL-derived metadata is persisted after each recoverable failure.

🤖 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/javascript/src/ThunderIDJavaScriptClient.ts` around lines 359 - 390,
Add regression tests for the discovery flow covering fetch rejection, non-200
responses, and malformed discovery payloads. For each recoverable failure,
assert the corresponding logger.warn call and verify base-URL-derived metadata
is persisted, while preserving the existing successful discovery behavior.
🤖 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/javascript/src/ThunderIDJavaScriptClient.ts`:
- Around line 362-373: Update the warning messages in the discovery
response-status and catch branches of ThunderIDJavaScriptClient so they do not
unconditionally promise a base-URL fallback. Make the wording conditional on
baseUrl being configured, or state that fallback will be attempted only when
available, while preserving the existing fallback and error behavior.

---

Nitpick comments:
In `@packages/javascript/src/__tests__/AuthenticationHelper.test.ts`:
- Around line 62-72: Update the resolveEndpointsByBaseURL() test to assert that
check_session_iframe retains the expected SESSION_IFRAME value, preserving the
unchanged endpoint contract while keeping the “derives every endpoint” coverage
claim accurate.

In `@packages/javascript/src/ThunderIDJavaScriptClient.ts`:
- Around line 359-390: Add regression tests for the discovery flow covering
fetch rejection, non-200 responses, and malformed discovery payloads. For each
recoverable failure, assert the corresponding logger.warn call and verify
base-URL-derived metadata is persisted, while preserving the existing successful
discovery behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 63566f92-4341-417d-9948-36715849efef

📥 Commits

Reviewing files that changed from the base of the PR and between 191076d and a658a51.

📒 Files selected for processing (3)
  • packages/javascript/src/ThunderIDJavaScriptClient.ts
  • packages/javascript/src/__tests__/AuthenticationHelper.test.ts
  • packages/javascript/src/constants/OIDCDiscoveryConstants.ts

Comment on lines +362 to +373
logger.warn(
`ThunderIDJavaScriptClient: Discovery request to ${resolvedWellKnownEndpoint} returned ` +
`${response.status}; falling back to endpoints derived from the base URL.`,
);
response = undefined;
}
} catch {
} catch (error: unknown) {
logger.warn(
`ThunderIDJavaScriptClient: Discovery request to ${resolvedWellKnownEndpoint} failed; ` +
'falling back to endpoints derived from the base URL.',
error,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Do not promise a base-URL fallback when baseUrl is absent.

These warnings always say “falling back,” but the subsequent branches throw JS-AUTH_CORE-GOPMD-HE01 when no baseUrl is configured. Make the message conditional or state that a fallback will be attempted only when available.

Also applies to: 384-390

🤖 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/javascript/src/ThunderIDJavaScriptClient.ts` around lines 362 - 373,
Update the warning messages in the discovery response-status and catch branches
of ThunderIDJavaScriptClient so they do not unconditionally promise a base-URL
fallback. Make the wording conditional on baseUrl being configured, or state
that fallback will be attempted only when available, while preserving the
existing fallback and error behavior.

@madurangasiriwardena
madurangasiriwardena merged commit 6a3775b into thunder-id:main Jul 30, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants