Phase 12: Initial Setup Wizard #22

Merged
luckberg merged 76 commits from gsd/phase-12-initial-setup-wizard into main 2026-06-16 19:10:33 -04:00
2 changed files with 42 additions and 1 deletions
Showing only changes of commit 2d6dc14a4c - Show all commits
+2 -1
View File
@@ -13,7 +13,8 @@
"typecheck": "pnpm -r typecheck",
"format": "prettier --write .",
"format:check": "prettier --check .",
"md:lint": "markdownlint-cli2"
"md:lint": "markdownlint-cli2",
"generate-secrets": "node scripts/generate-secrets.mjs"
},
"devDependencies": {
"@eslint/js": "9.39.4",
+40
View File
@@ -0,0 +1,40 @@
/**
* generate-secrets.mjs — FamilySync bootstrap secret generator (SETUP-03 / D-05).
*
* Generates all secrets required for a first-time FamilySync deployment:
* - SESSION_SECRET (AES-256-GCM session signing key, 32 random bytes / 64 hex chars)
* - APP_PASSWORD_ENCRYPTION_KEY (AES-256-GCM encryption key, 32 random bytes / 64 hex chars)
* - VAPID_PUBLIC_KEY (EC P-256 public key, base64url, ~87 chars)
* - VAPID_PRIVATE_KEY (EC P-256 private scalar, base64url, ~43 chars)
*
* Security contract (SC-3):
* - Prints to stdout ONLY — never writes any file, never touches the DB, never calls any API.
* - The operator is responsible for pasting the output into docker-compose.yml and keeping it safe.
* - These values CANNOT be recovered if lost (VAPID key rotation invalidates push subscriptions).
*
* Usage:
* node scripts/generate-secrets.mjs
* # or via pnpm script:
* pnpm generate-secrets
*/
// web-push is a CommonJS module — import via default then destructure.
// Resolve from apps/api/node_modules to avoid a root-level dependency.
import webpush from '../apps/api/node_modules/web-push/src/index.js';
const { generateVAPIDKeys } = webpush;
import { randomBytes } from 'node:crypto';
const sessionSecret = randomBytes(32).toString('hex');
const encKey = randomBytes(32).toString('hex');
const vapid = generateVAPIDKeys();
console.log(`# FamilySync Bootstrap Secrets — generated ${new Date().toISOString()}
# Paste into your docker-compose.yml environment block under the 'api' service.
# Keep this output safe — these values cannot be recovered if lost.
# VAPID key rotation will invalidate all existing push subscriptions.
SESSION_SECRET=${sessionSecret}
APP_PASSWORD_ENCRYPTION_KEY=${encKey}
VAPID_PUBLIC_KEY=${vapid.publicKey}
VAPID_PRIVATE_KEY=${vapid.privateKey}
`);