import 'dotenv/config' import { pool } from '~/data/db' import { auth, minPasswordLength } from '~/lib/auth' type Outcome = 'created' | 'updated' function readEnv(name: string): string { const value = process.env[name]?.trim() if (!value) { throw new Error(`${name} fehlt. Aufruf: ${name}=... pnpm admin:create`) } return value } export async function createAdmin(email: string, password: string, name: string): Promise { if (password.length < minPasswordLength) { throw new Error(`ADMIN_PASSWORD ist zu kurz. Es braucht mindestens ${minPasswordLength} Zeichen.`) } const context = await auth.$context const hashed = await context.password.hash(password) const existing = await context.internalAdapter.findUserByEmail(email, { includeAccounts: true }) if (!existing) { const user = await context.internalAdapter.createUser({ email, name, emailVerified: true, isAdmin: true }) await context.internalAdapter.createAccount({ userId: user.id, providerId: 'credential', accountId: user.id, password: hashed, }) return 'created' } const credential = existing.accounts.find(account => account.providerId === 'credential') if (credential) { await context.internalAdapter.updatePassword(existing.user.id, hashed) } else { await context.internalAdapter.createAccount({ userId: existing.user.id, providerId: 'credential', accountId: existing.user.id, password: hashed, }) } await context.internalAdapter.updateUser(existing.user.id, { isAdmin: true }) return 'updated' } async function main(): Promise { const email = readEnv('ADMIN_EMAIL') const password = readEnv('ADMIN_PASSWORD') const name = process.env.ADMIN_NAME?.trim() || email.split('@')[0] || email const outcome = await createAdmin(email, password, name) if (outcome === 'created') { console.log(`Admin angelegt: ${email}. Anmeldung ab sofort unter /login möglich.`) } else { console.log(`Admin aktualisiert: ${email}. Passwort neu gesetzt, Verwaltungsrecht bestätigt.`) } } main() .catch((error: unknown) => { console.error(error instanceof Error ? error.message : error) process.exitCode = 1 }) .finally(() => pool.end())