Skip to main content
Glama
utils.ts1.53 kB
import { NextRequest } from "next/server"; import { z } from "zod"; import db from "@repo/db"; import { apiKeysTable } from "@repo/db/schema/api"; import { eq } from "@repo/db/drizzle"; import { ForbiddenError, UnauthorizedError, UserError, ValidationError } from "@repo/core"; interface ValidatedRequest<T> { data: T; organizationId: number; error?: Response; } interface ErrorResponse { error: Response; } async function validateApiKey(apiKey: string) { const [key] = await db .select({ id: apiKeysTable.id, organizationId: apiKeysTable.organizationId, }) .from(apiKeysTable) .where(eq(apiKeysTable.key, apiKey)) .limit(1); if (!key) { return null; } return key; } export async function validateApiRequest<T>(req: NextRequest, schema: z.ZodSchema<T>): Promise<ValidatedRequest<T>> { // Extract and validate API key const authHeader = req.headers.get("authorization"); if (!authHeader?.startsWith("Bearer ")) { throw new UnauthorizedError("Missing or invalid Authorization header"); } const apiKey = authHeader.slice(7); // Remove "Bearer " prefix const keyData = await validateApiKey(apiKey); if (!keyData) { throw new ForbiddenError("Invalid API key"); } // Validate request body against schema const json = await req.json(); const parsed = schema.safeParse(json); if (!parsed.success) { throw new ValidationError(parsed.error.format()); } return { data: parsed.data, organizationId: keyData.organizationId, }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/madarco/ragrabbit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server