Spaces:
Running
Running
| import type { IncomingMessage, ServerResponse } from "node:http"; | |
| import type { RateLimiterMemory } from "rate-limiter-flexible"; | |
| import { | |
| type AuthorizationSurface, | |
| recordAuthorizedRequest, | |
| recordRejectedRequest, | |
| } from "./authorizationSinceLastRestart.ts"; | |
| import { verifyTokenAndRateLimit } from "./verifyTokenAndRateLimit.ts"; | |
| const SURFACES: [pathPrefix: string, surface: AuthorizationSurface][] = [ | |
| ["/search", "search"], | |
| ["/page-content", "pageContent"], | |
| ["/thumbnail", "thumbnail"], | |
| ["/inference", "inference"], | |
| ]; | |
| /** | |
| * The endpoint family a request was aimed at. `request.url` carries the query | |
| * string too, but the match is anchored at the start of it and only the label | |
| * is kept, so no part of a query can reach a counter or change one. | |
| */ | |
| function resolveSurface(request?: IncomingMessage): AuthorizationSurface { | |
| const path = request?.url ?? ""; | |
| const match = SURFACES.find(([pathPrefix]) => path.startsWith(pathPrefix)); | |
| return match ? match[1] : "other"; | |
| } | |
| export async function handleTokenVerification( | |
| token: string | null, | |
| response: ServerResponse, | |
| request?: IncomingMessage, | |
| options?: { limiter?: RateLimiterMemory }, | |
| ): Promise<{ shouldContinue: boolean }> { | |
| const result = await verifyTokenAndRateLimit( | |
| token, | |
| request, | |
| options?.limiter, | |
| ); | |
| const surface = resolveSurface(request); | |
| if (!result.isAuthorized) { | |
| recordRejectedRequest(surface, result.reason); | |
| response.statusCode = result.statusCode; | |
| response.setHeader("Content-Type", "application/json"); | |
| response.end(JSON.stringify({ error: result.error })); | |
| return { shouldContinue: false }; | |
| } | |
| recordAuthorizedRequest(surface); | |
| return { shouldContinue: true }; | |
| } | |