import { fileURLToPath } from "node:url" import { getPasswordHash } from "@/lib/security" import prisma from "../src/lib/prisma" type BootstrapAdminInput = { username: string email: string name: string password: string } function getBootstrapAdminInput(): BootstrapAdminInput { const isProduction = process.env.NODE_ENV === "production" const username = process.env.ADMIN_USERNAME ?? "admin" const email = process.env.ADMIN_EMAIL ?? "admin@localhost" const name = process.env.ADMIN_NAME ?? "Administrator" const password = process.env.ADMIN_PASSWORD if (isProduction && !password) { throw new Error("ADMIN_PASSWORD is required to bootstrap an admin user") } return { username, email, name, password: password ?? "admin", } } export async function bootstrapAdmin(client: typeof prisma) { const enabled = process.env.ADMIN_BOOTSTRAP_ENABLED !== "false" const existingAdmin = await client.user.findFirst({ where: { role: "ADMIN", isActive: true, }, select: { id: true, }, }) if (existingAdmin || !enabled) return const admin = getBootstrapAdminInput() await client.user.upsert({ where: { email: admin.email, }, update: { role: "ADMIN", isActive: true, }, create: { name: admin.name, username: admin.username, email: admin.email, role: "ADMIN", password: await getPasswordHash(admin.password), isActive: true, }, }) } async function main() { try { await bootstrapAdmin(prisma) } finally { await prisma.$disconnect() } } if (process.argv[1] === fileURLToPath(import.meta.url)) { main().catch((error) => { console.error(error) process.exit(1) }) }