import { NextRequest, NextResponse } from "next/server"; import { rateLimited, sanitize, sendEmail } from "@/lib/server-utils"; import { trimTooLong } from "@/lib/strings"; import validator from "validator"; const validateInput = (data: any) => { return ( typeof data !== "object" || ( !data.anon && ( typeof data.name !== "string" || typeof data.email !== "string" ) || typeof data.message !== "string" ) || !data.anon && ( !data.name.trim() || !data.email.trim() || !validator.isEmail(data.email) ) || !data.message.trim() ) } export async function POST(req: NextRequest) { const agent = req.headers.get("x-forwarded-for") ?? "damn"; const isRateLimited = await rateLimited(agent); if (isRateLimited) { return NextResponse.json( { error: "Too many requests" }, { status: 429 } ); } let data; try { data = await req.json(); } catch { return NextResponse.json( { error: "Invalid input" }, { status: 400 } ); } if (validateInput(data)) { return NextResponse.json( { error: "Invalid input" }, { status: 400 } ); } try { const name = trimTooLong(data.name as string, 20); const rawMessage = trimTooLong(data.message, 5000); const message = sanitize(validator.escape(rawMessage)); await sendEmail(name, data.email, message); return NextResponse.json({ status: "ok" }); } catch (err) { console.error(err); return NextResponse.json({ status: "failed", message: err instanceof Error ? err.message : '' }); } }