import { Router } from "@oak/oak"; import { APIErrorCode, APIException } from "../model/interfaces.ts"; import { getDump } from "../services/dump-service.ts"; const router = new Router({ prefix: "/api/files" }); router.get("/:dumpId", async (ctx) => { const { dumpId } = ctx.params; // Guard against path traversal (UUIDs are safe, but be explicit) if (!/^[0-9a-f-]{36}$/.test(dumpId)) { throw new APIException(APIErrorCode.BAD_REQUEST, 400, "Invalid dump ID"); } const dump = getDump(dumpId); if (dump.kind !== "file" || !dump.fileMime || !dump.fileName) { throw new APIException(APIErrorCode.NOT_FOUND, 404, "No file for this dump"); } try { const data = await Deno.readFile(`api/uploads/${dumpId}`); ctx.response.headers.set("Content-Type", dump.fileMime); ctx.response.headers.set( "Content-Disposition", `inline; filename="${dump.fileName}"`, ); ctx.response.body = data; } catch { throw new APIException(APIErrorCode.NOT_FOUND, 404, "File not found"); } }); export default router;