(req: express.Request, res: express.Response, next: express.NextFunction)
| 44 | |
| 45 | // ★ 日志查看器鉴权中间件:配置了 authTokens 时需要验证 |
| 46 | const logViewerAuth = (req: express.Request, res: express.Response, next: express.NextFunction) => { |
| 47 | const tokens = getConfig().authTokens; |
| 48 | if (!tokens || tokens.length === 0) return next(); // 未配置 token 则放行 |
| 49 | |
| 50 | // 支持多种传入方式: query ?token=xxx, Authorization header, x-api-key header |
| 51 | const tokenFromQuery = req.query.token as string | undefined; |
| 52 | const authHeader = req.headers['authorization'] || req.headers['x-api-key']; |
| 53 | const tokenFromHeader = authHeader ? String(authHeader).replace(/^Bearer\s+/i, '').trim() : undefined; |
| 54 | const token = tokenFromQuery || tokenFromHeader; |
| 55 | |
| 56 | if (!token || !tokens.includes(token)) { |
| 57 | // HTML 页面请求 → 返回登录页; API 请求 → 返回 JSON 错误 |
| 58 | if (req.path === '/logs') { |
| 59 | return serveLogViewerLogin(req, res); |
| 60 | } |
| 61 | res.status(401).json({ error: { message: 'Unauthorized. Provide token via ?token=xxx or Authorization header.', type: 'auth_error' } }); |
| 62 | return; |
| 63 | } |
| 64 | next(); |
| 65 | }; |
| 66 | |
| 67 | // ★ 日志查看器路由(带鉴权) |
| 68 | app.get('/logs', logViewerAuth, serveLogViewer); |
nothing calls this directly
no test coverage detected