vibe coded v1
This commit is contained in:
34
api/routes/files.ts
Normal file
34
api/routes/files.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user