feat: 实现修改管理员密码的功能

This commit is contained in:
Baobhan Sith
2025-04-15 11:35:25 +08:00
parent 839b2328a8
commit ffb772546d
13 changed files with 476 additions and 3 deletions
@@ -1,6 +1,7 @@
import { Request, Response } from 'express';
import bcrypt from 'bcrypt';
import { getDb } from '../database';
import sqlite3, { RunResult } from 'sqlite3'; // 导入 RunResult 类型
const db = getDb(); // 获取数据库实例
@@ -80,3 +81,96 @@ export const login = async (req: Request, res: Response): Promise<void> => {
// 其他认证相关函数的占位符 (登出, 管理员设置等)
// export const logout = ...
// export const setupAdmin = ...
/**
* 处理修改密码请求 (PUT /api/v1/auth/password)
*/
export const changePassword = async (req: Request, res: Response): Promise<void> => {
const { currentPassword, newPassword } = req.body;
const userId = req.session.userId; // 从会话中获取用户 ID
// 检查用户是否登录
if (!userId) {
res.status(401).json({ message: '用户未认证,请先登录。' });
return;
}
// 基础输入验证
if (!currentPassword || !newPassword) {
res.status(400).json({ message: '当前密码和新密码不能为空。' });
return;
}
// 可选:添加新密码复杂度要求
if (newPassword.length < 8) {
res.status(400).json({ message: '新密码长度至少需要 8 位。' });
return;
}
if (currentPassword === newPassword) {
res.status(400).json({ message: '新密码不能与当前密码相同。' });
return;
}
try {
// 1. 获取当前用户的哈希密码
const user = await new Promise<User | undefined>((resolve, reject) => {
db.get('SELECT id, hashed_password FROM users WHERE id = ?', [userId], (err, row: User) => {
if (err) {
console.error(`查询用户 ${userId} 时出错:`, err.message);
return reject(new Error('数据库查询失败'));
}
resolve(row);
});
});
if (!user) {
// 理论上不应该发生,因为 userId 来自 session
console.error(`修改密码错误: 未找到 ID 为 ${userId} 的用户。`);
res.status(404).json({ message: '用户不存在。' });
return;
}
// 2. 验证当前密码
const isMatch = await bcrypt.compare(currentPassword, user.hashed_password);
if (!isMatch) {
console.log(`修改密码尝试失败: 当前密码错误 - 用户 ID ${userId}`);
res.status(400).json({ message: '当前密码不正确。' });
return;
}
// 3. 哈希新密码
const saltRounds = 10;
const newHashedPassword = await bcrypt.hash(newPassword, saltRounds);
const now = Math.floor(Date.now() / 1000);
// 4. 更新数据库中的密码
await new Promise<void>((resolveUpdate, rejectUpdate) => {
const stmt = db.prepare(
'UPDATE users SET hashed_password = ?, updated_at = ? WHERE id = ?'
);
// 在回调函数中明确 this 的类型为 RunResult
stmt.run(newHashedPassword, now, userId, function (this: RunResult, err: Error | null) {
if (err) {
console.error(`更新用户 ${userId} 密码时出错:`, err.message);
return rejectUpdate(new Error('更新密码失败'));
}
if (this.changes === 0) {
// 理论上不应该发生
console.error(`修改密码错误: 更新影响行数为 0 - 用户 ID ${userId}`);
return rejectUpdate(new Error('未找到要更新的用户'));
}
console.log(`用户 ${userId} 密码已成功修改。`);
resolveUpdate();
});
stmt.finalize();
});
// 5. 返回成功响应
res.status(200).json({ message: '密码已成功修改。' });
} catch (error) {
console.error(`修改用户 ${userId} 密码时发生内部错误:`, error);
res.status(500).json({ message: '修改密码过程中发生内部服务器错误。' });
}
};