From ab6ec999c52fe395f8148ce122982b3b628a0ff7 Mon Sep 17 00:00:00 2001 From: zvictor Date: Thu, 5 Mar 2026 17:55:34 -0300 Subject: [PATCH 1/5] centralize URLs into single canonical URL var --- cli/src/commands/auth-bootstrap-ceo.ts | 6 ++++ cli/src/commands/env.ts | 41 ++++++++++++++++++++++++++ cli/src/commands/onboard.ts | 22 ++++++++++++-- doc/DOCKER.md | 22 ++++++++++++++ server/src/auth/better-auth.ts | 25 ++++++++++++++++ server/src/config.ts | 21 ++++++++++++- server/src/index.ts | 19 ++++++++++++ 7 files changed, 152 insertions(+), 4 deletions(-) diff --git a/cli/src/commands/auth-bootstrap-ceo.ts b/cli/src/commands/auth-bootstrap-ceo.ts index 63490f2d..a844c447 100644 --- a/cli/src/commands/auth-bootstrap-ceo.ts +++ b/cli/src/commands/auth-bootstrap-ceo.ts @@ -28,6 +28,12 @@ function resolveDbUrl(configPath?: string) { function resolveBaseUrl(configPath?: string, explicitBaseUrl?: string) { if (explicitBaseUrl) return explicitBaseUrl.replace(/\/+$/, ""); + const fromEnv = + process.env.PAPERCLIP_PUBLIC_URL ?? + process.env.PAPERCLIP_AUTH_PUBLIC_BASE_URL ?? + process.env.BETTER_AUTH_URL ?? + process.env.BETTER_AUTH_BASE_URL; + if (fromEnv?.trim()) return fromEnv.trim().replace(/\/+$/, ""); const config = readConfig(configPath); if (config?.auth.baseUrlMode === "explicit" && config.auth.publicBaseUrl) { return config.auth.publicBaseUrl.replace(/\/+$/, ""); diff --git a/cli/src/commands/env.ts b/cli/src/commands/env.ts index b8eb83a2..2a584785 100644 --- a/cli/src/commands/env.ts +++ b/cli/src/commands/env.ts @@ -118,6 +118,29 @@ function collectDeploymentEnvRows(config: PaperclipConfig | null, configPath: st const dbUrl = process.env.DATABASE_URL ?? config?.database?.connectionString ?? ""; const databaseMode = config?.database?.mode ?? "embedded-postgres"; const dbUrlSource: EnvSource = process.env.DATABASE_URL ? "env" : config?.database?.connectionString ? "config" : "missing"; + const publicUrl = + process.env.PAPERCLIP_PUBLIC_URL ?? + process.env.PAPERCLIP_AUTH_PUBLIC_BASE_URL ?? + process.env.BETTER_AUTH_URL ?? + process.env.BETTER_AUTH_BASE_URL ?? + config?.auth?.publicBaseUrl ?? + ""; + const publicUrlSource: EnvSource = + process.env.PAPERCLIP_PUBLIC_URL + ? "env" + : process.env.PAPERCLIP_AUTH_PUBLIC_BASE_URL || process.env.BETTER_AUTH_URL || process.env.BETTER_AUTH_BASE_URL + ? "env" + : config?.auth?.publicBaseUrl + ? "config" + : "missing"; + let trustedOriginsDefault = ""; + if (publicUrl) { + try { + trustedOriginsDefault = new URL(publicUrl).origin; + } catch { + trustedOriginsDefault = ""; + } + } const heartbeatInterval = process.env.HEARTBEAT_SCHEDULER_INTERVAL_MS ?? DEFAULT_HEARTBEAT_SCHEDULER_INTERVAL_MS; const heartbeatEnabled = process.env.HEARTBEAT_SCHEDULER_ENABLED ?? "true"; @@ -192,6 +215,24 @@ function collectDeploymentEnvRows(config: PaperclipConfig | null, configPath: st required: false, note: "HTTP listen port", }, + { + key: "PAPERCLIP_PUBLIC_URL", + value: publicUrl, + source: publicUrlSource, + required: false, + note: "Canonical public URL for auth/callback/invite origin wiring", + }, + { + key: "BETTER_AUTH_TRUSTED_ORIGINS", + value: process.env.BETTER_AUTH_TRUSTED_ORIGINS ?? trustedOriginsDefault, + source: process.env.BETTER_AUTH_TRUSTED_ORIGINS + ? "env" + : trustedOriginsDefault + ? "default" + : "missing", + required: false, + note: "Comma-separated auth origin allowlist (auto-derived from PAPERCLIP_PUBLIC_URL when possible)", + }, { key: "PAPERCLIP_AGENT_JWT_TTL_SECONDS", value: process.env.PAPERCLIP_AGENT_JWT_TTL_SECONDS ?? DEFAULT_AGENT_JWT_TTL_SECONDS, diff --git a/cli/src/commands/onboard.ts b/cli/src/commands/onboard.ts index 9fee5f84..9be97107 100644 --- a/cli/src/commands/onboard.ts +++ b/cli/src/commands/onboard.ts @@ -46,6 +46,7 @@ type OnboardOptions = { type OnboardDefaults = Pick; const ONBOARD_ENV_KEYS = [ + "PAPERCLIP_PUBLIC_URL", "DATABASE_URL", "PAPERCLIP_DB_BACKUP_ENABLED", "PAPERCLIP_DB_BACKUP_INTERVAL_MINUTES", @@ -60,6 +61,7 @@ const ONBOARD_ENV_KEYS = [ "PAPERCLIP_AUTH_BASE_URL_MODE", "PAPERCLIP_AUTH_PUBLIC_BASE_URL", "BETTER_AUTH_URL", + "BETTER_AUTH_BASE_URL", "PAPERCLIP_STORAGE_PROVIDER", "PAPERCLIP_STORAGE_LOCAL_DIR", "PAPERCLIP_STORAGE_S3_BUCKET", @@ -99,6 +101,12 @@ function quickstartDefaultsFromEnv(): { defaults: OnboardDefaults; usedEnvKeys: const defaultStorage = defaultStorageConfig(); const defaultSecrets = defaultSecretsConfig(); const databaseUrl = process.env.DATABASE_URL?.trim() || undefined; + const publicUrl = + process.env.PAPERCLIP_PUBLIC_URL?.trim() || + process.env.PAPERCLIP_AUTH_PUBLIC_BASE_URL?.trim() || + process.env.BETTER_AUTH_URL?.trim() || + process.env.BETTER_AUTH_BASE_URL?.trim() || + undefined; const deploymentMode = parseEnumFromEnv(process.env.PAPERCLIP_DEPLOYMENT_MODE, DEPLOYMENT_MODES) ?? "local_trusted"; const deploymentExposureFromEnv = parseEnumFromEnv( @@ -107,8 +115,7 @@ function quickstartDefaultsFromEnv(): { defaults: OnboardDefaults; usedEnvKeys: ); const deploymentExposure = deploymentMode === "local_trusted" ? "private" : (deploymentExposureFromEnv ?? "private"); - const authPublicBaseUrl = - (process.env.PAPERCLIP_AUTH_PUBLIC_BASE_URL ?? process.env.BETTER_AUTH_URL)?.trim() || undefined; + const authPublicBaseUrl = publicUrl; const authBaseUrlModeFromEnv = parseEnumFromEnv( process.env.PAPERCLIP_AUTH_BASE_URL_MODE, AUTH_BASE_URL_MODES, @@ -120,6 +127,15 @@ function quickstartDefaultsFromEnv(): { defaults: OnboardDefaults; usedEnvKeys: .map((value) => value.trim().toLowerCase()) .filter((value) => value.length > 0) : []; + const hostnameFromPublicUrl = publicUrl + ? (() => { + try { + return new URL(publicUrl).hostname.trim().toLowerCase(); + } catch { + return null; + } + })() + : null; const storageProvider = parseEnumFromEnv(process.env.PAPERCLIP_STORAGE_PROVIDER, STORAGE_PROVIDERS) ?? defaultStorage.provider; @@ -157,7 +173,7 @@ function quickstartDefaultsFromEnv(): { defaults: OnboardDefaults; usedEnvKeys: exposure: deploymentExposure, host: process.env.HOST ?? "127.0.0.1", port: Number(process.env.PORT) || 3100, - allowedHostnames: Array.from(new Set(allowedHostnamesFromEnv)), + allowedHostnames: Array.from(new Set([...allowedHostnamesFromEnv, ...(hostnameFromPublicUrl ? [hostnameFromPublicUrl] : [])])), serveUi: parseBooleanFromEnv(process.env.SERVE_UI) ?? true, }, auth: { diff --git a/doc/DOCKER.md b/doc/DOCKER.md index 033812f3..b7686984 100644 --- a/doc/DOCKER.md +++ b/doc/DOCKER.md @@ -42,6 +42,28 @@ Optional overrides: PAPERCLIP_PORT=3200 PAPERCLIP_DATA_DIR=./data/pc docker compose -f docker-compose.quickstart.yml up --build ``` +## Authenticated Compose (Single Public URL) + +For authenticated deployments, set one canonical public URL and let Paperclip derive auth/callback defaults: + +```yaml +services: + paperclip: + environment: + PAPERCLIP_DEPLOYMENT_MODE: authenticated + PAPERCLIP_DEPLOYMENT_EXPOSURE: private + PAPERCLIP_PUBLIC_URL: https://desk.koker.net +``` + +`PAPERCLIP_PUBLIC_URL` is used as the primary source for: + +- auth public base URL +- Better Auth base URL defaults +- bootstrap invite URL defaults +- hostname allowlist defaults (hostname extracted from URL) + +Granular overrides remain available if needed (`PAPERCLIP_AUTH_PUBLIC_BASE_URL`, `BETTER_AUTH_URL`, `BETTER_AUTH_TRUSTED_ORIGINS`, `PAPERCLIP_ALLOWED_HOSTNAMES`). + ## Claude + Codex Local Adapters in Docker The image pre-installs: diff --git a/server/src/auth/better-auth.ts b/server/src/auth/better-auth.ts index db117a00..c234cb49 100644 --- a/server/src/auth/better-auth.ts +++ b/server/src/auth/better-auth.ts @@ -42,13 +42,38 @@ function headersFromExpressRequest(req: Request): Headers { return headersFromNodeHeaders(req.headers); } +export function deriveAuthTrustedOrigins(config: Config): string[] { + const baseUrl = config.authBaseUrlMode === "explicit" ? config.authPublicBaseUrl : undefined; + const trustedOrigins = new Set(); + + if (baseUrl) { + try { + trustedOrigins.add(new URL(baseUrl).origin); + } catch { + // Better Auth will surface invalid base URL separately. + } + } + if (config.deploymentMode === "authenticated" && config.deploymentExposure === "private") { + for (const hostname of config.allowedHostnames) { + const trimmed = hostname.trim().toLowerCase(); + if (!trimmed) continue; + trustedOrigins.add(`https://${trimmed}`); + trustedOrigins.add(`http://${trimmed}`); + } + } + + return Array.from(trustedOrigins); +} + export function createBetterAuthInstance(db: Db, config: Config): BetterAuthInstance { const baseUrl = config.authBaseUrlMode === "explicit" ? config.authPublicBaseUrl : undefined; const secret = process.env.BETTER_AUTH_SECRET ?? process.env.PAPERCLIP_AGENT_JWT_SECRET ?? "paperclip-dev-secret"; + const trustedOrigins = deriveAuthTrustedOrigins(config); const authConfig = { baseURL: baseUrl, secret, + trustedOrigins, database: drizzleAdapter(db, { provider: "pg", schema: { diff --git a/server/src/config.ts b/server/src/config.ts index 01a37588..5aa0c31e 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -130,9 +130,12 @@ export function loadConfig(): Config { AUTH_BASE_URL_MODES.includes(authBaseUrlModeFromEnvRaw as AuthBaseUrlMode) ? (authBaseUrlModeFromEnvRaw as AuthBaseUrlMode) : null; + const publicUrlFromEnv = process.env.PAPERCLIP_PUBLIC_URL; const authPublicBaseUrlRaw = process.env.PAPERCLIP_AUTH_PUBLIC_BASE_URL ?? process.env.BETTER_AUTH_URL ?? + process.env.BETTER_AUTH_BASE_URL ?? + publicUrlFromEnv ?? fileConfig?.auth?.publicBaseUrl; const authPublicBaseUrl = authPublicBaseUrlRaw?.trim() || undefined; const authBaseUrlMode: AuthBaseUrlMode = @@ -146,8 +149,24 @@ export function loadConfig(): Config { .map((value) => value.trim().toLowerCase()) .filter((value) => value.length > 0) : null; + const publicUrlHostname = authPublicBaseUrl + ? (() => { + try { + return new URL(authPublicBaseUrl).hostname.trim().toLowerCase(); + } catch { + return null; + } + })() + : null; const allowedHostnames = Array.from( - new Set((allowedHostnamesFromEnv ?? fileConfig?.server.allowedHostnames ?? []).map((value) => value.trim().toLowerCase()).filter(Boolean)), + new Set( + [ + ...(allowedHostnamesFromEnv ?? fileConfig?.server.allowedHostnames ?? []), + ...(publicUrlHostname ? [publicUrlHostname] : []), + ] + .map((value) => value.trim().toLowerCase()) + .filter(Boolean), + ), ); const companyDeletionEnvRaw = process.env.PAPERCLIP_ENABLE_COMPANY_DELETION; const companyDeletionEnabled = diff --git a/server/src/index.ts b/server/src/index.ts index ada5743f..052f671c 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -412,6 +412,7 @@ if (config.deploymentMode === "authenticated") { const { createBetterAuthHandler, createBetterAuthInstance, + deriveAuthTrustedOrigins, resolveBetterAuthSession, resolveBetterAuthSessionFromHeaders, } = await import("./auth/better-auth.js"); @@ -422,6 +423,24 @@ if (config.deploymentMode === "authenticated") { "authenticated mode requires BETTER_AUTH_SECRET (or PAPERCLIP_AGENT_JWT_SECRET) to be set", ); } + const derivedTrustedOrigins = deriveAuthTrustedOrigins(config); + const envTrustedOrigins = (process.env.BETTER_AUTH_TRUSTED_ORIGINS ?? "") + .split(",") + .map((value) => value.trim()) + .filter((value) => value.length > 0); + const effectiveTrustedOrigins = Array.from(new Set([...derivedTrustedOrigins, ...envTrustedOrigins])); + logger.info( + { + authBaseUrlMode: config.authBaseUrlMode, + authPublicBaseUrl: config.authPublicBaseUrl ?? null, + trustedOrigins: effectiveTrustedOrigins, + trustedOriginsSource: { + derived: derivedTrustedOrigins.length, + env: envTrustedOrigins.length, + }, + }, + "Authenticated mode auth origin configuration", + ); const auth = createBetterAuthInstance(db as any, config); betterAuthHandler = createBetterAuthHandler(auth); resolveSession = (req) => resolveBetterAuthSession(auth, req); From 82d97418b2d9d8b7247d7394afaab6295af0415f Mon Sep 17 00:00:00 2001 From: zvictor Date: Thu, 5 Mar 2026 18:33:49 -0300 Subject: [PATCH 2/5] set `PAPERCLIP_PUBLIC_URL` in compose files --- doc/DOCKER.md | 4 ++++ docker-compose.quickstart.yml | 1 + docker-compose.yml | 1 + 3 files changed, 6 insertions(+) diff --git a/doc/DOCKER.md b/doc/DOCKER.md index b7686984..49d0c4ab 100644 --- a/doc/DOCKER.md +++ b/doc/DOCKER.md @@ -42,6 +42,8 @@ Optional overrides: PAPERCLIP_PORT=3200 PAPERCLIP_DATA_DIR=./data/pc docker compose -f docker-compose.quickstart.yml up --build ``` +If you change host port or use a non-local domain, set `PAPERCLIP_PUBLIC_URL` to the external URL you will use in browser/auth flows. + ## Authenticated Compose (Single Public URL) For authenticated deployments, set one canonical public URL and let Paperclip derive auth/callback defaults: @@ -64,6 +66,8 @@ services: Granular overrides remain available if needed (`PAPERCLIP_AUTH_PUBLIC_BASE_URL`, `BETTER_AUTH_URL`, `BETTER_AUTH_TRUSTED_ORIGINS`, `PAPERCLIP_ALLOWED_HOSTNAMES`). +Set `PAPERCLIP_ALLOWED_HOSTNAMES` explicitly only when you need additional hostnames beyond the public URL host (for example Tailscale/LAN aliases or multiple private hostnames). + ## Claude + Codex Local Adapters in Docker The image pre-installs: diff --git a/docker-compose.quickstart.yml b/docker-compose.quickstart.yml index 373c5d48..66623c75 100644 --- a/docker-compose.quickstart.yml +++ b/docker-compose.quickstart.yml @@ -10,5 +10,6 @@ services: PAPERCLIP_HOME: "/paperclip" OPENAI_API_KEY: "${OPENAI_API_KEY:-}" ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY:-}" + PAPERCLIP_PUBLIC_URL: "${PAPERCLIP_PUBLIC_URL:-http://localhost:3100}" volumes: - "${PAPERCLIP_DATA_DIR:-./data/docker-paperclip}:/paperclip" diff --git a/docker-compose.yml b/docker-compose.yml index d3cdc6ad..f6d09fd8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: DATABASE_URL: postgres://paperclip:paperclip@db:5432/paperclip PORT: "3100" SERVE_UI: "true" + PAPERCLIP_PUBLIC_URL: "${PAPERCLIP_PUBLIC_URL:-http://localhost:3100}" depends_on: - db From 08ac2bc9a7ff7f689f361bbcee94dd9453ea352c Mon Sep 17 00:00:00 2001 From: zvictor Date: Fri, 6 Mar 2026 11:28:31 -0300 Subject: [PATCH 3/5] fix: parseBooleanFromEnv silently treats common truthy values as false --- cli/src/commands/onboard.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/src/commands/onboard.ts b/cli/src/commands/onboard.ts index 9be97107..e0c8a2bf 100644 --- a/cli/src/commands/onboard.ts +++ b/cli/src/commands/onboard.ts @@ -76,7 +76,10 @@ const ONBOARD_ENV_KEYS = [ function parseBooleanFromEnv(rawValue: string | undefined): boolean | null { if (rawValue === undefined) return null; - return rawValue === "true"; + const lower = rawValue.trim().toLowerCase(); + if (lower === "true" || lower === "1" || lower === "yes") return true; + if (lower === "false" || lower === "0" || lower === "no") return false; + return null; } function parseNumberFromEnv(rawValue: string | undefined): number | null { From e1d4e37776f067c822ce2f56ffe405468de559d1 Mon Sep 17 00:00:00 2001 From: zvictor Date: Fri, 6 Mar 2026 11:29:28 -0300 Subject: [PATCH 4/5] fix(onboard): preserve env-derived secrets defaults and report ignored exposure env in local_trusted mode --- cli/src/commands/onboard.ts | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/cli/src/commands/onboard.ts b/cli/src/commands/onboard.ts index e0c8a2bf..0e70d9cf 100644 --- a/cli/src/commands/onboard.ts +++ b/cli/src/commands/onboard.ts @@ -99,7 +99,11 @@ function resolvePathFromEnv(rawValue: string | undefined): string | null { return path.resolve(expandHomePrefix(rawValue.trim())); } -function quickstartDefaultsFromEnv(): { defaults: OnboardDefaults; usedEnvKeys: string[] } { +function quickstartDefaultsFromEnv(): { + defaults: OnboardDefaults; + usedEnvKeys: string[]; + ignoredEnvKeys: Array<{ key: string; reason: string }>; +} { const instanceId = resolvePaperclipInstanceId(); const defaultStorage = defaultStorageConfig(); const defaultSecrets = defaultSecretsConfig(); @@ -209,8 +213,19 @@ function quickstartDefaultsFromEnv(): { defaults: OnboardDefaults; usedEnvKeys: }, }, }; - const usedEnvKeys = ONBOARD_ENV_KEYS.filter((key) => process.env[key] !== undefined); - return { defaults, usedEnvKeys }; + const ignoredEnvKeys: Array<{ key: string; reason: string }> = []; + if (deploymentMode === "local_trusted" && process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE !== undefined) { + ignoredEnvKeys.push({ + key: "PAPERCLIP_DEPLOYMENT_EXPOSURE", + reason: "Ignored because deployment mode local_trusted always forces private exposure", + }); + } + + const ignoredKeySet = new Set(ignoredEnvKeys.map((entry) => entry.key)); + const usedEnvKeys = ONBOARD_ENV_KEYS.filter( + (key) => process.env[key] !== undefined && !ignoredKeySet.has(key), + ); + return { defaults, usedEnvKeys, ignoredEnvKeys }; } export async function onboard(opts: OnboardOptions): Promise { @@ -266,7 +281,7 @@ export async function onboard(opts: OnboardOptions): Promise { } let llm: PaperclipConfig["llm"] | undefined; - const { defaults: derivedDefaults, usedEnvKeys } = quickstartDefaultsFromEnv(); + const { defaults: derivedDefaults, usedEnvKeys, ignoredEnvKeys } = quickstartDefaultsFromEnv(); let { database, logging, @@ -348,7 +363,14 @@ export async function onboard(opts: OnboardOptions): Promise { storage = await promptStorage(storage); p.log.step(pc.bold("Secrets")); - secrets = defaultSecretsConfig(); + const secretsDefaults = defaultSecretsConfig(); + secrets = { + provider: secrets.provider ?? secretsDefaults.provider, + strictMode: secrets.strictMode ?? secretsDefaults.strictMode, + localEncrypted: { + keyFilePath: secrets.localEncrypted?.keyFilePath ?? secretsDefaults.localEncrypted.keyFilePath, + }, + }; p.log.message( pc.dim( `Using defaults: provider=${secrets.provider}, strictMode=${secrets.strictMode}, keyFile=${secrets.localEncrypted.keyFilePath}`, @@ -364,6 +386,9 @@ export async function onboard(opts: OnboardOptions): Promise { pc.dim("No environment overrides detected: embedded database, file storage, local encrypted secrets."), ); } + for (const ignored of ignoredEnvKeys) { + p.log.message(pc.dim(`Ignored ${ignored.key}: ${ignored.reason}`)); + } } const jwtSecret = ensureAgentJwtSecret(configPath); From 55bb3012eaa926fdd73d5ccd3386128fbd958a92 Mon Sep 17 00:00:00 2001 From: zvictor Date: Fri, 6 Mar 2026 15:38:33 -0300 Subject: [PATCH 5/5] fix(auth): apply effective trusted origins and honor allowed hostnames in public mode --- server/src/auth/better-auth.ts | 8 ++++---- server/src/index.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/auth/better-auth.ts b/server/src/auth/better-auth.ts index c234cb49..5c80fad7 100644 --- a/server/src/auth/better-auth.ts +++ b/server/src/auth/better-auth.ts @@ -53,7 +53,7 @@ export function deriveAuthTrustedOrigins(config: Config): string[] { // Better Auth will surface invalid base URL separately. } } - if (config.deploymentMode === "authenticated" && config.deploymentExposure === "private") { + if (config.deploymentMode === "authenticated") { for (const hostname of config.allowedHostnames) { const trimmed = hostname.trim().toLowerCase(); if (!trimmed) continue; @@ -65,15 +65,15 @@ export function deriveAuthTrustedOrigins(config: Config): string[] { return Array.from(trustedOrigins); } -export function createBetterAuthInstance(db: Db, config: Config): BetterAuthInstance { +export function createBetterAuthInstance(db: Db, config: Config, trustedOrigins?: string[]): BetterAuthInstance { const baseUrl = config.authBaseUrlMode === "explicit" ? config.authPublicBaseUrl : undefined; const secret = process.env.BETTER_AUTH_SECRET ?? process.env.PAPERCLIP_AGENT_JWT_SECRET ?? "paperclip-dev-secret"; - const trustedOrigins = deriveAuthTrustedOrigins(config); + const effectiveTrustedOrigins = trustedOrigins ?? deriveAuthTrustedOrigins(config); const authConfig = { baseURL: baseUrl, secret, - trustedOrigins, + trustedOrigins: effectiveTrustedOrigins, database: drizzleAdapter(db, { provider: "pg", schema: { diff --git a/server/src/index.ts b/server/src/index.ts index 6604bb54..e78a6479 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -441,7 +441,7 @@ if (config.deploymentMode === "authenticated") { }, "Authenticated mode auth origin configuration", ); - const auth = createBetterAuthInstance(db as any, config); + const auth = createBetterAuthInstance(db as any, config, effectiveTrustedOrigins); betterAuthHandler = createBetterAuthHandler(auth); resolveSession = (req) => resolveBetterAuthSession(auth, req); resolveSessionFromHeaders = (headers) => resolveBetterAuthSessionFromHeaders(auth, headers);