|
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(); |