import { sql } from 'drizzle-orm'; import * as z from 'zod'; import { users } from '~~/drizzle/schema'; import { auth } from '~~/lib/auth'; import { db } from '~~/server/lib/db'; // any fixed number works, it only has to be the same for every request const SETUP_LOCK_ID = 7_261_008; /** * Creates the first account of the instance as its admin. * * Public, because nobody can be signed in yet, and only works while there are * no accounts at all. It does not go through sign up, so it also works when * registration is turned off. */ export default defineEventHandler(async (event) => { const result = await readValidatedBody(event, (body) => z .object({ name: z.string().trim().min(1).max(128), email: z.email(), password: z.string().min(8).max(128), }) .safeParse(body), ); if (!result.success) { throw createError({ statusCode: 400, message: result.error.issues[0]!.message, data: { code: 'INVALID_BODY', }, }); } const { name, email, password } = result.data; let alreadyDone = false; try { await db.transaction(async (tx) => { // two people submitting the form at the same moment wait here, and // the second one then finds the first one's account await tx.execute(sql`select pg_advisory_xact_lock(${SETUP_LOCK_ID})`); const existing = await tx.select({ id: users.id }).from(users).limit(1); if (existing.length > 0) { alreadyDone = true; return; } await auth.api.createUser({ body: { name, email, password, role: 'admin', }, }); }); } catch (error: any) { const code = error?.body?.code as string | undefined; if (code === undefined) { console.error('Failed to create the admin account:', error); } throw createError({ statusCode: code === undefined ? 500 : 400, statusMessage: 'Failed to set up the instance', message: error?.body?.message ?? 'Failed to set up the instance', data: { code: code ?? 'INTERNAL_ERROR', }, }); } if (alreadyDone) { throw createError({ statusCode: 409, statusMessage: 'This instance is already set up', data: { code: 'SETUP_ALREADY_DONE', }, }); } return { ok: true }; });