import { createServiceClient } from "../_shared/security.ts"; import { getCorsHeaders, jsonResponse, preflightResponse, readJsonBody, } from "../_shared/security.ts"; const MAX_BODY_BYTES = 4 * 1024; type UnsubscribeBody = { endpoint?: string; phone_normalized?: string; }; Deno.serve(async (request) => { if (request.method === "OPTIONS") { return preflightResponse(request, "public"); } if (request.method !== "POST") { return jsonResponse({ ok: false, error: "Method not allowed" }, 405); } const corsHeaders = getCorsHeaders(request, "public"); if (!corsHeaders) { return jsonResponse({ ok: false, error: "Origin not allowed" }, 403); } try { const { body } = await readJsonBody(request, { maxBytes: MAX_BODY_BYTES, }); const endpoint = String(body.endpoint || "").trim(); const phoneNormalized = String(body.phone_normalized || "").trim(); if (!endpoint) { return jsonResponse( { ok: false, error: "endpoint is required" }, 400, corsHeaders, ); } if (!phoneNormalized) { return jsonResponse( { ok: false, error: "phone_normalized is required" }, 400, corsHeaders, ); } const supabase = createServiceClient(); const now = new Date().toISOString(); const { data, error } = await supabase .from("push_subscriptions") .update({ is_active: false, updated_at: now, }) .eq("endpoint", endpoint) .eq("phone_normalized", phoneNormalized) .select("id, phone_normalized, endpoint, is_active, updated_at"); if (error) { console.error("push-unsubscribe update error:", error); return jsonResponse( { ok: false, error: "Database error", detail: error.message }, 500, corsHeaders, ); } const deactivatedCount = data?.length || 0; return jsonResponse( { ok: true, deactivated: deactivatedCount, subscriptions: data, }, 200, corsHeaders, ); } catch (error) { if (error instanceof Error && "status" in error) { const httpError = error as { status: number; message: string }; return jsonResponse( { ok: false, error: httpError.message }, httpError.status, corsHeaders, ); } return jsonResponse( { ok: false, error: error instanceof Error ? error.message : "Unexpected error", }, 500, corsHeaders, ); } });