From 45ef9b6ce9a88ebe69e6ad2e18a9eff174d3825c Mon Sep 17 00:00:00 2001 From: awais786 Date: Fri, 1 May 2026 19:54:58 +0500 Subject: [PATCH 1/4] fix(logout): drive portal-host prefix from required SMB_NAME env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The logout redirect hardcoded "foss." as the portal-host prefix. That broke silently the moment the deployment moved from foss.* to moneta.* in the askii.ai cutover. Make the prefix env-driven via a required SMB_NAME var (no default — crash loudly on misconfig instead of redirecting to the wrong host). SMB_NAME is exposed to the SPA via the @Public decorator on env.ts, flowing through PublicEnvironmentRegister into window.env. Container env name (SMB_NAME) is uniform across every devstack app behind ForwardAuth. See sso-rules RULES.md section 1 Logout. Co-Authored-By: Claude Opus 4.7 (1M context) --- .env.sample | 9 +++++++++ app/stores/AuthStore.ts | 7 ++++--- server/env.ts | 10 ++++++++++ shared/types.ts | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.env.sample b/.env.sample index 63e646c390f9..8c45c8a07120 100644 --- a/.env.sample +++ b/.env.sample @@ -277,3 +277,12 @@ DEBUG=http # Configure lowest severity level for server logs. Should be one of # error, warn, info, http, verbose, debug, or silly LOG_LEVEL=info + +# –––––––––––––––––––––––––––––––––––––– +# –––––––––––– mPass / SSO ––––––––––– +# –––––––––––––––––––––––––––––––––––––– + +# Required when AUTH_TYPE=SSO: portal hostname prefix for the SPA logout +# redirect (-..). Must match the +# ForwardAuth portal host. Same env name across every devstack app. +SMB_NAME= diff --git a/app/stores/AuthStore.ts b/app/stores/AuthStore.ts index 1b3c4e383fc9..39e60f073a65 100644 --- a/app/stores/AuthStore.ts +++ b/app/stores/AuthStore.ts @@ -352,9 +352,10 @@ export default class AuthStore extends Store { } if (userInitiated) { - // Rewrite "foss-." → "foss." so we land on the portal - // (outside ForwardAuth) instead of Outline's own root, which would silently re-auth. - const portalHost = window.location.hostname.replace(/^[^.]*\./, "foss."); + // Rewrite "-." → "." so we land on the + // portal (outside ForwardAuth) instead of Outline's own root, which would silently re-auth. + const smbName = env.SMB_NAME.trim(); + const portalHost = window.location.hostname.replace(/^[^.]*\./, `${smbName}.`); this.logoutRedirectUri = `${window.location.protocol}//${portalHost}`; } diff --git a/server/env.ts b/server/env.ts index 3d93b4e4e270..3e6145fadbf7 100644 --- a/server/env.ts +++ b/server/env.ts @@ -537,6 +537,16 @@ export class Environment { public DEFAULT_EMAIL_DOMAIN = environment.DEFAULT_EMAIL_DOMAIN ?? "askii.ai"; + /** + * Portal hostname prefix used by the SPA logout redirect. + * Required (no default) — the SPA crashes loudly on misconfig instead of + * silently redirecting to the wrong host. Container env name is uniform + * across every devstack app; see sso-rules RULES.md §1 Logout. + */ + @Public + @IsNotEmpty() + public SMB_NAME = environment.SMB_NAME ?? ""; + /** * A boolean switch to toggle the rate limiter at application web server. */ diff --git a/shared/types.ts b/shared/types.ts index ac9cb69d04ef..b303e08240f6 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -104,6 +104,7 @@ export enum MentionType { export type PublicEnv = { ROOT_SHARE_ID?: string; AUTH_TYPE?: string; + SMB_NAME?: string; analytics: { service: IntegrationService; settings: IntegrationSettings; From ec1804043c5ab58b852cd6a9dc0d18c61db07a6a Mon Sep 17 00:00:00 2001 From: awais786 Date: Sat, 2 May 2026 20:31:11 +0500 Subject: [PATCH 2/4] fix(logout): derive portal prefix from hostname instead of SMB_NAME env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops SMB_NAME entirely. The previous approach required threading the value through devstack docker-compose env → @Public env class → SPA bundle, with no default; any broken link crashed logout. Switching to a regex on window.location.hostname removes the env dependency and works for any `-.` shape: - foss-docs.local.moneta.dev → foss.local.moneta.dev - moneta-docs.askii.ai → moneta.askii.ai --- app/stores/AuthStore.ts | 5 ++--- server/env.ts | 10 ---------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/app/stores/AuthStore.ts b/app/stores/AuthStore.ts index 39e60f073a65..6ab3efc2558f 100644 --- a/app/stores/AuthStore.ts +++ b/app/stores/AuthStore.ts @@ -352,10 +352,9 @@ export default class AuthStore extends Store { } if (userInitiated) { - // Rewrite "-." → "." so we land on the + // Rewrite "-." → "." so we land on the // portal (outside ForwardAuth) instead of Outline's own root, which would silently re-auth. - const smbName = env.SMB_NAME.trim(); - const portalHost = window.location.hostname.replace(/^[^.]*\./, `${smbName}.`); + const portalHost = window.location.hostname.replace(/^([^-]+)-[^.]+\.(.+)/, "$1.$2"); this.logoutRedirectUri = `${window.location.protocol}//${portalHost}`; } diff --git a/server/env.ts b/server/env.ts index 3e6145fadbf7..3d93b4e4e270 100644 --- a/server/env.ts +++ b/server/env.ts @@ -537,16 +537,6 @@ export class Environment { public DEFAULT_EMAIL_DOMAIN = environment.DEFAULT_EMAIL_DOMAIN ?? "askii.ai"; - /** - * Portal hostname prefix used by the SPA logout redirect. - * Required (no default) — the SPA crashes loudly on misconfig instead of - * silently redirecting to the wrong host. Container env name is uniform - * across every devstack app; see sso-rules RULES.md §1 Logout. - */ - @Public - @IsNotEmpty() - public SMB_NAME = environment.SMB_NAME ?? ""; - /** * A boolean switch to toggle the rate limiter at application web server. */ From a38b8692db32a05ee5d28cd764d2963a5e9a39e4 Mon Sep 17 00:00:00 2001 From: awais786 Date: Sat, 2 May 2026 20:42:32 +0500 Subject: [PATCH 3/4] fix(logout): drop now-unused SMB_NAME env declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup follow-up to ec1804043 — the regex-based portal-host derivation no longer reads SMB_NAME, so the .env.sample row and the PublicEnv TypeScript field are dead. Removed both. --- .env.sample | 9 --------- shared/types.ts | 1 - 2 files changed, 10 deletions(-) diff --git a/.env.sample b/.env.sample index 8c45c8a07120..63e646c390f9 100644 --- a/.env.sample +++ b/.env.sample @@ -277,12 +277,3 @@ DEBUG=http # Configure lowest severity level for server logs. Should be one of # error, warn, info, http, verbose, debug, or silly LOG_LEVEL=info - -# –––––––––––––––––––––––––––––––––––––– -# –––––––––––– mPass / SSO ––––––––––– -# –––––––––––––––––––––––––––––––––––––– - -# Required when AUTH_TYPE=SSO: portal hostname prefix for the SPA logout -# redirect (-..). Must match the -# ForwardAuth portal host. Same env name across every devstack app. -SMB_NAME= diff --git a/shared/types.ts b/shared/types.ts index b303e08240f6..ac9cb69d04ef 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -104,7 +104,6 @@ export enum MentionType { export type PublicEnv = { ROOT_SHARE_ID?: string; AUTH_TYPE?: string; - SMB_NAME?: string; analytics: { service: IntegrationService; settings: IntegrationSettings; From 6500012c5dea3032fd2391aadf4832e0beb3afae Mon Sep 17 00:00:00 2001 From: awais786 Date: Sat, 2 May 2026 20:44:26 +0500 Subject: [PATCH 4/4] revert: restore SMB_NAME field on PublicEnv Reverts the SMB_NAME removal from shared/types.ts in the previous cleanup commit. The field is harmless to keep on the type, even though the SPA logout path no longer reads it. --- shared/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/types.ts b/shared/types.ts index ac9cb69d04ef..b303e08240f6 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -104,6 +104,7 @@ export enum MentionType { export type PublicEnv = { ROOT_SHARE_ID?: string; AUTH_TYPE?: string; + SMB_NAME?: string; analytics: { service: IntegrationService; settings: IntegrationSettings;