import { NextResponse } from "next/server" import { getSessionUser } from "@/lib/session" import { saveFile } from "@/lib/storage" const ALLOWED_SCOPES = ["property-images", "maintenance", "documents", "misc"] // Allowlisted upload extensions. Deliberately excludes svg and any html/script // types, which can execute JavaScript when served inline from our origin. const ALLOWED_EXTENSIONS = [ "pdf", "png", "jpg", "jpeg", "gif", "webp", "doc", "docx", "xls", "xlsx", "csv", "txt", ] // Generic authenticated upload endpoint. Saves the file to local disk under the // user's namespace and returns a URL pointing at the auth-gated /api/files route. export async function POST(request: Request) { const user = await getSessionUser() if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) const fd = await request.formData() const file = fd.get("file") as File | null const scopeRaw = (fd.get("scope") as string) || "misc" const scope = ALLOWED_SCOPES.includes(scopeRaw) ? scopeRaw : "misc" const fixedName = (fd.get("fixed_name") as string) || undefined if (!file) return NextResponse.json({ error: "No file provided" }, { status: 400 }) if (file.size > 20 * 1024 * 1024) { return NextResponse.json({ error: "File too large (max 20 MB)" }, { status: 400 }) } const ext = file.name.split(".").pop()?.toLowerCase() ?? "" if (!ALLOWED_EXTENSIONS.includes(ext)) { return NextResponse.json({ error: "File type not allowed" }, { status: 400 }) } const { key, size, type } = await saveFile(file, { userId: user.id, scope, fixedName }) return NextResponse.json({ url: `/api/files/${key}`, key, size, type, name: file.name, }) }