Add OIDC Back-Channel Logout support

Implement OIDC Back-Channel Logout 1.0 (RFC). When enabled, the IdP can
POST a signed logout_token JWT to invalidate user sessions server-side.

- Add BackchannelLogoutHandler: JWT verification via jose, jti replay
  protection with bounded cache, session destruction by sub or sid
- Add oidcSessionId column to sessions table with index for fast lookups
- Add backchannel logout route (POST /auth/openid/backchannel-logout)
- Notify connected clients via socket to redirect to login page
- Add authOpenIDBackchannelLogoutEnabled toggle in schema-driven settings UI
- Migration v2.34.0 adds oidcSessionId column and index
- Polish settings UI: auto-populate loading state, subfolder dropdown
  options, KeyValueEditor fixes, localized descriptions via descriptionKey,
  duplicate key detection, success/error toasts
- Localize backchannel logout toast (ToastSessionEndedByProvider)
- OidcAuthStrategy tests now use real class via require-cache stubbing
This commit is contained in:
Denis Arnst 2026-02-05 17:55:10 +01:00
parent 33bee70a12
commit 073eff74ef
No known key found for this signature in database
GPG key ID: D5866C58940197BF
16 changed files with 886 additions and 104 deletions

View file

@ -85,6 +85,7 @@ class ServerSettings {
this.authOpenIDScopes = 'openid profile email'
this.authOpenIDGroupMap = {}
this.authOpenIDRequireVerifiedEmail = false
this.authOpenIDBackchannelLogoutEnabled = false
if (settings) {
this.construct(settings)
@ -152,6 +153,7 @@ class ServerSettings {
this.authOpenIDScopes = settings.authOpenIDScopes || 'openid profile email'
this.authOpenIDGroupMap = settings.authOpenIDGroupMap || {}
this.authOpenIDRequireVerifiedEmail = !!settings.authOpenIDRequireVerifiedEmail
this.authOpenIDBackchannelLogoutEnabled = !!settings.authOpenIDBackchannelLogoutEnabled
if (!Array.isArray(this.authActiveAuthMethods)) {
this.authActiveAuthMethods = ['local']
@ -264,7 +266,8 @@ class ServerSettings {
authOpenIDSubfolderForRedirectURLs: this.authOpenIDSubfolderForRedirectURLs,
authOpenIDScopes: this.authOpenIDScopes,
authOpenIDGroupMap: this.authOpenIDGroupMap,
authOpenIDRequireVerifiedEmail: this.authOpenIDRequireVerifiedEmail
authOpenIDRequireVerifiedEmail: this.authOpenIDRequireVerifiedEmail,
authOpenIDBackchannelLogoutEnabled: this.authOpenIDBackchannelLogoutEnabled
}
}
@ -317,7 +320,8 @@ class ServerSettings {
authOpenIDSubfolderForRedirectURLs: this.authOpenIDSubfolderForRedirectURLs,
authOpenIDScopes: this.authOpenIDScopes,
authOpenIDGroupMap: this.authOpenIDGroupMap,
authOpenIDRequireVerifiedEmail: this.authOpenIDRequireVerifiedEmail
authOpenIDRequireVerifiedEmail: this.authOpenIDRequireVerifiedEmail,
authOpenIDBackchannelLogoutEnabled: this.authOpenIDBackchannelLogoutEnabled
}
}