/** * Legt ein Konto fuer den Adminbereich an. Es gibt keine Selbstregistrierung * und kein Standardpasswort. * * pnpm admin:create --email admin@example.org --name "Vorname Nachname" * * Passwort: aus ADMIN_PASSWORD (mind. 12 Zeichen) oder zufaellig erzeugt und * EINMAL ausgegeben. Nach der ersten Anmeldung erzwingt der Adminbereich die * Einrichtung der Zwei-Faktor-Anmeldung. */ import { randomBytes } from "node:crypto"; import { parseArgs } from "node:util"; import { createProvisioningAuth } from "@/lib/auth"; import { getDb } from "@/lib/db"; try { process.loadEnvFile(); } catch { // Umgebung kommt aus dem Container. } const { values } = parseArgs({ options: { email: { type: "string" }, name: { type: "string" } } }); const email = values.email?.trim().toLowerCase(); const name = values.name?.trim(); if (!email || !/^\S+@\S+\.\S+$/.test(email) || !name) { console.error('Aufruf: pnpm admin:create --email --name ""'); process.exit(1); } const provided = process.env.ADMIN_PASSWORD; if (provided !== undefined && provided.length < 12) { console.error("ADMIN_PASSWORD muss mindestens 12 Zeichen haben."); process.exit(1); } const password = provided ?? randomBytes(18).toString("base64url"); const db = getDb(); try { if (await db.user.findUnique({ where: { email } })) { console.error("Für diese E-Mail-Adresse existiert bereits ein Konto."); process.exitCode = 1; } else { // Offizieller Weg ueber Better Auth: Passwortregeln und Leak-Pruefung // greifen dabei automatisch. const result = await createProvisioningAuth().api.signUpEmail({ body: { email, name, password } }); await db.user.update({ where: { id: result.user.id }, data: { emailVerified: true } }); await db.auditLog.create({ data: { actorType: "SYSTEM", action: "admin.created", entityType: "User", entityId: result.user.id } }); console.log(`Konto angelegt: ${email}`); if (!provided) console.log(`Einmaliges Passwort (jetzt sicher ablegen, wird nicht erneut angezeigt): ${password}`); console.log("Bei der ersten Anmeldung wird die Zwei-Faktor-Anmeldung eingerichtet."); } } finally { await db.$disconnect(); }