43 lines
1.4 KiB
JavaScript
43 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
||
'use strict';
|
||
|
||
/**
|
||
* 开发运维脚本:重置用户密码(argon2id)
|
||
* 用法:node scripts/set-password.js <username> <newPassword>
|
||
* 说明:绕过 API 直接写库,仅限开发/运维;生产操作须记入变更单。
|
||
*/
|
||
const path = require('path');
|
||
require('dotenv').config({ path: path.join(__dirname, '..', '.env') });
|
||
|
||
const mysql = require('mysql2/promise');
|
||
const argon2 = require('argon2');
|
||
|
||
async function main() {
|
||
const [username, password] = process.argv.slice(2);
|
||
if (!username || !password) {
|
||
console.error('用法: node scripts/set-password.js <username> <newPassword>');
|
||
process.exit(1);
|
||
}
|
||
if (password.length < 10 || !/[a-z]/.test(password) || !/[A-Z]/.test(password) || !/\d/.test(password)) {
|
||
console.error('密码强度不足:至少 10 位,须含大小写字母与数字');
|
||
process.exit(1);
|
||
}
|
||
const conn = await mysql.createConnection(process.env.DATABASE_URL);
|
||
const hash = await argon2.hash(password, { type: argon2.argon2id });
|
||
const [res] = await conn.execute(
|
||
'UPDATE users SET password_hash = ?, pwd_changed_at = NOW(), failed_attempts = 0, locked_until = NULL WHERE username = ?',
|
||
[hash, username],
|
||
);
|
||
if (res.affectedRows === 0) {
|
||
console.error(`用户不存在: ${username}`);
|
||
process.exit(1);
|
||
}
|
||
console.log(`密码已重置: ${username}`);
|
||
await conn.end();
|
||
}
|
||
|
||
main().catch((e) => {
|
||
console.error(e.message);
|
||
process.exit(1);
|
||
});
|