// Create (or update) a dashboard user directly in the SQLite database. // Run the migrations first (npm run db:migrate), then: // npm run create-admin -- --email you@example.com --password "secret" --name "Ime" --role admin // Values can also come from ADMIN_EMAIL / ADMIN_PASSWORD / ADMIN_NAME / ADMIN_ROLE env vars. import Database from 'better-sqlite3'; import { hash } from '@node-rs/argon2'; import { randomUUID } from 'node:crypto'; function arg(name) { const i = process.argv.indexOf(`--${name}`); return i !== -1 ? process.argv[i + 1] : undefined; } const email = (arg('email') ?? process.env.ADMIN_EMAIL ?? '').trim().toLowerCase(); const password = arg('password') ?? process.env.ADMIN_PASSWORD ?? ''; const name = arg('name') ?? process.env.ADMIN_NAME ?? 'Admin'; const role = arg('role') ?? process.env.ADMIN_ROLE ?? 'admin'; const dbPath = process.env.DATABASE_PATH ?? './data/app.db'; if (!email || !password) { console.error( 'Usage: npm run create-admin -- --email you@example.com --password "secret" [--name "Ime"] [--role admin|editor]' ); process.exit(1); } if (role !== 'admin' && role !== 'editor') { console.error('role must be "admin" or "editor"'); process.exit(1); } const db = new Database(dbPath); const hasUsersTable = db .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='users'") .get(); if (!hasUsersTable) { console.error('No "users" table found. Run "npm run db:migrate" first.'); process.exit(1); } const passwordHash = await hash(password); const existing = db.prepare('SELECT id FROM users WHERE email = ?').get(email); if (existing) { db.prepare('UPDATE users SET password_hash = ?, name = ?, role = ? WHERE email = ?').run( passwordHash, name, role, email ); console.log(`Updated existing user ${email} (role: ${role}).`); } else { db.prepare( 'INSERT INTO users (id, email, password_hash, name, role, created_at) VALUES (?, ?, ?, ?, ?, ?)' ).run(randomUUID(), email, passwordHash, name, role, Date.now()); console.log(`Created user ${email} (role: ${role}).`); }