import { NextResponse } from "next/server"; import fssync from "node:fs"; import path from "node:path"; import mime from "mime"; const BASE = "/app/files"; function safeJoin(base: string, reqPath: string) { const decoded = decodeURIComponent(reqPath || "/"); const normalized = path.posix.normalize("/" + decoded).replace(/^(\.\.(\/|\\|$))+/g, ""); const full = path.join(base, normalized); if (!full.startsWith(base)) throw new Error("Invalid path"); return full; } export async function GET(req: Request) { try { const { searchParams } = new URL(req.url); const p = searchParams.get("path"); if (!p) return NextResponse.json({ ok: false, error: "Missing path" }, { status: 400 }); const abs = safeJoin(BASE, p); if (!fssync.existsSync(abs) || !fssync.statSync(abs).isFile()) { return NextResponse.json({ ok: false, error: "Not found" }, { status: 404 }); } const stream = fssync.createReadStream(abs); const type = mime.getType(abs) || "application/octet-stream"; return new Response(stream as any, { headers: { "Content-Type": type, "Cache-Control": "public, max-age=3600", }, }); } catch (err: any) { return NextResponse.json({ ok: false, error: err?.message || "Error" }, { status: 400 }); } }