SPB Git

Repository Public

route.ts 1.5 KB 22 lines typescript

1import { sql } from "@/lib/db";2import { clientIpHash, sameOrigin } from "@/lib/auth";3import { rateLimit } from "@/lib/ratelimit";4import { bad } from "@/lib/api";56const REASONS = ["inaccurate", "harmful", "likeness", "copyright", "other"];7/** POST /api/reports — public takedown / problem report. Reviewed by a person in the studio. */8export async function POST(req: Request) {9  if (!sameOrigin(req)) return bad("bad_origin", 403);10  if (!(await rateLimit(`report:${await clientIpHash()}`, 5, 3600))) return bad("rate_limited", 429);11  const b = (await req.json().catch(() => null)) as Record<string, unknown> | null;12  if (!b) return bad("invalid_body");13  if (typeof b.website === "string" && b.website) return new Response(null, { status: 204 });   // honeypot14  const detail = String(b.detail ?? "").trim().slice(0, 2000), reason = String(b.reason ?? "other");15  if (detail.length < 8 || !REASONS.includes(reason)) return bad("invalid_body");16  const ref = String(b.film ?? "").trim().slice(0, 200);17  const slug = ref.split("/film/").pop()?.split(/[?#]/)[0] ?? "";18  const [film] = await sql<{ id: string }[]>`SELECT id FROM films WHERE slug = ${slug} OR lower(title_en) = lower(${ref}) OR lower(title_fr) = lower(${ref}) LIMIT 1`;19  await sql`INSERT INTO reports (film_id, reason, detail, contact) VALUES (${film?.id ?? null}, ${reason}, ${film ? detail : `[${ref}] ${detail}`}, ${String(b.contact ?? "").trim().slice(0, 200)})`;20  return Response.json({ ok: true }, { status: 201 });21}22
Files main
Menu

Theme