import { describe, expect, test } from "bun:test"; import { UploadPolicyError, createSignedFileToken, enforceUploadPolicy, inspectUpload, sniffContentType, verifySignedFileToken, } from "../src/security.ts"; describe("upload policy hardening", () => { test("enforces size, type, filename, and checksum independently", async () => { const inspection = await inspectUpload("report.pdf", new Uint8Array([0x25, 0x50, 0x44, 0x46])); const cases: Array<[Parameters[1], string | undefined, string]> = [ [{ maxBytes: 3 }, undefined, "UPLOAD_TOO_LARGE"], [{ accept: ["image/png"] }, undefined, "UPLOAD_TYPE_REJECTED"], [{ filenamePattern: /^invoice-/ }, undefined, "UPLOAD_FILENAME_REJECTED"], [{ requireChecksum: true }, undefined, "UPLOAD_CHECKSUM_REQUIRED"], [{}, "0".repeat(64), "UPLOAD_CHECKSUM_MISMATCH"], ]; for (const [policy, checksum, code] of cases) { try { enforceUploadPolicy(inspection, policy, checksum); throw new Error("policy unexpectedly accepted upload"); } catch (error) { expect(error).toBeInstanceOf(UploadPolicyError); expect((error as UploadPolicyError).code).toBe(code); } } enforceUploadPolicy( inspection, { maxBytes: 4, accept: ["application/pdf"] }, inspection.sha256, ); }); test("recognizes bounded signatures and rejects malformed signed-token inputs", async () => { expect(sniffContentType(new Uint8Array([0xff, 0xd8, 0xff]))).toBe("image/jpeg"); expect(sniffContentType(new Uint8Array([0x50, 0x4b, 0x03, 0x04]))).toBe("application/zip"); expect(sniffContentType(new Uint8Array([1, 2, 3]))).toBeNull(); await expect( createSignedFileToken({ store: "", key: "x", expiresAt: 1 }, "long-enough-secret"), ).rejects.toThrow("store"); expect(await verifySignedFileToken("not-a-token", "long-enough-secret")).toBeNull(); }); test("signed file tokens reject expiry, tampering, and the wrong signing key", async () => { const value = { store: "uploads", key: "safe/report.pdf", expiresAt: 2_000 }; const token = await createSignedFileToken(value, "long-enough-secret"); expect(await verifySignedFileToken(token, "long-enough-secret", 1_999)).toEqual(value); expect(await verifySignedFileToken(token, "long-enough-secret", 2_000)).toBeNull(); expect(await verifySignedFileToken(`${token}x`, "long-enough-secret", 1_999)).toBeNull(); expect(await verifySignedFileToken(token, "different-long-secret", 1_999)).toBeNull(); }); });