diff --git a/src/lib/auth/session.ts b/src/lib/auth/session.ts index 530ccbf..e3d2a41 100644 --- a/src/lib/auth/session.ts +++ b/src/lib/auth/session.ts @@ -46,7 +46,12 @@ export async function setSessionCookie(token: string): Promise { const cookieStore = await cookies(); cookieStore.set(SESSION_COOKIE, token, { httpOnly: true, - secure: process.env.NODE_ENV === "production", + // Secure by default in production. Set COOKIE_ALLOW_INSECURE=true only + // for temporary testing over plain HTTP (e.g. mid-migration before the + // HTTPS reverse proxy is wired up) — a Secure cookie is silently + // dropped by the browser over HTTP, which looks exactly like "login + // accepts the password but you're bounced straight back to /login". + secure: process.env.NODE_ENV === "production" && process.env.COOKIE_ALLOW_INSECURE !== "true", sameSite: "lax", path: "/", maxAge: SESSION_TTL_MS / 1000, diff --git a/src/lib/db/client.ts b/src/lib/db/client.ts index 832c34a..086a32e 100644 --- a/src/lib/db/client.ts +++ b/src/lib/db/client.ts @@ -8,14 +8,13 @@ const dataDir = process.env.DATA_DIR ?? path.join(process.cwd(), "data"); fs.mkdirSync(dataDir, { recursive: true }); const sqlite = new Database(path.join(dataDir, "db.sqlite")); +// busy_timeout MUST be set before journal_mode: switching to WAL itself +// takes a momentary exclusive lock, and if a concurrent worker is mid-switch +// on a fresh db.sqlite, that first statement has no busy_timeout protection +// yet and throws SQLITE_BUSY immediately instead of waiting. +sqlite.pragma("busy_timeout = 30000"); sqlite.pragma("journal_mode = WAL"); sqlite.pragma("foreign_keys = ON"); -// Next's build-time page-data collection evaluates route modules across -// several worker processes concurrently — without this, two workers -// racing to open/initialize a fresh db.sqlite can throw SQLITE_BUSY -// instead of just waiting for the other's lock to clear. 5s wasn't enough -// once the route count grew — bumped to 30s (build-time only cost). -sqlite.pragma("busy_timeout = 30000"); export const db = drizzle(sqlite, { schema }); export type DB = typeof db;