chore: prepare project for server deployment
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
const crypto = require('crypto');
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
const { getDb } = require('../config/database');
|
||||
|
||||
const sessions = new Map();
|
||||
|
||||
const hashPassword = (password, salt = crypto.randomBytes(16).toString('hex')) => {
|
||||
const hash = crypto.scryptSync(password, salt, 64).toString('hex');
|
||||
return `${salt}:${hash}`;
|
||||
};
|
||||
|
||||
const verifyPassword = (password, stored) => {
|
||||
const [salt, expected] = String(stored || '').split(':');
|
||||
if (!salt || !expected) return false;
|
||||
const actual = crypto.scryptSync(password, salt, 64).toString('hex');
|
||||
return crypto.timingSafeEqual(Buffer.from(actual, 'hex'), Buffer.from(expected, 'hex'));
|
||||
};
|
||||
|
||||
class AdminAuthService {
|
||||
static login(username, password) {
|
||||
const user = getDb().prepare('SELECT * FROM admin_users WHERE username = ?').get(username);
|
||||
if (!user || !verifyPassword(password, user.password_hash)) {
|
||||
throw new Error('用户名或密码错误');
|
||||
}
|
||||
const token = crypto.randomBytes(32).toString('hex');
|
||||
sessions.set(token, { userId: user.user_id, username: user.username, expiresAt: Date.now() + 8 * 60 * 60 * 1000 });
|
||||
return { token, username: user.username, expiresIn: 8 * 60 * 60 };
|
||||
}
|
||||
|
||||
static verify(token) {
|
||||
const session = sessions.get(token);
|
||||
if (!session || session.expiresAt < Date.now()) {
|
||||
if (token) sessions.delete(token);
|
||||
return null;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
static changePassword(username, currentPassword, newPassword) {
|
||||
if (!newPassword || newPassword.length < 8) throw new Error('新密码至少需要8位');
|
||||
const db = getDb();
|
||||
const user = db.prepare('SELECT * FROM admin_users WHERE username = ?').get(username);
|
||||
if (!user || !verifyPassword(currentPassword, user.password_hash)) throw new Error('当前密码错误');
|
||||
db.prepare('UPDATE admin_users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE username = ?')
|
||||
.run(hashPassword(newPassword), username);
|
||||
for (const [token, session] of sessions.entries()) {
|
||||
if (session.username === username) sessions.delete(token);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
static logout(token) {
|
||||
sessions.delete(token);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AdminAuthService;
|
||||
Reference in New Issue
Block a user