Files
clearity/scripts/create-admin.mjs
T

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}`);