feat(19-01): add local_credentials schema, 0003 migration, generate-secrets LOCAL_SESSION_SECRET, .dockerignore D-15

- schema.ts: export localCredentials = mysqlTable('local_credentials', {...})
  - user_id FK->users(cascade), username, password_hash, createdAt, updatedAt
  - UNIQUE(user_id), UNIQUE(username), INDEX(user_id)
- 0003_warm_deathstrike.sql: purely additive CREATE TABLE (no ALTER/DROP/TRUNCATE on existing tables)
  - Applied to dev DB: pnpm --filter @familysync/api db:migrate exits 0
- test/setup.ts: add localCredentials to afterEach delete cleanup (FK-safe ordering)
- generate-secrets.mjs: emit LOCAL_SESSION_SECRET (base64 32-byte, >=32 chars, D-05)
- .dockerignore: add apps/api/scripts/ exclusion (D-15/IMG-02) — entire break-glass dir excluded
This commit is contained in:
Lucas Berger
2026-06-17 16:17:04 -04:00
parent 7d61148415
commit 96f0991605
7 changed files with 1218 additions and 2 deletions
+5
View File
@@ -27,6 +27,9 @@ import { randomBytes, createECDH } from 'node:crypto';
const sessionSecret = randomBytes(32).toString('hex');
const encKey = randomBytes(32).toString('hex');
// Phase 19 (D-05): LOCAL_SESSION_SECRET signs the local-auth JWT session cookie.
// Must be >= 32 chars. 32 random bytes encoded as base64 = 44 chars (safe, distinct from hex keys).
const localSessionSecret = randomBytes(32).toString('base64');
// VAPID key generation (P-256 / prime256v1 — same curve as web-push)
const ecdhCurve = createECDH('prime256v1');
@@ -55,4 +58,6 @@ SESSION_SECRET=${sessionSecret}
APP_PASSWORD_ENCRYPTION_KEY=${encKey}
VAPID_PUBLIC_KEY=${vapid.publicKey}
VAPID_PRIVATE_KEY=${vapid.privateKey}
# Phase 19 (D-05): Signs local-auth JWT session cookies. Required when not using DEV_AUTH_BYPASS.
LOCAL_SESSION_SECRET=${localSessionSecret}
`);