import { NextRequest, NextResponse } from "next/server"; import { headers } from "next/headers"; import { auth } from "@/lib/auth"; import { uploadFile } from "@/lib/s3"; import { randomUUID } from "crypto"; // Images only: comments render them inline, and anything else would just be an // unlabelled blob in the middle of a discussion. const ALLOWED_TYPES = new Set(["image/jpeg", "image/png", "image/gif", "image/webp"]); const ALLOWED_EXTS = new Set(["jpg", "jpeg", "png", "gif", "webp"]); const MAX_BYTES = 5 * 1024 * 1024; // 5 MB — enough for a screenshot export async function POST(req: NextRequest) { const session = await auth.api.getSession({ headers: await headers() }); if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); const form = await req.formData(); const file = form.get("file") as File | null; if (!file) return NextResponse.json({ error: "Missing file" }, { status: 400 }); if (file.size > MAX_BYTES) { return NextResponse.json({ error: "Изображение слишком большое (макс. 5 МБ)" }, { status: 413 }); } if (!ALLOWED_TYPES.has(file.type)) { return NextResponse.json({ error: "Разрешены только изображения: jpg, png, gif, webp" }, { status: 415 }); } const ext = file.name.split(".").pop()?.toLowerCase() ?? "bin"; if (!ALLOWED_EXTS.has(ext)) { return NextResponse.json({ error: "Недопустимое расширение файла" }, { status: 415 }); } const key = `comments/${session.user.id}/${randomUUID()}.${ext}`; const buffer = Buffer.from(await file.arrayBuffer()); const url = await uploadFile(key, buffer, file.type); return NextResponse.json({ name: file.name, url, size: file.size }); }