Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions surfsense_web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=LOCAL or GOOGLE
NEXT_PUBLIC_OIDC_LOGOUT_URL=https://<cognito-domain>/logout
NEXT_PUBLIC_OIDC_CLIENT_ID=<cognito-app-client-id>
NEXT_PUBLIC_OAUTH2_PROXY_URL=https://<subdomain-prefix>auth.<platform-domain>

# Required when AUTH_TYPE=SSO: portal hostname prefix for the SPA
# logout redirect (<prefix>-<app>.<domain> → <prefix>.<domain>). Must
# match the ForwardAuth portal host. Same env name across every
# devstack app — see sso-rules RULES.md §1 Logout. The container reads
# SMB_NAME; docker-entrypoint.js substitutes the bundle's
# __NEXT_PUBLIC_SMB_NAME__ placeholder at startup.
SMB_NAME=
NEXT_PUBLIC_ETL_SERVICE=UNSTRUCTURED or LLAMACLOUD or DOCLING
NEXT_PUBLIC_ZERO_CACHE_URL=http://localhost:4848

Expand Down
2 changes: 2 additions & 0 deletions surfsense_web/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ARG NEXT_PUBLIC_ETL_SERVICE=__NEXT_PUBLIC_ETL_SERVICE__
ARG NEXT_PUBLIC_ZERO_CACHE_URL=__NEXT_PUBLIC_ZERO_CACHE_URL__
ARG NEXT_PUBLIC_DEPLOYMENT_MODE=__NEXT_PUBLIC_DEPLOYMENT_MODE__
ARG NEXT_PUBLIC_OAUTH2_PROXY_URL=__NEXT_PUBLIC_OAUTH2_PROXY_URL__
ARG NEXT_PUBLIC_SMB_NAME=__NEXT_PUBLIC_SMB_NAME__
# These are baked at build time (not placeholder-substituted). Next.js inlines
# them as literal strings and terser dead-code-eliminates branches based on
# truthiness; placeholder tokens look truthy and defeat that optimization.
Expand All @@ -51,6 +52,7 @@ ENV NEXT_PUBLIC_ETL_SERVICE=$NEXT_PUBLIC_ETL_SERVICE
ENV NEXT_PUBLIC_ZERO_CACHE_URL=$NEXT_PUBLIC_ZERO_CACHE_URL
ENV NEXT_PUBLIC_DEPLOYMENT_MODE=$NEXT_PUBLIC_DEPLOYMENT_MODE
ENV NEXT_PUBLIC_OAUTH2_PROXY_URL=$NEXT_PUBLIC_OAUTH2_PROXY_URL
ENV NEXT_PUBLIC_SMB_NAME=$NEXT_PUBLIC_SMB_NAME
ENV NEXT_PUBLIC_LOGOUT_REDIRECT_URL=$NEXT_PUBLIC_LOGOUT_REDIRECT_URL
ENV NEXT_PUBLIC_OIDC_LOGOUT_URL=$NEXT_PUBLIC_OIDC_LOGOUT_URL
ENV NEXT_PUBLIC_OIDC_CLIENT_ID=$NEXT_PUBLIC_OIDC_CLIENT_ID
Expand Down
13 changes: 13 additions & 0 deletions surfsense_web/docker-entrypoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@
const fs = require("fs");
const path = require("path");

// SMB_NAME is required when AUTH_TYPE=SSO. No default — fail loudly at
// startup so the SPA never silently rewrites the logout host to the wrong
// domain. Same env name across every devstack app — see sso-rules
// RULES.md §1 Logout.
if (!process.env.SMB_NAME && process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE === "SSO") {
console.error(
"[entrypoint] ERROR: SMB_NAME env is required when NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=SSO."
);
console.error("[entrypoint] Set it to the portal hostname prefix (e.g. 'moneta').");
process.exit(1);
}

const replacements = [
[
"__NEXT_PUBLIC_FASTAPI_BACKEND_URL__",
Expand All @@ -28,6 +40,7 @@ const replacements = [
],
["__NEXT_PUBLIC_DEPLOYMENT_MODE__", process.env.NEXT_PUBLIC_DEPLOYMENT_MODE || "self-hosted"],
["__NEXT_PUBLIC_OAUTH2_PROXY_URL__", process.env.NEXT_PUBLIC_OAUTH2_PROXY_URL || ""],
["__NEXT_PUBLIC_SMB_NAME__", process.env.SMB_NAME || ""],
];

let filesProcessed = 0;
Expand Down
7 changes: 4 additions & 3 deletions surfsense_web/lib/auth-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,10 @@ export async function logout(): Promise<boolean> {
clearAllTokens();

if (typeof window !== "undefined") {
// Rewrite "foss-<app>.<domain>" → "foss.<domain>" so we land on the portal
// (outside ForwardAuth) instead of SurfSense's own root, which would silently re-auth.
const portalHost = window.location.hostname.replace(/^[^.]*\./, "moneta.");
// Rewrite "<SMB_NAME>-<app>.<domain>" → "<SMB_NAME>.<domain>" so we land on the
// portal (outside ForwardAuth) instead of SurfSense's own root, which would silently re-auth.
const smbName = process.env.NEXT_PUBLIC_SMB_NAME!.trim();
const portalHost = window.location.hostname.replace(/^[^.]*\./, `${smbName}.`);
window.location.href = `${window.location.protocol}//${portalHost}`;
return true;
}
Expand Down
Loading