fix: decouple session cookie 'secure' flag from NODE_ENV
CI / web (push) Successful in 16s
CI / api (push) Successful in 17s

Cookie was silently never set because NODE_ENV=production forced
secure=true while the app is served over plain HTTP on the LAN (TLS
terminates at a reverse proxy later, not here). Add explicit
COOKIE_SECURE env var, default false.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 20:21:52 -06:00
parent a075488f4b
commit ac768ed0db
3 changed files with 10 additions and 1 deletions
+5
View File
@@ -16,6 +16,11 @@ ADMIN_PASSWORD=
# local | oidc (oidc not implemented yet, see issue #12) # local | oidc (oidc not implemented yet, see issue #12)
AUTH_MODE=local AUTH_MODE=local
# Set to true only once a TLS-terminating reverse proxy sits in front (see
# issue #13). Leave false for plain-HTTP LAN access, otherwise the session
# cookie won't be set at all.
COOKIE_SECURE=false
PORT=3000 PORT=3000
POLL_INTERVAL_SECONDS=30 POLL_INTERVAL_SECONDS=30
SNAPSHOT_RETENTION_HOURS=24 SNAPSHOT_RETENTION_HOURS=24
+4
View File
@@ -15,6 +15,9 @@ export interface AppConfig {
snapshotRetentionHours: number; snapshotRetentionHours: number;
authMode: "local" | "oidc"; authMode: "local" | "oidc";
sessionSecret: string; sessionSecret: string;
// Only set once a TLS-terminating reverse proxy sits in front (see issue #13) —
// browsers silently drop `secure` cookies over plain HTTP.
cookieSecure: boolean;
adminUsername: string; adminUsername: string;
adminPassword: string | undefined; adminPassword: string | undefined;
proxmox: { proxmox: {
@@ -42,6 +45,7 @@ export function loadConfig(hostsConfigPath: string): AppConfig {
snapshotRetentionHours: Number(process.env.SNAPSHOT_RETENTION_HOURS ?? 24), snapshotRetentionHours: Number(process.env.SNAPSHOT_RETENTION_HOURS ?? 24),
authMode: (process.env.AUTH_MODE as "local" | "oidc") ?? "local", authMode: (process.env.AUTH_MODE as "local" | "oidc") ?? "local",
sessionSecret: required("SESSION_SECRET"), sessionSecret: required("SESSION_SECRET"),
cookieSecure: process.env.COOKIE_SECURE === "true",
adminUsername: process.env.ADMIN_USERNAME ?? "admin", adminUsername: process.env.ADMIN_USERNAME ?? "admin",
adminPassword: process.env.ADMIN_PASSWORD, adminPassword: process.env.ADMIN_PASSWORD,
proxmox: { proxmox: {
+1 -1
View File
@@ -46,7 +46,7 @@ async function main() {
await app.register(fastifyCookie); await app.register(fastifyCookie);
await app.register(fastifySession, { await app.register(fastifySession, {
secret: cfg.sessionSecret, secret: cfg.sessionSecret,
cookie: { secure: process.env.NODE_ENV === "production", maxAge: 1000 * 60 * 60 * 12 }, cookie: { secure: cfg.cookieSecure, maxAge: 1000 * 60 * 60 * 12 },
}); });
registerAuthRoutes(app, db); registerAuthRoutes(app, db);