73 lines
2.4 KiB
JavaScript
73 lines
2.4 KiB
JavaScript
#!/usr/bin/env node
|
|
import crypto from 'node:crypto';
|
|
import readline from 'node:readline/promises';
|
|
import { stdin as input, stdout as output } from 'node:process';
|
|
import { Algorithm as Argon2Algorithm, hashRawSync as argon2HashRawSync } from '@node-rs/argon2';
|
|
import { createDbPool, isDatabaseConfigured } from '../server/db.mjs';
|
|
|
|
const PASSWORD_ALGORITHM_ARGON2ID = 'argon2id';
|
|
const ARGON2_MEMORY = 64 * 1024;
|
|
const ARGON2_PASSES = 3;
|
|
const ARGON2_PARALLELISM = 1;
|
|
const ARGON2_TAG_LENGTH = 32;
|
|
|
|
function createPasswordRecord(password) {
|
|
const salt = crypto.randomBytes(16).toString('hex');
|
|
const passwordHash = argon2HashRawSync(password, {
|
|
salt: Buffer.from(salt, 'hex'),
|
|
parallelism: ARGON2_PARALLELISM,
|
|
outputLen: ARGON2_TAG_LENGTH,
|
|
memoryCost: ARGON2_MEMORY,
|
|
timeCost: ARGON2_PASSES,
|
|
algorithm: Argon2Algorithm.Argon2id,
|
|
}).toString('hex');
|
|
return { salt, passwordHash, passwordAlgorithm: PASSWORD_ALGORITHM_ARGON2ID };
|
|
}
|
|
|
|
if (!isDatabaseConfigured()) {
|
|
console.error('MySQL 未配置,请先设置 DATABASE_URL 或 MYSQL_*');
|
|
process.exit(1);
|
|
}
|
|
|
|
const [usernameArg, passwordArg, confirmArg] = process.argv.slice(2);
|
|
let username = (usernameArg ?? '').trim();
|
|
let password = passwordArg ?? '';
|
|
let confirm = confirmArg ?? '';
|
|
|
|
if (!username || !password || !confirm) {
|
|
const rl = readline.createInterface({ input, output });
|
|
username = username || (await rl.question('admin username [admin]: ')).trim() || 'admin';
|
|
password = password || (await rl.question('admin password: '));
|
|
confirm = confirm || (await rl.question('confirm password: '));
|
|
rl.close();
|
|
} else {
|
|
username = username.trim() || 'admin';
|
|
}
|
|
|
|
if (!password || password !== confirm) {
|
|
console.error('密码为空或两次输入不一致');
|
|
process.exit(1);
|
|
}
|
|
|
|
const pool = createDbPool();
|
|
const [rows] = await pool.execute(
|
|
`SELECT id FROM h5_users WHERE username = ? AND role = 'admin' LIMIT 1`,
|
|
[username],
|
|
);
|
|
if (!rows.length) {
|
|
console.error(`未找到共享主用户表中的 admin 账号: ${username}`);
|
|
await pool.end();
|
|
process.exit(1);
|
|
}
|
|
|
|
const nextPassword = createPasswordRecord(password);
|
|
await pool.execute(
|
|
`UPDATE h5_users
|
|
SET salt = ?, password_hash = ?, password_algorithm = ?, updated_at = ?
|
|
WHERE id = ?`,
|
|
[nextPassword.salt, nextPassword.passwordHash, nextPassword.passwordAlgorithm, Date.now(), rows[0].id],
|
|
);
|
|
|
|
console.log(`admin 账号密码已更新到 h5_users: ${username}`);
|
|
await pool.end();
|