BillTracker/.env.example

89 lines
5.5 KiB
Plaintext
Raw Permalink Normal View History

2026-05-03 19:51:57 -05:00
# ── Bill Tracker — Environment Variables ──────────────────────────────────────
# Copy this file to .env and fill in your values before deploying.
# Docker Compose reads .env automatically.
# For direct Node.js: NODE_ENV=production node server.cts (or use PM2).
2026-05-03 19:51:57 -05:00
# ── Server ─────────────────────────────────────────────────────────────────────
PORT=3000
NODE_ENV=production
# ── Reverse proxy ──────────────────────────────────────────────────────────────
# Set when running behind a reverse proxy (Docker, nginx, Traefik, Caddy, etc.)
# so req.ip reflects the real client (rate limiting, audit logs, login history)
# and req.secure reflects the original protocol (Secure cookies).
# TRUST_PROXY=true (trust first proxy hop — most common)
# TRUST_PROXY=2 (trust two hops, e.g. CDN + nginx)
# TRUST_PROXY=loopback (trust loopback addresses only)
# Leave unset for direct deployments with no proxy.
# TRUST_PROXY=true
2026-05-09 13:03:36 -05:00
# ── CSRF Cookie httpOnly Setting ──────────────────────────────────────────────
# CSRF cookie httpOnly setting (default: true)
2026-05-31 15:52:50 -05:00
# The SPA fetches the token from GET /api/auth/csrf-token and stores it in
# memory — JavaScript does not need to read the cookie directly. httpOnly=true
# removes the token from the XSS-accessible cookie surface.
# CSRF_HTTP_ONLY: "true" (default — cookie not readable by document.cookie)
# CSRF_HTTP_ONLY: "false" (legacy — only if a custom client reads document.cookie)
2026-05-09 13:03:36 -05:00
#
# ── CSRF Cookie sameSite Setting ──────────────────────────────────────────────
# CSRF cookie sameSite setting (default: strict)
# Options: 'lax', 'strict', 'none'
# CSRF_SAME_SITE: "strict" (most secure - default)
# CSRF_SAME_SITE: "lax" (for SPA cross-site scenarios)
#
# ── CSRF Cookie secure Setting ───────────────────────────────────────────────
# CSRF cookie secure flag (default: true - HTTPS only)
# Set CSRF_SECURE=false for HTTP development (NOT recommended for production)
# CSRF_SECURE: "true" (HTTPS only - default)
# CSRF_SECURE: "false" (HTTP allowed - development only)
#
# ── CSRF Cookie Name ─────────────────────────────────────────────────────────
# CSRF cookie name (default: bt_csrf_token)
# Use CSRF_COOKIE_NAME to customize for multi-app deployments
# CSRF_COOKIE_NAME: "bt_csrf_token" (default)
2026-05-03 19:51:57 -05:00
# ── Data paths (used by both Docker and direct deployments) ───────────────────
# Docker: these are set in the Dockerfile; override here only if needed.
# Direct: set these to absolute paths on the server.
#
# DB_PATH=/opt/bill-tracker/data/db/bills.db
# BACKUP_PATH=/opt/bill-tracker/data/backups
2026-05-31 15:52:50 -05:00
# ── Encryption key ────────────────────────────────────────────────────────────
# AES-256-GCM key used to encrypt secrets at rest (SimpleFIN tokens, SMTP passwords).
# Must be at least 32 bytes. Any printable string works; a random hex string is best.
#
# Generate one with: node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"
#
# If not set, Bill Tracker auto-generates a key and stores it in the database
# next to the encrypted data — anyone with database read access can decrypt.
# Set this variable in production to keep the key separate from the data.
#
# TOKEN_ENCRYPTION_KEY=replace-with-a-long-random-string-at-least-32-chars
# WebAuthn / passkeys Relying Party ID. REQUIRED for passkeys to work behind a
# real domain: credentials are cryptographically bound to this hostname, so the
# "localhost" default only works in local dev. Use the bare hostname users sign
# in on (no scheme, no port) — e.g. bills.example.com. Changing it later
# invalidates already-registered keys.
#
# WEBAUTHN_RP_ID=bills.example.com
fix: four review-confirmed regressions in auth + OIDC flows All found by the multi-angle /code-review over the branch and verified against the installed libraries: - 401 discriminator: the session-expiry redirect keyed off a path prefix (!/auth/*) and falsely logged users out on /profile/change-password with a wrong current password. requireAuth's no-session 401 now carries the distinct AUTH_REQUIRED code — the only signal api.ts dispatches auth:expired on; wrong-credential 401s keep AUTH_ERROR on any path. Test updated to pin the code-based contract on both directions. - OIDC RFC 9207: exchangeAndVerifyTokens rebuilt the callback URL with only code+state, dropping the iss parameter openid-client v6 validates when the provider advertises support (authentik does) — every OIDC login would fail post-upgrade. The full callback query is now forwarded. - OIDC http issuers: v6 enforces HTTPS on discovery/endpoints (v5 didn't) — breaking internal http:// providers on Docker networks. OIDC_ALLOW_INSECURE_HTTP=true opts back in (documented in .env.example). - 2FA downgrade: authService's webauthn fallback caught ANY challenge error and silently downgraded to password-only login; now only the stale-flag 'No registered WebAuthn credentials' case falls through, everything else rethrows. - Burned-challenge retry: the server consumes the single-use 2FA challenge before verifying (anti-replay), so after a server rejection a retry can only ever return 'Challenge expired'. LoginPage now resets to sign-in on server failure (WebAuthn AND the pre-existing TOTP trap); a browser-prompt cancel keeps retry (token still live). Also lazy-loads @simplewebauthn/browser out of the entry bundle, matching ProfilePage. Server 252/252, client 52/52, OIDC smoke 44/44, probe 33/33, e2e 27. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 22:57:07 -05:00
# openid-client v6 requires HTTPS for the OIDC issuer and all discovered
# endpoints. If your identity provider is reached over an internal http://
# address (e.g. http://authentik:9000 on a Docker network), opt back in:
#
# OIDC_ALLOW_INSECURE_HTTP=true
# ── Bank Sync (SimpleFIN) ─────────────────────────────────────────────────────
# Enable/disable bank sync from the Admin panel. Users connect their own
# SimpleFIN Bridge from the Data page. No environment config required.
2026-05-03 19:51:57 -05:00
# ── First-run admin account ────────────────────────────────────────────────────
# Set BOTH on first start to create the admin account automatically.
# Remove or comment out after the server has started once — they are not
# needed again. Open the web UI afterward to create your first user account.
#
# INIT_ADMIN_USER=admin
# INIT_ADMIN_PASS=changeme123