| import type { FastifyRequest, FastifyReply } from 'fastify'; | |
| /** | |
| * Creates a Fastify onRequest hook that validates the proxy auth token. | |
| * | |
| * Accepts the token from either: | |
| * - `Authorization: Bearer <token>` (Claude Code / standard clients) | |
| * - `x-goog-api-key: <token>` (Gemini CLI) | |
| * | |
| * Rejects with 401 if no valid token is found or the token doesn't match. | |
| */ | |
| export function createAuthHook(proxyAuthToken: string): (request: FastifyRequest, reply: FastifyReply) => Promise<void> { | |
| return async (request: FastifyRequest, reply: FastifyReply): Promise<void> => { | |
| // Try Authorization header first (Claude Code / standard clients) | |
| const authHeader = request.headers['authorization']; | |
| if (authHeader) { | |
| const token = authHeader.startsWith('Bearer ') | |
| ? authHeader.slice(7) | |
| : authHeader; | |
| if (token === proxyAuthToken) return; | |
| } | |
| // Fall back to x-goog-api-key header (Gemini CLI) | |
| const googApiKey = request.headers['x-goog-api-key']; | |
| if (googApiKey) { | |
| const token = Array.isArray(googApiKey) ? googApiKey[0] : googApiKey; | |
| if (token === proxyAuthToken) return; | |
| } | |
| reply.code(401).send({ error: 'Missing or invalid authorization token' }); | |
| }; | |
| } | |