91 lines
2.7 KiB
JavaScript
91 lines
2.7 KiB
JavaScript
import { createClient } from '@libsql/client';
|
|
import { hashPassword } from 'better-auth/crypto';
|
|
import { readFileSync } from 'node:fs';
|
|
import { randomUUID } from 'node:crypto';
|
|
|
|
function readDotEnv() {
|
|
try {
|
|
const entries = readFileSync('.env', 'utf8')
|
|
.split('\n')
|
|
.map((line) => line.trim())
|
|
.filter((line) => line && !line.startsWith('#'))
|
|
.map((line) => {
|
|
const index = line.indexOf('=');
|
|
const key = line.slice(0, index);
|
|
const value = line.slice(index + 1).replace(/^"|"$/g, '');
|
|
return [key, value];
|
|
});
|
|
|
|
for (const [key, value] of entries) {
|
|
process.env[key] ??= value;
|
|
}
|
|
} catch {
|
|
// .env is optional in deployed or scripted environments.
|
|
}
|
|
}
|
|
|
|
readDotEnv();
|
|
|
|
const databaseUrl = process.env.DATABASE_URL;
|
|
const email = process.env.ADMIN_EMAIL?.trim().toLowerCase();
|
|
const password = process.env.ADMIN_PASSWORD;
|
|
const name = process.env.ADMIN_NAME?.trim() || 'Administrator';
|
|
const overwrite = process.env.ADMIN_OVERWRITE === '1';
|
|
|
|
if (!databaseUrl) {
|
|
console.error('DATABASE_URL is required.');
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!email || !password) {
|
|
console.error('ADMIN_EMAIL and ADMIN_PASSWORD are required.');
|
|
console.error('Example: ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=change-me pnpm admin:create');
|
|
process.exit(1);
|
|
}
|
|
|
|
const client = createClient({ url: databaseUrl });
|
|
const now = Date.now();
|
|
const existing = await client.execute({
|
|
sql: 'select id from user where email = ? limit 1',
|
|
args: [email]
|
|
});
|
|
|
|
if (existing.rows.length > 0 && !overwrite) {
|
|
console.error(`A user with email ${email} already exists. Set ADMIN_OVERWRITE=1 to update the password.`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const userId = existing.rows[0]?.id?.toString() ?? randomUUID();
|
|
const passwordHash = await hashPassword(password);
|
|
|
|
if (existing.rows.length === 0) {
|
|
await client.execute({
|
|
sql: 'insert into user (id, name, email, email_verified, image, created_at, updated_at) values (?, ?, ?, ?, ?, ?, ?)',
|
|
args: [userId, name, email, 1, null, now, now]
|
|
});
|
|
} else {
|
|
await client.execute({
|
|
sql: 'update user set name = ?, email_verified = ?, updated_at = ? where id = ?',
|
|
args: [name, 1, now, userId]
|
|
});
|
|
}
|
|
|
|
const account = await client.execute({
|
|
sql: 'select id from account where user_id = ? and provider_id = ? limit 1',
|
|
args: [userId, 'credential']
|
|
});
|
|
|
|
if (account.rows.length === 0) {
|
|
await client.execute({
|
|
sql: 'insert into account (id, account_id, provider_id, user_id, password, created_at, updated_at) values (?, ?, ?, ?, ?, ?, ?)',
|
|
args: [randomUUID(), userId, 'credential', userId, passwordHash, now, now]
|
|
});
|
|
} else {
|
|
await client.execute({
|
|
sql: 'update account set password = ?, updated_at = ? where id = ?',
|
|
args: [passwordHash, now, account.rows[0].id]
|
|
});
|
|
}
|
|
|
|
console.log(`Admin user ready: ${email}`);
|