80 lines
2.6 KiB
JavaScript
80 lines
2.6 KiB
JavaScript
// Hermes Server 入口 — 接收 EternalAI 同步请求,创建 profile,生成二维码
|
||
|
||
require('dotenv').config();
|
||
const express = require('express');
|
||
const cors = require('cors');
|
||
const path = require('path');
|
||
|
||
const { ensureDirs } = require('./src/lib/profile-store');
|
||
|
||
const app = express();
|
||
const PORT = process.env.PORT || 3002;
|
||
|
||
// 确保数据目录存在
|
||
ensureDirs();
|
||
|
||
// 中间件
|
||
// P2 修复:CORS 限制为已知来源
|
||
const allowedOrigins = process.env.ALLOWED_ORIGINS;
|
||
if (allowedOrigins) {
|
||
app.use(cors({ origin: allowedOrigins.split(',').map((o) => o.trim()) }));
|
||
} else {
|
||
// 非生产环境默认允许所有来源,生产环境需配置 ALLOWED_ORIGINS
|
||
app.use(cors());
|
||
}
|
||
app.use(express.json({ limit: '1mb' }));
|
||
app.use(express.urlencoded({ extended: true, limit: '1mb' }));
|
||
|
||
// P1 修复:trust proxy 仅信任 loopback(Nginx 反向代理场景)
|
||
// 生产环境应配置为具体代理 IP,如 app.set('trust proxy', '10.0.0.1')
|
||
app.set('trust proxy', 'loopback');
|
||
|
||
// 路由
|
||
app.use('/api', require('./src/routes/health'));
|
||
app.use('/api', require('./src/routes/sync'));
|
||
app.use('/api/profiles', require('./src/routes/profiles'));
|
||
app.use('/api/bind', require('./src/routes/bind'));
|
||
|
||
// 二维码图片静态服务
|
||
const QRCODES_DIR = path.join(__dirname, 'data', 'qrcodes');
|
||
app.use('/api/qrcodes', express.static(QRCODES_DIR, {
|
||
setHeaders: (res) => {
|
||
res.type('image/png');
|
||
res.set('Cache-Control', 'public, max-age=86400');
|
||
},
|
||
}));
|
||
|
||
// 根路径 — 简单信息页
|
||
app.get('/', (req, res) => {
|
||
res.json({
|
||
service: 'hermes-server',
|
||
status: 'running',
|
||
endpoints: {
|
||
sync: 'POST /api/sync',
|
||
profiles: 'GET /api/profiles',
|
||
bind: 'GET /api/bind/:profileId',
|
||
health: 'GET /api/health',
|
||
},
|
||
});
|
||
});
|
||
|
||
// 404
|
||
app.use((req, res) => {
|
||
res.status(404).json({ error: '接口不存在' });
|
||
});
|
||
|
||
// 错误处理
|
||
app.use((err, req, res, next) => {
|
||
console.error('[Hermes Server] 未捕获错误:', err);
|
||
res.status(500).json({ error: '服务器内部错误' });
|
||
});
|
||
|
||
app.listen(PORT, '0.0.0.0', () => {
|
||
console.log(`Hermes Server running on http://0.0.0.0:${PORT}`);
|
||
console.log(`HERMES_BASE_URL: ${process.env.HERMES_BASE_URL || `http://localhost:${PORT}`}`);
|
||
console.log(`ETERNALAI_BASE_URL: ${process.env.ETERNALAI_BASE_URL || '⚠️ 未配置'}`);
|
||
console.log(`SYNC_SECRET: ${process.env.SYNC_SECRET ? '已配置' : '⚠️ 未配置'}`);
|
||
console.log(`HERMES_ADMIN_TOKEN: ${process.env.HERMES_ADMIN_TOKEN ? '已配置' : '⚠️ 使用默认值'}`);
|
||
console.log(`NODE_ENV: ${process.env.NODE_ENV || 'development'}`);
|
||
});
|