fix: serve uploads via route handler instead of public/ (standalone 404 fix)
All checks were successful
Deploy / build-and-deploy (push) Successful in 1m49s

This commit is contained in:
2026-06-15 03:34:11 +03:00
parent 3f41d7699c
commit cfcfa0ccee
7 changed files with 55 additions and 5 deletions

View File

@@ -7,7 +7,7 @@ import path from "path";
import { v4 as uuidv4 } from "uuid";
import { eq } from "drizzle-orm";
const UPLOAD_DIR = path.join(process.cwd(), "public", "uploads", "images");
const UPLOAD_DIR = path.join(process.cwd(), "data", "uploads", "images");
const ALLOWED_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
const MAX_SIZE = 5 * 1024 * 1024;

View File

@@ -10,7 +10,7 @@ import { convertToCompressedMp3 } from "@/lib/convert";
export const maxDuration = 120;
const UPLOAD_DIR = path.join(process.cwd(), "public", "uploads", "sounds");
const UPLOAD_DIR = path.join(process.cwd(), "data", "uploads", "sounds");
const ALLOWED_EXTENSIONS = /\.(mp3|ogg|wav|flac|aac|m4a|wma|opus|webm|mp4|avi|mov|mkv|webm|wmv|flv)$/i;
const MAX_SIZE = 50 * 1024 * 1024; // 50 MB

View File

@@ -9,7 +9,7 @@ import { convertToCompressedMp3 } from "@/lib/convert";
export const maxDuration = 60;
const UPLOAD_DIR = path.join(process.cwd(), "public", "uploads", "sounds");
const UPLOAD_DIR = path.join(process.cwd(), "data", "uploads", "sounds");
const ALLOWED_EXTENSIONS = /\.(mp3|ogg|wav|flac|aac|m4a|wma|opus|webm|mp4|avi|mov|mkv|webm|wmv|flv)$/i;
const MAX_SIZE = 50 * 1024 * 1024; // 50 MB

View File

@@ -0,0 +1,49 @@
import { NextRequest, NextResponse } from "next/server";
import fs from "fs";
import path from "path";
const UPLOADS_DIR = path.join(process.cwd(), "data", "uploads");
export async function GET(
_req: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }
) {
const { path: segments } = await params;
const filePath = path.join(UPLOADS_DIR, ...segments);
if (!filePath.startsWith(UPLOADS_DIR)) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
}
try {
const content = fs.readFileSync(filePath);
const ext = path.extname(filePath).toLowerCase();
const mime = MIME_MAP[ext] ?? "application/octet-stream";
return new NextResponse(content, {
headers: {
"Content-Type": mime,
"Cache-Control": "public, max-age=31536000, immutable",
},
});
} catch {
return NextResponse.json({ error: "Not found" }, { status: 404 });
}
}
const MIME_MAP: Record<string, string> = {
".mp3": "audio/mpeg",
".ogg": "audio/ogg",
".wav": "audio/wav",
".flac": "audio/flac",
".m4a": "audio/mp4",
".webm": "audio/webm",
".mp4": "video/mp4",
".avi": "video/x-msvideo",
".mov": "video/quicktime",
".mkv": "video/x-matroska",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".webp": "image/webp",
};