76 lines
3.0 KiB
JavaScript
76 lines
3.0 KiB
JavaScript
// 带外创建/重置【管理员账号】。
|
|
//
|
|
// 为什么需要它:超管资格 = .env 的 SUPER_ADMIN_EMAILS 白名单里的邮箱,谁注册了谁就是超管。
|
|
// 但自助注册【已被安全策略禁止用白名单邮箱】(否则管理员邮箱尚无账号时,任何人都能抢注→拿到全部后台
|
|
// 权限:改大师/生成深伪/结算分成/读 PII)。所以管理员账号只能【带外预置】——就是这个脚本。
|
|
//
|
|
// 用法(在服务器上,后端目录内):
|
|
// ADMIN_EMAIL=you@example.com ADMIN_PASSWORD='你的强密码' node scripts/create-admin.js
|
|
//
|
|
// 幂等:账号已存在 → 重置密码;不存在 → 新建。密码只用 scrypt 存 hash(与 routes/auth.js 完全一致),
|
|
// 脚本【绝不打印密码】。
|
|
import 'dotenv/config';
|
|
import crypto from 'node:crypto';
|
|
import { connectDb, getDb, closeDb } from '../src/db.js';
|
|
|
|
// 与 routes/auth.js 的 hash() 完全一致,否则建出来的号登不进去。
|
|
function hash(password, salt) {
|
|
return crypto.scryptSync(password, salt, 64).toString('hex');
|
|
}
|
|
|
|
async function run() {
|
|
const email = String(process.env.ADMIN_EMAIL || '').trim().toLowerCase();
|
|
const password = String(process.env.ADMIN_PASSWORD || '');
|
|
|
|
if (!email || !email.includes('@')) {
|
|
console.error('❌ 需要 ADMIN_EMAIL(合法邮箱)');
|
|
process.exit(1);
|
|
}
|
|
if (password.length < 8) {
|
|
console.error('❌ 需要 ADMIN_PASSWORD,且至少 8 位(管理员账号别用弱密码)');
|
|
process.exit(1);
|
|
}
|
|
|
|
await connectDb();
|
|
const db = getDb();
|
|
const now = new Date();
|
|
const salt = crypto.randomBytes(16).toString('hex');
|
|
const existing = await db.collection('users').findOne({ email });
|
|
|
|
if (existing) {
|
|
await db.collection('users').updateOne(
|
|
{ _id: existing._id },
|
|
{ $set: { salt, passwordHash: hash(password, salt), updatedAt: now } }
|
|
);
|
|
console.log(`✅ 账号已存在 → 已重置密码:${email}`);
|
|
} else {
|
|
const name = email.split('@')[0];
|
|
await db.collection('users').insertOne({
|
|
email,
|
|
name,
|
|
nickname: name,
|
|
salt,
|
|
passwordHash: hash(password, salt),
|
|
entitlements: [],
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
});
|
|
console.log(`✅ 已新建账号:${email}`);
|
|
}
|
|
|
|
// 提醒:账号有了还不等于是超管——还要这个邮箱在 .env 的 SUPER_ADMIN_EMAILS 里。
|
|
const whitelist = (process.env.SUPER_ADMIN_EMAILS || '')
|
|
.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
if (whitelist.includes(email)) {
|
|
console.log(`✅ 该邮箱已在 SUPER_ADMIN_EMAILS 白名单里 → 登录后即为超管。`);
|
|
} else {
|
|
console.log(`⚠ 该邮箱【不在】SUPER_ADMIN_EMAILS 白名单里,现在登录只是普通账号。`);
|
|
console.log(` 请把 .env 的 SUPER_ADMIN_EMAILS 设为 ${email} 并重启后端(grant-superadmin 工作流会做这步)。`);
|
|
}
|
|
console.log('(本脚本从不打印密码。请用你设置的密码登录,登录后建议立刻改成只有你知道的强密码。)');
|
|
|
|
await closeDb();
|
|
}
|
|
|
|
run().catch((e) => { console.error(e); process.exit(1); });
|