import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { db, webhooks, eq, and } from "@epicure/db"; import { requireSession } from "@/lib/api-auth"; import { validateWebhookUrl } from "@/lib/validate-webhook-url"; import { WEBHOOK_EVENTS } from "@/lib/webhooks"; const UpdateWebhookBody = z.object({ url: z.string().min(1).max(2048).optional(), events: z.array(z.enum(WEBHOOK_EVENTS)).optional(), active: z.boolean().optional(), }); export async function DELETE( _req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { session, response } = await requireSession(); if (response) return response; const { id } = await params; const existing = await db .select({ id: webhooks.id }) .from(webhooks) .where(and(eq(webhooks.id, id), eq(webhooks.userId, session!.user.id))) .limit(1); if (existing.length === 0) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } await db .delete(webhooks) .where(and(eq(webhooks.id, id), eq(webhooks.userId, session!.user.id))); return new NextResponse(null, { status: 204 }); } export async function PATCH( req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { session, response } = await requireSession(); if (response) return response; const { id } = await params; const existing = await db .select({ id: webhooks.id }) .from(webhooks) .where(and(eq(webhooks.id, id), eq(webhooks.userId, session!.user.id))) .limit(1); if (existing.length === 0) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } const body = await req.json() as unknown; const parsed = UpdateWebhookBody.safeParse(body); if (!parsed.success) { return NextResponse.json( { error: "Validation error", issues: parsed.error.issues }, { status: 400 } ); } if (parsed.data.url) { const ssrfError = await validateWebhookUrl(parsed.data.url); if (ssrfError) { return NextResponse.json({ error: ssrfError }, { status: 400 }); } } const updates: Partial<{ url: string; events: string[]; active: boolean }> = {}; if (parsed.data.url !== undefined) updates.url = parsed.data.url; if (parsed.data.events !== undefined) updates.events = parsed.data.events; if (parsed.data.active !== undefined) updates.active = parsed.data.active; if (Object.keys(updates).length === 0) { return NextResponse.json({ error: "No fields to update" }, { status: 400 }); } await db .update(webhooks) .set(updates) .where(and(eq(webhooks.id, id), eq(webhooks.userId, session!.user.id))); const updated = await db .select({ id: webhooks.id, userId: webhooks.userId, url: webhooks.url, events: webhooks.events, active: webhooks.active, createdAt: webhooks.createdAt, }) .from(webhooks) .where(eq(webhooks.id, id)) .limit(1); return NextResponse.json(updated[0]); }