← back to Govarbitrage
src/app/api/import/url/route.ts
31 lines
import { NextRequest, NextResponse } from "next/server";
import { scrapeUrl } from "@/importers/scrape";
import { ingest } from "@/importers/ingest";
import { requireWrite } from "@/lib/auth";
import { assertPublicUrl } from "@/lib/ssrf-guard";
export const dynamic = "force-dynamic";
export const runtime = "nodejs";
export const maxDuration = 60;
// Scrape a single auction URL (Playwright best-effort) and ingest it.
export async function POST(req: NextRequest) {
const denied = await requireWrite(req);
if (denied) return denied;
try {
const { url } = (await req.json()) as { url?: string };
if (!url) return NextResponse.json({ error: "Missing url" }, { status: 400 });
// SSRF guard: reject metadata/loopback/private targets before scraping.
try {
await assertPublicUrl(url);
} catch {
return NextResponse.json({ error: "URL not allowed" }, { status: 400 });
}
const raw = await scrapeUrl(url);
const result = await ingest(raw);
return NextResponse.json({ ...result, raw });
} catch (e) {
return NextResponse.json({ error: (e as Error).message }, { status: 500 });
}
}