import { NextResponse } from "next/server" import { createSupabaseServerClient } from "@/lib/supabase/server" import { createSupabaseAdminClient } from "@/lib/supabase/admin" import { TIER_LIMITS, type SubscriptionTier } from "@asa-news/shared" import { rateLimit } from "@/lib/rate-limit" export async function GET() { const supabaseClient = await createSupabaseServerClient() const { data: { user }, } = await supabaseClient.auth.getUser() if (!user) { return NextResponse.json({ error: "not authenticated" }, { status: 401 }) } const adminClient = createSupabaseAdminClient() const { data: profile, error } = await adminClient .from("user_profiles") .select( "tier, webhook_url, webhook_secret, webhook_enabled, webhook_consecutive_failures" ) .eq("id", user.id) .single() if (error || !profile) { return NextResponse.json( { error: "failed to load webhook config" }, { status: 500 } ) } return NextResponse.json({ webhookUrl: profile.webhook_url, webhookSecret: profile.webhook_secret, webhookEnabled: profile.webhook_enabled, consecutiveFailures: profile.webhook_consecutive_failures, }) } export async function PUT(request: Request) { const supabaseClient = await createSupabaseServerClient() const { data: { user }, } = await supabaseClient.auth.getUser() if (!user) { return NextResponse.json({ error: "not authenticated" }, { status: 401 }) } const rateLimitResult = rateLimit(`webhook-config:${user.id}`, 10, 60_000) if (!rateLimitResult.success) { return NextResponse.json({ error: "too many requests" }, { status: 429 }) } const adminClient = createSupabaseAdminClient() const { data: profile } = await adminClient .from("user_profiles") .select("tier") .eq("id", user.id) .single() if ( !profile || !TIER_LIMITS[profile.tier as SubscriptionTier]?.allowsWebhooks ) { return NextResponse.json( { error: "webhooks require the developer plan" }, { status: 403 } ) } const body = await request.json().catch(() => ({})) const updates: Record = {} if (typeof body.webhookUrl === "string") { const trimmedUrl = body.webhookUrl.trim() if (trimmedUrl && !trimmedUrl.startsWith("https://")) { return NextResponse.json( { error: "webhook url must use https" }, { status: 400 } ) } updates.webhook_url = trimmedUrl || null } if (typeof body.webhookSecret === "string") { updates.webhook_secret = body.webhookSecret.trim() || null } if (typeof body.webhookEnabled === "boolean") { if (body.webhookEnabled) { const { data: currentProfile } = await adminClient .from("user_profiles") .select("webhook_url") .eq("id", user.id) .single() const effectiveUrl = typeof body.webhookUrl === "string" ? body.webhookUrl.trim() : currentProfile?.webhook_url if (!effectiveUrl) { return NextResponse.json( { error: "cannot enable webhooks without a url" }, { status: 400 } ) } updates.webhook_consecutive_failures = 0 } updates.webhook_enabled = body.webhookEnabled } if (Object.keys(updates).length === 0) { return NextResponse.json({ error: "no updates provided" }, { status: 400 }) } const { error } = await adminClient .from("user_profiles") .update(updates) .eq("id", user.id) if (error) { return NextResponse.json( { error: "failed to update webhook config" }, { status: 500 } ) } return NextResponse.json({ updated: true }) }