Login feature flag - the rest.
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
whisper-web:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
# Runtime feature flags (Decisions.md D-015).
|
||||
AUTH_ENABLED: "true" # set to "false" to disable login/register
|
||||
volumes:
|
||||
# Persists the SQLite database (users + sessions).
|
||||
- whisper-data:/app/data
|
||||
|
||||
volumes:
|
||||
whisper-data:
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Server feature flags (Decisions.md D-015) — read from the process
|
||||
* environment at startup, so one Docker image serves every configuration
|
||||
* (e.g. `AUTH_ENABLED=false` in docker-compose.yml). The client is never
|
||||
* rebuilt for a flag: it discovers auth availability at runtime from the
|
||||
* `GET /api/auth/me` probe it already makes (404 → feature off).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interpret an env-var flag. Unset or empty → `fallback`;
|
||||
* "false", "0", "no", "off" (any case) → false; anything else → true.
|
||||
*/
|
||||
export function envFlag(value: string | undefined, fallback: boolean): boolean {
|
||||
if (value === undefined || value === "") return fallback;
|
||||
return !["false", "0", "no", "off"].includes(value.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Login/register (M4): the /api/auth/* endpoints, and thereby the Sign in
|
||||
* UI (src/components/AuthForms.tsx renders nothing when /me 404s).
|
||||
* Enabled by default; set AUTH_ENABLED=false to disable.
|
||||
*/
|
||||
export const AUTH_ENABLED = envFlag(process.env.AUTH_ENABLED, true);
|
||||
@@ -0,0 +1,21 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { envFlag } from "../src/server/flags";
|
||||
|
||||
test("unset or empty falls back", () => {
|
||||
expect(envFlag(undefined, true)).toBe(true);
|
||||
expect(envFlag(undefined, false)).toBe(false);
|
||||
expect(envFlag("", true)).toBe(true);
|
||||
expect(envFlag("", false)).toBe(false);
|
||||
});
|
||||
|
||||
test("disabling spellings, any case", () => {
|
||||
for (const value of ["false", "FALSE", "False", "0", "no", "off", "OFF"]) {
|
||||
expect(envFlag(value, true)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("anything else enables", () => {
|
||||
for (const value of ["true", "1", "yes", "on", "enabled"]) {
|
||||
expect(envFlag(value, false)).toBe(true);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user