(req: any, res: any, next: any)
| 84 | } |
| 85 | |
| 86 | export function authenticate_api_request(req: any, res: any, next: any) { |
| 87 | const path = req.path || req.url; |
| 88 | if (is_public_endpoint(path)) return next(); |
| 89 | if (!auth_config.api_key || auth_config.api_key === "") { |
| 90 | console.warn("[AUTH] No API key configured"); |
| 91 | return next(); |
| 92 | } |
| 93 | const provided = extract_api_key(req); |
| 94 | if (!provided) |
| 95 | return res |
| 96 | .status(401) |
| 97 | .json({ |
| 98 | error: "authentication_required", |
| 99 | message: "API key required", |
| 100 | }); |
| 101 | if (!validate_api_key(provided, auth_config.api_key)) |
| 102 | return res.status(403).json({ error: "invalid_api_key" }); |
| 103 | const client_id = get_client_id(req, provided); |
| 104 | const rl = check_rate_limit(client_id); |
| 105 | if (auth_config.rate_limit_enabled) { |
| 106 | res.setHeader("X-RateLimit-Limit", auth_config.rate_limit_max_requests); |
| 107 | res.setHeader("X-RateLimit-Remaining", rl.remaining); |
| 108 | res.setHeader("X-RateLimit-Reset", Math.floor(rl.reset_time / 1000)); |
| 109 | } |
| 110 | if (!rl.allowed) |
| 111 | return res.status(429).json({ |
| 112 | error: "rate_limit_exceeded", |
| 113 | retry_after: Math.ceil((rl.reset_time - Date.now()) / 1000), |
| 114 | }); |
| 115 | next(); |
| 116 | } |
| 117 | |
| 118 | export function log_authenticated_request(req: any, res: any, next: any) { |
| 119 | const key = extract_api_key(req); |
nothing calls this directly
no test coverage detected