diff --git a/packages/browser/src/ThunderIDBrowserClient.ts b/packages/browser/src/ThunderIDBrowserClient.ts index 4cb77df3..94ddae71 100644 --- a/packages/browser/src/ThunderIDBrowserClient.ts +++ b/packages/browser/src/ThunderIDBrowserClient.ts @@ -369,6 +369,19 @@ class ThunderIDBrowserClient extends ThunderIDJavaScriptC const sm = this.getStorageManager(); const config = await (sm as any).getConfigData(); + // Revoke the access token at the OP before ending the session. Best-effort: revocation can + // fail (no revocation_endpoint advertised, network error, non-200 response) without blocking + // sign out, since the local session must be cleared regardless. Set + // tokenLifecycle.revokeToken.revokeOnSignOut to false to skip this and only clear the local + // session. + if (config?.tokenLifecycle?.revokeToken?.revokeOnSignOut !== false) { + try { + await this.revokeAccessToken(sessionId); + } catch (error) { + logger.debug('Could not revoke the access token before signing out.', error); + } + } + // OIDC RP-Initiated Logout: end the session at the OP's end_session_endpoint. The sign-out URL // (carrying id_token_hint/client_id + post_logout_redirect_uri) is resolved before the local // session is cleared, so the ID token used for the hint is still available. This is the default; diff --git a/packages/javascript/src/models/config.ts b/packages/javascript/src/models/config.ts index 03060bc2..0fdf57cc 100644 --- a/packages/javascript/src/models/config.ts +++ b/packages/javascript/src/models/config.ts @@ -214,8 +214,8 @@ export interface BaseConfig extends WithPreferences, WithExtensions * by default derived by concatenating `baseUrl` with a fixed path (e.g. `{baseUrl}/flow/execute`). * These do not participate in OIDC discovery. * - * Split these two groups when the OAuth authorization server (IdP) and the Thunder resource - * server are different hosts — for example, when two Thunder instances are connected as trusted + * Split these two groups when the OAuth authorization server (IdP) and the ThunderID resource + * server are different hosts — for example, when two ThunderID instances are connected as trusted * issuers. Point `baseUrl` (and hence the OAuth/discovery endpoints) at the authorization server, * and override the resource-server endpoints to target the resource server that actually owns the * users and flows. @@ -429,6 +429,24 @@ export interface BaseConfig extends WithPreferences, WithExtensions */ autoRefresh?: boolean; }; + + /** + * Configuration for token revocation behavior. + */ + revokeToken?: { + /** + * Whether `signOut()` revokes the access token at the OP's `revocation_endpoint` before + * clearing the local session and completing sign out. + * + * Enabled by default. Revocation is best-effort: if it fails (no `revocation_endpoint` + * advertised, network error, non-200 response), sign out still proceeds with a + * local-only session clear. Set to `false` to skip revocation and only clear the local + * session. + * + * @default true + */ + revokeOnSignOut?: boolean; + }; }; /** @@ -602,7 +620,6 @@ export interface Preferences { i18n?: I18nPreferences; /** * Whether to resolve the theme from the Flow Meta API (GET /flow/meta). - * @remarks This is only applicable when using platform `ThunderID V2` (Thunder). */ resolveFromMeta?: boolean; /**