/** * GET /api/auth/lookup-email?email=foo@example.com * * Returns { known: true|false }. "Known" means the email is already on our * subscriber list (bb.email_subscribers) OR has an auth.users entry. Used * by the register page so existing newsletter readers get a magic-link * login flow instead of being asked to create a new account. * * Privacy: returns only known/not-known, never any details — does not * leak account existence beyond a binary signal (necessary for the UX). * Rate-limited at the proxy layer. */ import { NextRequest, NextResponse } from "next/server"; import { createClient as createService } from "@supabase/supabase-js"; export async function GET(req: NextRequest) { const email = (new URL(req.url).searchParams.get("email") || "").trim().toLowerCase(); if (!email || !email.includes("@")) { return NextResponse.json({ known: false }, { status: 400 }); } const url = process.env.NEXT_PUBLIC_SUPABASE_URL || ""; const key = process.env.SUPABASE_SERVICE_ROLE_KEY || ""; if (!url || !key) { return NextResponse.json({ known: false }); } const svc = createService(url, key, { auth: { persistSession: false } }); // Layer 1 — the rich subscriber registry (95k+ rows) const { data: sub } = await svc .schema("av") .from("email_subscribers") .select("id, status") .eq("email_domain", email.split("@")[1]) .ilike("email", email) .limit(1) .maybeSingle(); if (sub) return NextResponse.json({ known: true, source: "subscriber" }); // Layer 2 — the lean property-specific list const { data: nl } = await svc .schema("av") .from("newsletter_subscribers") .select("id") .ilike("email", email) .limit(1) .maybeSingle(); if (nl) return NextResponse.json({ known: true, source: "newsletter" }); return NextResponse.json({ known: false }); }