| 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'; |
|
|
| |
| const dataDir = path.dirname(ADMIN_FILE); |
| if (!fs.existsSync(dataDir)) { |
| fs.mkdirSync(dataDir, { recursive: true }); |
| } |
|
|
| |
| 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); |
| } |
|
|
| |
| generateToken(username) { |
| return jwt.sign({ username }, JWT_SECRET, { expiresIn: '24h' }); |
| } |
|
|
| |
| 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(); |