chore: prepare project for server deployment

This commit is contained in:
amb
2026-09-09 17:43:07 +08:00
commit d0bcff2311
83 changed files with 24163 additions and 0 deletions
+57
View File
@@ -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;