cursor / src /models /admin.js
0412Xu's picture
Upload 20 files
dc70e52 verified
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
// 管理员数据文件路径
const ADMIN_FILE = path.join(__dirname, '../../data/admin.json');
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
// 确保data目录存在
const dataDir = path.dirname(ADMIN_FILE);
if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir, { recursive: true });
}
// 确保admin.json文件存在
if (!fs.existsSync(ADMIN_FILE)) {
fs.writeFileSync(ADMIN_FILE, JSON.stringify({ admin: null }), 'utf8');
}
class Admin {
constructor() {
this.loadAdmin();
}
// 加载管理员数据
loadAdmin() {
try {
const data = fs.readFileSync(ADMIN_FILE, 'utf8');
this.admin = JSON.parse(data).admin;
} catch (error) {
console.error('加载管理员数据失败:', error);
this.admin = null;
}
}
// 保存管理员数据
saveAdmin() {
try {
fs.writeFileSync(ADMIN_FILE, JSON.stringify({ admin: this.admin }), 'utf8');
} catch (error) {
console.error('保存管理员数据失败:', error);
throw error;
}
}
// 检查是否已有管理员
hasAdmin() {
return !!this.admin;
}
// 注册管理员
register(username, password) {
if (this.hasAdmin()) {
throw new Error('已存在管理员账号');
}
// 生成盐值
const salt = crypto.randomBytes(16).toString('hex');
// 使用盐值加密密码
const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
this.admin = {
username,
salt,
hash
};
this.saveAdmin();
return this.generateToken(username);
}
// 验证密码
verifyPassword(password, salt, hash) {
const testHash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
return testHash === hash;
}
// 登录验证
login(username, password) {
if (!this.admin || username !== this.admin.username) {
throw new Error('用户名或密码错误');
}
if (!this.verifyPassword(password, this.admin.salt, this.admin.hash)) {
throw new Error('用户名或密码错误');
}
return this.generateToken(username);
}
// 生成JWT token
generateToken(username) {
return jwt.sign({ username }, JWT_SECRET, { expiresIn: '24h' });
}
// 验证JWT token
verifyToken(token) {
try {
const decoded = jwt.verify(token, JWT_SECRET);
return {
success: true,
username: decoded.username
};
} catch (error) {
return {
success: false,
error: 'Invalid token'
};
}
}
}
module.exports = new Admin();