From bc847146705fdb76584cc34ac989a2589229aa7e Mon Sep 17 00:00:00 2001 From: Shuttleu Date: Fri, 16 Feb 2024 16:35:38 +0000 Subject: [PATCH] Add ability to logout from OIDC (#6539) * Add OIDC_LOGOUT_URI functionality * Add logout redirect to work on logout route * Fix lint * Fix lint * Fix lint * Fix lint * Return null if logout endpoint used * Update import --- .env.sample | 1 + app.json | 4 ++++ app/actions/definitions/navigation.tsx | 8 +++++++- app/scenes/Logout.tsx | 5 +++++ server/env.ts | 10 ++++++++++ server/presenters/env.ts | 1 + shared/types.ts | 1 + 7 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.env.sample b/.env.sample index 1724989de..80ba377e7 100644 --- a/.env.sample +++ b/.env.sample @@ -103,6 +103,7 @@ OIDC_CLIENT_SECRET= OIDC_AUTH_URI= OIDC_TOKEN_URI= OIDC_USERINFO_URI= +OIDC_LOGOUT_URI= # Specify which claims to derive user information from # Supports any valid JSON path with the JWT payload diff --git a/app.json b/app.json index 9169adf16..fe4d8bd9b 100644 --- a/app.json +++ b/app.json @@ -81,6 +81,10 @@ "description": "", "required": false }, + "OIDC_LOGOUT_URI": { + "description": "", + "required": false + }, "OIDC_USERNAME_CLAIM": { "description": "Specify which claims to derive user information from. Supports any valid JSON path with the JWT payload", "value": "preferred_username", diff --git a/app/actions/definitions/navigation.tsx b/app/actions/definitions/navigation.tsx index 14e5c86f4..844dfd76b 100644 --- a/app/actions/definitions/navigation.tsx +++ b/app/actions/definitions/navigation.tsx @@ -26,6 +26,7 @@ import SearchQuery from "~/models/SearchQuery"; import KeyboardShortcuts from "~/scenes/KeyboardShortcuts"; import { createAction } from "~/actions"; import { NavigationSection, RecentSearchesSection } from "~/actions/sections"; +import env from "~/env"; import Desktop from "~/utils/Desktop"; import history from "~/utils/history"; import isCloudHosted from "~/utils/isCloudHosted"; @@ -209,7 +210,12 @@ export const logout = createAction({ analyticsName: "Log out", section: NavigationSection, icon: , - perform: () => stores.auth.logout(), + perform: () => { + void stores.auth.logout(); + if (env.OIDC_LOGOUT_URI) { + window.location.replace(env.OIDC_LOGOUT_URI); + } + }, }); export const rootNavigationActions = [ diff --git a/app/scenes/Logout.tsx b/app/scenes/Logout.tsx index 2f21dc099..32f4e27d8 100644 --- a/app/scenes/Logout.tsx +++ b/app/scenes/Logout.tsx @@ -1,10 +1,15 @@ import * as React from "react"; import { Redirect } from "react-router-dom"; +import env from "~/env"; import useStores from "~/hooks/useStores"; const Logout = () => { const { auth } = useStores(); void auth.logout(); + if (env.OIDC_LOGOUT_URI) { + window.location.replace(env.OIDC_LOGOUT_URI); + return null; + } return ; }; diff --git a/server/env.ts b/server/env.ts index d014dc8af..2c048f869 100644 --- a/server/env.ts +++ b/server/env.ts @@ -499,6 +499,16 @@ export class Environment { process.env.OIDC_USERINFO_URI ); + /** + * The OIDC logout endpoint. + */ + @IsOptional() + @IsUrl({ + require_tld: false, + allow_underscores: true, + }) + public OIDC_LOGOUT_URI = this.toOptionalString(process.env.OIDC_LOGOUT_URI); + /** * The OIDC profile field to use as the username. The default value is * "preferred_username". diff --git a/server/presenters/env.ts b/server/presenters/env.ts index 4c8218aca..edaaeca61 100644 --- a/server/presenters/env.ts +++ b/server/presenters/env.ts @@ -33,6 +33,7 @@ export default function present( process.env.SOURCE_COMMIT || process.env.SOURCE_VERSION || undefined, APP_NAME: env.APP_NAME, ROOT_SHARE_ID: options.rootShareId || undefined, + OIDC_LOGOUT_URI: env.OIDC_LOGOUT_URI || undefined, analytics: { service: options.analytics?.service, diff --git a/shared/types.ts b/shared/types.ts index 83a72773c..714b6eea8 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -61,6 +61,7 @@ export type PublicEnv = { RELEASE: string | undefined; APP_NAME: string; ROOT_SHARE_ID?: string; + OIDC_LOGOUT_URI?: string; analytics: { service?: IntegrationService | UserCreatableIntegrationService; settings?: IntegrationSettings;