import { NextRequest, NextResponse } from "next/server"; import crypto from "node:crypto"; import { z } from "zod"; import { db, apiKeys, eq, sql } from "@epicure/db"; import { requireSession } from "@/lib/api-auth"; const CreateApiKeyBody = z.object({ name: z.string().min(1).max(100), }); export async function GET() { const { session, response } = await requireSession(); if (response) return response; const rows = await db .select({ id: apiKeys.id, name: apiKeys.name, lastUsedAt: apiKeys.lastUsedAt, createdAt: apiKeys.createdAt, }) .from(apiKeys) .where(eq(apiKeys.userId, session!.user.id)); return NextResponse.json(rows); } export async function POST(req: NextRequest) { const { session, response } = await requireSession(); if (response) return response; const body = await req.json() as unknown; const parsed = CreateApiKeyBody.safeParse(body); if (!parsed.success) { return NextResponse.json( { error: "Validation error", issues: parsed.error.issues }, { status: 400 } ); } const [row] = await db .select({ count: sql`count(*)::int` }) .from(apiKeys) .where(eq(apiKeys.userId, session!.user.id)); if ((row?.count ?? 0) >= 10) { return NextResponse.json({ error: "API key limit reached (max 10)" }, { status: 403 }); } const rawKey = "ek_" + crypto.randomBytes(32).toString("hex"); const keyHash = crypto.createHash("sha256").update(rawKey).digest("hex"); const id = crypto.randomUUID(); const now = new Date(); await db.insert(apiKeys).values({ id, userId: session!.user.id, name: parsed.data.name, keyHash, createdAt: now, }); return NextResponse.json( { id, name: parsed.data.name, key: rawKey, createdAt: now.toISOString() }, { status: 201 } ); }