- Fix typo: santizedFileName -> sanitizedFileName in upload.tsx - Add sanitize(jobId) in download.tsx for defense-in-depth path traversal protection Even though jobId is validated against the database, sanitizing it prevents any potential path traversal via malicious job IDs.
65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import path from "node:path";
|
|
import { Elysia } from "elysia";
|
|
import sanitize from "sanitize-filename";
|
|
import * as tar from "tar";
|
|
import { outputDir } from "..";
|
|
import db from "../db/db";
|
|
import { WEBROOT } from "../helpers/env";
|
|
import { userService } from "./user";
|
|
|
|
export const download = new Elysia()
|
|
.use(userService)
|
|
.get(
|
|
"/download/:userId/:jobId/:fileName",
|
|
async ({ params, redirect, user }) => {
|
|
const userId = user.id;
|
|
const job = await db
|
|
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
|
.get(user.id, params.jobId);
|
|
|
|
if (!job) {
|
|
return redirect(`${WEBROOT}/results`, 302);
|
|
}
|
|
// parse from URL encoded string
|
|
const jobId = decodeURIComponent(params.jobId);
|
|
const fileName = sanitize(decodeURIComponent(params.fileName));
|
|
|
|
const filePath = `${outputDir}${userId}/${sanitize(jobId)}/${fileName}`;
|
|
return Bun.file(filePath);
|
|
},
|
|
{
|
|
auth: true,
|
|
},
|
|
)
|
|
.get(
|
|
"/archive/:jobId",
|
|
async ({ params, redirect, user }) => {
|
|
const userId = user.id;
|
|
const job = await db
|
|
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
|
.get(user.id, params.jobId);
|
|
|
|
if (!job) {
|
|
return redirect(`${WEBROOT}/results`, 302);
|
|
}
|
|
|
|
const jobId = decodeURIComponent(params.jobId);
|
|
const outputPath = `${outputDir}${userId}/${jobId}`;
|
|
const outputTar = path.join(outputPath, `converted_files_${jobId}.tar`);
|
|
|
|
await tar.create(
|
|
{
|
|
file: outputTar,
|
|
cwd: outputPath,
|
|
filter: (path) => {
|
|
return !path.match(".*\\.tar");
|
|
},
|
|
},
|
|
["."],
|
|
);
|
|
return Bun.file(outputTar);
|
|
},
|
|
{
|
|
auth: true,
|
|
},
|
|
);
|