File size: 1,315 Bytes
ae9d2aa
 
 
3784bc3
ae9d2aa
3784bc3
 
 
 
 
ae9d2aa
 
 
3784bc3
ae9d2aa
3784bc3
 
 
 
ae9d2aa
3784bc3
ae9d2aa
 
3784bc3
 
 
 
 
ae9d2aa
3784bc3
 
ae9d2aa
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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' });
    };
}