import { NextResponse } from "next/server"; import { z } from "zod"; import { db, userAiKeys, eq, and } from "@epicure/db"; import { requireSession } from "@/lib/api-auth"; import { encrypt } from "@/lib/encrypt"; import { applyRateLimit } from "@/lib/rate-limit"; const VALID_PROVIDERS = ["openai", "anthropic", "openrouter", "ollama"] as const; const PostSchema = z.object({ provider: z.enum(VALID_PROVIDERS), apiKey: z.string().min(1).max(500), }); export async function GET() { const { session, response } = await requireSession(); if (response) return response; const keys = await db.query.userAiKeys.findMany({ where: eq(userAiKeys.userId, session!.user.id), columns: { provider: true, createdAt: true }, }); return NextResponse.json({ keys }); } export async function POST(req: Request) { const { session, response } = await requireSession(); if (response) return response; const limited = await applyRateLimit(`rl:ai-keys:${session!.user.id}`, 5, 3600); if (limited) return limited; const body = PostSchema.safeParse(await req.json()); if (!body.success) return NextResponse.json({ error: "Validation error", issues: body.error.issues }, { status: 400 }); const { provider, apiKey } = body.data; const userId = session!.user.id; const existing = await db.query.userAiKeys.findFirst({ where: and(eq(userAiKeys.userId, userId), eq(userAiKeys.provider, provider)), }); const encryptedKey = encrypt(apiKey); if (existing) { await db.update(userAiKeys) .set({ encryptedKey }) .where(and(eq(userAiKeys.userId, userId), eq(userAiKeys.provider, provider))); } else { await db.insert(userAiKeys).values({ id: crypto.randomUUID(), userId, provider, encryptedKey, }); } return NextResponse.json({ ok: true }); }