feat: bootstrap admin user on first run
When the user table is empty, init creates an admin via better-auth's admin.createUser API. ADMIN_USERNAME / ADMIN_EMAIL / ADMIN_PASSWORD configure it; password is generated and logged once if not provided. Also silence the cosmetic async_hooks warning by marking it external. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+31
-1
@@ -4,10 +4,12 @@ import { building, dev } from '$app/environment';
|
||||
import { getAuth } from '$lib/auth/server';
|
||||
import { getTextDirection } from '$lib/paraglide/runtime';
|
||||
import { paraglideMiddleware } from '$lib/paraglide/server';
|
||||
import { db } from '$lib/server/db';
|
||||
import { getConfig } from '$lib/server/config';
|
||||
import { svelteKitHandler } from 'better-auth/svelte-kit';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
export const init: ServerInit = () => {
|
||||
export const init: ServerInit = async () => {
|
||||
const env = process.env;
|
||||
const errors: string[] = [];
|
||||
|
||||
@@ -20,6 +22,34 @@ export const init: ServerInit = () => {
|
||||
|
||||
if (errors.length)
|
||||
throw new Error(`Invalid environment:\n - ${errors.join('\n - ')}`);
|
||||
|
||||
// Bootstrap an admin if the user table is empty.
|
||||
const userCount = db.$client.prepare('SELECT COUNT(*) AS c FROM user').get() as { c: number };
|
||||
if (userCount.c > 0) return;
|
||||
|
||||
const username = env.ADMIN_USERNAME?.trim() || 'admin';
|
||||
const email = env.ADMIN_EMAIL?.trim() || `${username}@example.com`;
|
||||
const provided = env.ADMIN_PASSWORD?.trim();
|
||||
const password = provided || randomBytes(18).toString('base64url');
|
||||
|
||||
await getAuth().api.createUser({
|
||||
body: {
|
||||
email,
|
||||
name: username,
|
||||
password,
|
||||
role: 'admin',
|
||||
data: { username, displayUsername: username, emailVerified: true }
|
||||
}
|
||||
});
|
||||
|
||||
const line = '━'.repeat(64);
|
||||
if (provided) {
|
||||
console.log(`${line}\nBootstrap admin "${username}" created (ADMIN_PASSWORD).\n${line}`);
|
||||
} else {
|
||||
console.log(
|
||||
`${line}\nBootstrap admin created — sign in with these and rotate immediately:\n username: ${username}\n password: ${password}\nSet ADMIN_PASSWORD env to pick your own.\n${line}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBetterAuth: Handle = async ({ event, resolve }) => {
|
||||
|
||||
+4
-1
@@ -5,11 +5,14 @@ import adapter from 'svelte-adapter-bun';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rollupOptions: { external: ['async_hooks'] }
|
||||
},
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
sveltekit({
|
||||
adapter: adapter({
|
||||
precompress:true
|
||||
precompress: true
|
||||
}),
|
||||
compilerOptions: {
|
||||
experimental: { async: true },
|
||||
|
||||
Reference in New Issue
Block a user