import express from 'express'; import multer from 'multer'; import archiver from 'archiver'; import { createKey, loadKeys, deleteKey, updateKeyRateLimit, getKeyStats } from './key_manager.js'; import { getRecentLogs, clearLogs, addLog } from './log_manager.js'; import { getSystemStatus, incrementRequestCount, getTodayRequestCount } from './monitor.js'; import { loadAccounts, deleteAccount, toggleAccount, triggerLogin, getAccountStats, addTokenFromCallback, getAccountName, importTokens } from './token_admin.js'; import { createSession, validateSession, destroySession, verifyPassword, adminAuth } from './session.js'; import { loadSettings, saveSettings } from './settings_manager.js'; import tokenManager from '../auth/token_manager.js'; // 配置文件上传 const upload = multer({ dest: 'uploads/' }); const router = express.Router(); // 登录接口(不需要认证) router.post('/login', async (req, res) => { try { const { password } = req.body; if (!password) { return res.status(400).json({ error: '请输入密码' }); } if (verifyPassword(password)) { const token = createSession(); await addLog('info', '管理员登录成功'); res.json({ success: true, token }); } else { await addLog('warn', '管理员登录失败:密码错误'); res.status(401).json({ error: '密码错误' }); } } catch (error) { res.status(500).json({ error: error.message }); } }); // 登出接口 router.post('/logout', (req, res) => { const token = req.headers['x-admin-token']; if (token) { destroySession(token); } res.json({ success: true }); }); // 验证会话接口 router.get('/verify', (req, res) => { const token = req.headers['x-admin-token']; if (validateSession(token)) { res.json({ valid: true }); } else { res.status(401).json({ valid: false }); } }); // 以下所有路由需要认证 router.use(adminAuth); // 生成新密钥 router.post('/keys/generate', async (req, res) => { try { const { name, rateLimit, key } = req.body; const newKey = await createKey(name, rateLimit, key); await addLog('success', `密钥已生成: ${name || '未命名'}`); res.json({ success: true, key: newKey.key, name: newKey.name, rateLimit: newKey.rateLimit }); } catch (error) { await addLog('error', `生成密钥失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 获取所有密钥 router.get('/keys', async (req, res) => { try { const keys = await loadKeys(); // 返回密钥列表(隐藏部分字符) const safeKeys = keys.map(k => ({ ...k, key: k.key.substring(0, 10) + '...' + k.key.substring(k.key.length - 4) })); res.json(keys); // 在管理界面显示完整密钥 } catch (error) { res.status(500).json({ error: error.message }); } }); // 删除密钥 router.delete('/keys/:key', async (req, res) => { try { const { key } = req.params; await deleteKey(key); await addLog('warn', `密钥已删除: ${key.substring(0, 10)}...`); res.json({ success: true }); } catch (error) { await addLog('error', `删除密钥失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 更新密钥频率限制 router.patch('/keys/:key/ratelimit', async (req, res) => { try { const { key } = req.params; const { rateLimit } = req.body; await updateKeyRateLimit(key, rateLimit); await addLog('info', `密钥频率限制已更新: ${key.substring(0, 10)}...`); res.json({ success: true }); } catch (error) { await addLog('error', `更新频率限制失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 获取密钥统计 router.get('/keys/stats', async (req, res) => { try { const stats = await getKeyStats(); res.json(stats); } catch (error) { res.status(500).json({ error: error.message }); } }); // 获取日志 router.get('/logs', async (req, res) => { try { const limit = parseInt(req.query.limit) || 100; const logs = await getRecentLogs(limit); res.json(logs); } catch (error) { res.status(500).json({ error: error.message }); } }); // 清空日志 router.delete('/logs', async (req, res) => { try { await clearLogs(); await addLog('info', '日志已清空'); res.json({ success: true }); } catch (error) { res.status(500).json({ error: error.message }); } }); // 获取系统状态 router.get('/status', async (req, res) => { try { const status = getSystemStatus(); res.json(status); } catch (error) { res.status(500).json({ error: error.message }); } }); // 获取今日请求统计 router.get('/today-requests', async (req, res) => { try { const todayRequests = getTodayRequestCount(); res.json({ todayRequests }); } catch (error) { res.status(500).json({ error: error.message }); } }); // Token 管理路由 // 获取所有账号 router.get('/tokens', async (req, res) => { try { const accounts = await loadAccounts(); // 隐藏敏感信息,只返回必要字段 const safeAccounts = accounts.map((acc, index) => ({ index, access_token: acc.access_token?.substring(0, 20) + '...', refresh_token: acc.refresh_token ? 'exists' : 'none', expires_in: acc.expires_in, timestamp: acc.timestamp, enable: acc.enable !== false, created: new Date(acc.timestamp).toLocaleString() })); res.json(safeAccounts); } catch (error) { res.status(500).json({ error: error.message }); } }); // 删除账号 router.delete('/tokens/:index', async (req, res) => { try { const index = parseInt(req.params.index); await deleteAccount(index); await addLog('warn', `Token 账号 ${index} 已删除`); res.json({ success: true }); } catch (error) { await addLog('error', `删除 Token 失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 启用/禁用账号 router.patch('/tokens/:index', async (req, res) => { try { const index = parseInt(req.params.index); const { enable } = req.body; await toggleAccount(index, enable); await addLog('info', `Token 账号 ${index} 已${enable ? '启用' : '禁用'}`); res.json({ success: true }); } catch (error) { await addLog('error', `切换 Token 状态失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 启用/禁用账号 (POST方法支持) router.post('/tokens/toggle', async (req, res) => { try { const { index, enable } = req.body; await toggleAccount(index, enable); await addLog('info', `Token 账号 ${index} 已${enable ? '启用' : '禁用'}`); res.json({ success: true }); } catch (error) { await addLog('error', `切换 Token 状态失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 触发登录流程 router.post('/tokens/login', async (req, res) => { try { await addLog('info', '开始 Google OAuth 登录流程'); const result = await triggerLogin(); res.json(result); } catch (error) { await addLog('error', `登录失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 获取 Token 统计 router.get('/tokens/stats', async (req, res) => { try { const stats = await getAccountStats(); res.json(stats); } catch (error) { res.status(500).json({ error: error.message }); } }); // 获取 Token 使用统计(轮询信息) router.get('/tokens/usage', async (req, res) => { try { const usageStats = tokenManager.getUsageStats(); res.json(usageStats); } catch (error) { res.status(500).json({ error: error.message }); } }); // 手动添加 Token(通过回调链接) router.post('/tokens/callback', async (req, res) => { try { const { callbackUrl } = req.body; if (!callbackUrl) { return res.status(400).json({ error: '请提供回调链接' }); } await addLog('info', '正在通过回调链接添加 Token...'); const result = await addTokenFromCallback(callbackUrl); await addLog('success', 'Token 已通过回调链接成功添加'); res.json(result); } catch (error) { await addLog('error', `添加 Token 失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 获取账号详细信息(包括名称) router.post('/tokens/details', async (req, res) => { try { const { indices } = req.body; const accounts = await loadAccounts(); const details = []; for (const index of indices) { if (index >= 0 && index < accounts.length) { const account = accounts[index]; const accountInfo = await getAccountName(account.access_token); details.push({ index, email: accountInfo.email, name: accountInfo.name, access_token: account.access_token, refresh_token: account.refresh_token, expires_in: account.expires_in, timestamp: account.timestamp, enable: account.enable !== false }); } } res.json(details); } catch (error) { res.status(500).json({ error: error.message }); } }); // 批量导出 Token (ZIP格式) router.post('/tokens/export', async (req, res) => { try { const { indices } = req.body; const accounts = await loadAccounts(); const exportData = []; for (const index of indices) { if (index >= 0 && index < accounts.length) { const account = accounts[index]; const accountInfo = await getAccountName(account.access_token); exportData.push({ email: accountInfo.email, name: accountInfo.name, access_token: account.access_token, refresh_token: account.refresh_token, expires_in: account.expires_in, timestamp: account.timestamp, created: new Date(account.timestamp).toLocaleString(), enable: account.enable !== false }); } } await addLog('info', `批量导出了 ${exportData.length} 个 Token 账号`); // 创建 ZIP 文件 const archive = archiver('zip', { zlib: { level: 9 } }); const timestamp = new Date().toISOString().split('T')[0]; res.attachment(`tokens_export_${timestamp}.zip`); res.setHeader('Content-Type', 'application/zip'); archive.pipe(res); // 添加 tokens.json 文件到 ZIP archive.append(JSON.stringify(exportData, null, 2), { name: 'tokens.json' }); await archive.finalize(); } catch (error) { await addLog('error', `批量导出失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 批量导入 Token (ZIP格式) router.post('/tokens/import', upload.single('file'), async (req, res) => { try { if (!req.file) { return res.status(400).json({ error: '请上传文件' }); } await addLog('info', '正在导入 Token 账号...'); const result = await importTokens(req.file.path); await addLog('success', `成功导入 ${result.count} 个 Token 账号`); res.json(result); } catch (error) { await addLog('error', `导入失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); // 获取系统设置 router.get('/settings', async (req, res) => { try { const settings = await loadSettings(); res.json(settings); } catch (error) { res.status(500).json({ error: error.message }); } }); // 保存系统设置 router.post('/settings', async (req, res) => { try { const result = await saveSettings(req.body); await addLog('success', '系统设置已更新'); res.json(result); } catch (error) { await addLog('error', `保存设置失败: ${error.message}`); res.status(500).json({ error: error.message }); } }); export default router; export { incrementRequestCount, addLog };