import { lstat } from "node:fs/promises"; import { hasValidAuth, renderPasswordForm } from "../auth"; import { notFound } from "../http"; import { log } from "../log"; import { contentDisposition, fileIdFromKey, KEY_PATTERN, secretMatches } from "../security"; import type { Storage } from "../storage"; export async function handleDownload( req: Request, storage: Storage, rawKey: string, secret: string, ): Promise { if (!KEY_PATTERN.test(rawKey)) return notFound(); const id = fileIdFromKey(rawKey); if (!id) return notFound(); const meta = await storage.readMetadata(id); if (!meta) return notFound(); if (!secretMatches(meta.downloadKeyHash, rawKey)) return notFound(); if (!hasValidAuth(req, secret, rawKey)) { const url = new URL(req.url); return renderPasswordForm(rawKey, meta.originalName, url.searchParams.has("e")); } const filePath = storage.filePath(id); let fileStat; try { fileStat = await lstat(filePath); } catch { return notFound(); } if (!fileStat.isFile()) return notFound(); const headers = new Headers({ "content-type": meta.mimeType || "application/octet-stream", "content-length": String(fileStat.size), "content-disposition": contentDisposition(meta.originalName), "cache-control": "private, no-store", "x-content-type-options": "nosniff", "referrer-policy": "no-referrer", }); if (req.method === "HEAD") return new Response(null, { status: 200, headers }); log("info", `download id=${id} size=${fileStat.size}`); return new Response(Bun.file(filePath).stream(), { status: 200, headers }); }