From 1f0986a94d20dc2a27f45d402c6add4ea3e95349 Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 23 Mar 2026 16:41:25 -0500 Subject: [PATCH] fixed --- .env.example | 1 + README.md | 1 + UNRAID.md | 7 +++++++ lib/auth.ts | 6 +++++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 5afc745..eae9505 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ DATABASE_PATH=/data/inven.sqlite APP_NAME=Inven AUTH_SECRET=change-me-to-a-long-random-secret +AUTH_SECURE_COOKIES=false ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=change-me-now diff --git a/README.md b/README.md index 1cb4015..f7fd35d 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ Suggested Unraid mapping: - Container port: `3000` - Environment variable: `DATABASE_PATH=/data/inven.sqlite` - Environment variable: `AUTH_SECRET=` +- Environment variable: `AUTH_SECURE_COOKIES=false` for plain HTTP on a LAN, `true` only behind HTTPS - Environment variable: `ADMIN_EMAIL=` - Environment variable: `ADMIN_PASSWORD=` diff --git a/UNRAID.md b/UNRAID.md index 11baadf..27bb8c6 100644 --- a/UNRAID.md +++ b/UNRAID.md @@ -17,6 +17,8 @@ If a change would alter how the container is built, started, configured, mapped, Recommended: `/data/inven.sqlite` - `AUTH_SECRET` Use a long random string. This signs login sessions. +- `AUTH_SECURE_COOKIES` + Set to `false` for normal `http://` access on your LAN. Set to `true` only when the app is served over HTTPS. - `ADMIN_EMAIL` Initial bootstrap admin email. - `ADMIN_PASSWORD` @@ -27,6 +29,7 @@ Important: - The bootstrap admin is created only when the database has no users yet. - Changing `ADMIN_EMAIL` or `ADMIN_PASSWORD` after first boot does not replace an existing user automatically. - Keep `AUTH_SECRET` stable after deployment. Rotating it will invalidate active sessions. +- If you access the app over plain HTTP and `AUTH_SECURE_COOKIES=true`, login will appear to work but the browser will not stay signed in. ## CLI Build And Run @@ -62,6 +65,7 @@ docker run -d \ -v /mnt/user/appdata/inven/data:/data \ -e DATABASE_PATH=/data/inven.sqlite \ -e AUTH_SECRET='replace-with-a-long-random-secret' \ + -e AUTH_SECURE_COOKIES='false' \ -e ADMIN_EMAIL='admin@example.com' \ -e ADMIN_PASSWORD='replace-with-a-strong-password' \ --restart unless-stopped \ @@ -126,6 +130,8 @@ Add these variables: Value: `/data/inven.sqlite` - `AUTH_SECRET` Value: a long random secret +- `AUTH_SECURE_COOKIES` + Value: `false` for standard LAN HTTP access - `ADMIN_EMAIL` Value: your initial admin email - `ADMIN_PASSWORD` @@ -159,6 +165,7 @@ When app changes do require install changes: - Confirm `ADMIN_EMAIL` and `ADMIN_PASSWORD` were present on first boot - If the database already existed before auth was configured, the bootstrap user may not have been created - Confirm `AUTH_SECRET` is set and stable +- Confirm `AUTH_SECURE_COOKIES=false` if you are not serving the app over HTTPS ### Sessions keep getting invalidated diff --git a/lib/auth.ts b/lib/auth.ts index 74809d3..a53801d 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -17,6 +17,10 @@ function getAuthSecret() { return process.env.AUTH_SECRET || "dev-insecure-auth-secret"; } +function useSecureCookies() { + return process.env.AUTH_SECURE_COOKIES === "true"; +} + function hashPassword(password: string) { const salt = crypto.randomBytes(16).toString("hex"); const hash = crypto.scryptSync(password, salt, 64).toString("hex"); @@ -105,7 +109,7 @@ export async function createSession(user: { id: number; email: string; role: str cookieStore.set(SESSION_COOKIE, encodeSession(payload), { httpOnly: true, sameSite: "lax", - secure: process.env.NODE_ENV === "production", + secure: useSecureCookies(), path: "/", maxAge: SESSION_TTL_SECONDS });