import assert from "node:assert/strict"; import { createHash, randomBytes } from "node:crypto"; import { mkdtempSync } from "node:fs"; import { readFile, readdir, stat } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { Readable } from "node:stream"; import { test } from "node:test"; import { UploadDir, hashOf, isValidObjectName } from "../src/upload.ts"; test("object name validation", () => { const hash = "a".repeat(64); assert.ok(isValidObjectName(hash)); assert.ok(isValidObjectName(`${hash}.mp4`)); assert.ok(isValidObjectName(`${hash}.webm`)); assert.ok(!isValidObjectName(`${hash}.`)); assert.ok(!isValidObjectName(`${hash}.MP4`), "uppercase extension"); assert.ok(!isValidObjectName(`${hash}.m p4`), "space in extension"); assert.ok(!isValidObjectName(`../../etc/passwd`), "traversal"); assert.ok(!isValidObjectName(`${"a".repeat(63)}.mp4`), "short hash"); assert.ok(!isValidObjectName(`${hash}.${"x".repeat(17)}`), "long extension"); assert.equal(hashOf(`${hash}.mp4`), hash); }); function payload(bytes: Buffer): { name: string; body: Readable } { const digest = createHash("sha256").update(bytes).digest("hex"); return { name: `${digest}.bin`, body: Readable.from([bytes]) }; } test("receive stores a verified upload and is idempotent", async () => { const dir = mkdtempSync(join(tmpdir(), "uploads-")); const uploads = new UploadDir(dir, 1024 * 1024); await uploads.init(); const bytes = randomBytes(4096); const { name, body } = payload(bytes); assert.deepEqual(await uploads.receive(name, body), { status: "created" }); assert.deepEqual(await readFile(join(dir, name)), bytes); assert.ok(await uploads.exists(name)); const again = await uploads.receive(name, Readable.from([bytes])); assert.deepEqual(again, { status: "exists" }); // The temp dir holds no leftovers either way. assert.deepEqual(await readdir(join(dir, ".internaluploader-tmp")), []); }); test("receive rejects a body that does not match its name", async () => { const dir = mkdtempSync(join(tmpdir(), "uploads-")); const uploads = new UploadDir(dir, 1024 * 1024); await uploads.init(); const name = `${"0".repeat(64)}.bin`; const outcome = await uploads.receive(name, Readable.from([randomBytes(16)])); assert.equal(outcome.status, "hash-mismatch"); await assert.rejects(stat(join(dir, name))); assert.deepEqual(await readdir(join(dir, ".internaluploader-tmp")), []); }); test("receive enforces the size ceiling", async () => { const dir = mkdtempSync(join(tmpdir(), "uploads-")); const uploads = new UploadDir(dir, 1000); await uploads.init(); const bytes = randomBytes(4096); const { name, body } = payload(bytes); const outcome = await uploads.receive(name, body); assert.equal(outcome.status, "too-large"); assert.deepEqual(await readdir(join(dir, ".internaluploader-tmp")), []); });