feat: implement one-time admin token generation and upgrade process

This commit is contained in:
averel10
2026-03-13 08:11:40 +01:00
parent b9f6836f1a
commit cda21a60ec
6 changed files with 235 additions and 5 deletions

View File

@@ -1,9 +1,15 @@
import { migrate } from 'drizzle-orm/better-sqlite3/migrator';
import db from '@/lib/db';
import { join } from 'path';
import { eq } from 'drizzle-orm';
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
// Import nodejs-only modules dynamically
const { migrate } = await import('drizzle-orm/better-sqlite3/migrator');
const { join } = await import('path');
const { randomBytes } = await import('crypto');
const { count } = await import('drizzle-orm');
const db = (await import('@/lib/db')).default;
const { user } = await import('@/lib/model/auth-schema');
try {
console.log('Running database migrations...');
@@ -13,8 +19,30 @@ export async function register() {
migrate(db, { migrationsFolder });
console.log('✓ Database migrations completed successfully');
// Check if any admin exists
const adminCount = await db.select({ count: count() }).from(user).where(eq(user.admin, true));
const hasAdmin = adminCount.length > 0 && adminCount[0].count > 0;
// If no admin exists, generate a one-time token
if (!hasAdmin) {
const token = randomBytes(32).toString('hex');
process.env.ADMIN_SIGNUP_TOKEN = token;
console.log('\n╔════════════════════════════════════════════════════════════════╗');
console.log('║ ADMIN TOKEN GENERATED ║');
console.log('╠════════════════════════════════════════════════════════════════╣');
console.log(`║ Token: ${token}`);
console.log('║ ║');
console.log('║ This token can be used ONCE to upgrade a user to admin. ║');
console.log('║ After the first use, it will become invalid. ║');
console.log('║ ║');
console.log('║ 1. Sign in with your account ║');
console.log('║ 2. Try to access /admin ║');
console.log('║ 3. Enter this token when prompted ║');
console.log('╚════════════════════════════════════════════════════════════════╝\n');
}
} catch (error) {
console.error('Failed to run database migrations:', error);
console.error('Failed to initialize app:', error);
process.exit(1);
}
}