// Seed the first admin user (run once at install). // // ADMIN_USER=admin ADMIN_PASS='strong-pass' \ // node --env-file-if-exists=.env apps/server/scripts/seed-admin.mjs // // Or interactively (prompts for a hidden password): // node --env-file-if-exists=.env apps/server/scripts/seed-admin.mjs // // Idempotent-ish: refuses to overwrite an existing user unless FORCE=1. import { randomUUID } from "node:crypto"; import { createInterface } from "node:readline/promises"; import { stdin, stdout } from "node:process"; import { createRequire } from "node:module"; const require = createRequire(import.meta.url); const bcrypt = require("bcrypt"); const { createDb, users, eq } = require("@parking/db"); const username = process.env.ADMIN_USER ?? process.argv[2]; let password = process.env.ADMIN_PASS; if (!username) { console.error("usage: ADMIN_USER=.. ADMIN_PASS=.. seed-admin.mjs (or pass a username arg)"); process.exit(1); } if (!password) { const rl = createInterface({ input: stdin, output: stdout }); password = (await rl.question(`Password for "${username}": `)).trim(); rl.close(); } if (!password || password.length < 8) { console.error("password must be at least 8 characters"); process.exit(1); } const db = createDb(); const existing = await db.select().from(users).where(eq(users.username, username)).get(); if (existing && process.env.FORCE !== "1") { console.error(`user "${username}" already exists (set FORCE=1 to reset the password)`); process.exit(1); } const passwordHash = await bcrypt.hash(password, 12); if (existing) { await db.update(users).set({ passwordHash, role: "admin" }).where(eq(users.id, existing.id)); console.log(`reset password for admin "${username}"`); } else { await db.insert(users).values({ id: randomUUID(), username, passwordHash, role: "admin", }); console.log(`created admin "${username}"`); } process.exit(0);