67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
import bcrypt from 'bcrypt';
|
||
import pool from './src/config/database';
|
||
|
||
/**
|
||
* 密码迁移脚本
|
||
* 将数据库中所有明文密码更新为bcrypt哈希密码
|
||
* 仅更新密码不是bcrypt哈希格式(以$2b$开头)的用户
|
||
*/
|
||
async function migratePasswords() {
|
||
try {
|
||
console.log('开始密码迁移...');
|
||
|
||
// 获取所有用户
|
||
const [users] = await pool.query<any[]>(
|
||
'SELECT user_id, username, password FROM user'
|
||
);
|
||
|
||
console.log(`共找到 ${users.length} 个用户`);
|
||
|
||
let migratedCount = 0;
|
||
let skippedCount = 0;
|
||
let errorCount = 0;
|
||
|
||
for (const user of users) {
|
||
const { user_id, username, password } = user;
|
||
|
||
// 检查密码是否已经是bcrypt哈希格式
|
||
if (password.startsWith('$2b$') || password.startsWith('$2a$') || password.startsWith('$2y$')) {
|
||
console.log(`✓ 用户 ${username} (ID: ${user_id}) 密码已经是哈希格式,跳过`);
|
||
skippedCount++;
|
||
continue;
|
||
}
|
||
|
||
try {
|
||
// 生成bcrypt哈希(使用默认盐轮数10)
|
||
const hashedPassword = await bcrypt.hash(password, 10);
|
||
|
||
// 更新数据库
|
||
await pool.query(
|
||
'UPDATE user SET password = ? WHERE user_id = ?',
|
||
[hashedPassword, user_id]
|
||
);
|
||
|
||
console.log(`✓ 用户 ${username} (ID: ${user_id}) 密码已更新为哈希格式`);
|
||
migratedCount++;
|
||
} catch (err) {
|
||
console.error(`✗ 用户 ${username} (ID: ${user_id}) 密码更新失败:`, err);
|
||
errorCount++;
|
||
}
|
||
}
|
||
|
||
console.log('\n迁移完成!');
|
||
console.log(`成功迁移: ${migratedCount} 个用户`);
|
||
console.log(`跳过(已是哈希): ${skippedCount} 个用户`);
|
||
console.log(`失败: ${errorCount} 个用户`);
|
||
|
||
// 关闭连接池
|
||
await pool.end();
|
||
process.exit(0);
|
||
} catch (error) {
|
||
console.error('密码迁移失败:', error);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// 运行迁移
|
||
migratePasswords(); |