import { createHmac } from "node:crypto"; import { afterEach, describe, expect, it, vi } from "vitest"; import worker from "./index.js"; const SANDBOX_CSP = "default-src 'none'; style-src 'unsafe-inline'; sandbox"; const env = { CAMO_SHARED_SECRET: "s3cret" }; const signed = (url) => `https://camo.test/${createHmac("sha256", "s3cret").update(Buffer.from(url, "utf8")).digest("hex")}/${Buffer.from(url, "utf8").toString("hex")}`; const serve = (url, fetch, match = async () => undefined, put = async () => {}) => { vi.stubGlobal("fetch", fetch); vi.stubGlobal("caches", { default: { match, put } }); return worker.fetch(new Request(signed(url)), env); }; afterEach(() => vi.unstubAllGlobals()); describe("fetch", () => { it("sandboxes an SVG with scripts in it", async () => { const svg = ''; const fresh = await serve( "https://ebilupstream.test/logo.svg", vi.fn(async () => new Response(svg, { headers: { "Content-Type": "image/svg+xml" } }), ), ); expect(fresh.status).toBe(200); expect(fresh.headers.get("Content-Type")).toBe("image/svg+xml"); expect(fresh.headers.get("Content-Security-Policy")).toBe(SANDBOX_CSP); expect(fresh.headers.get("X-Content-Type-Options")).toBe("nosniff"); const stored = new Response(svg, { headers: { "Content-Type": "image/svg+xml", "Cache-Control": "public, max-age=86400, immutable", }, }); const cached = await serve( "https://ebilupstream.test/logo.svg", vi.fn(), async () => stored, ); expect(cached.status).toBe(200); expect(cached.headers.get("Content-Security-Policy")).toBe(SANDBOX_CSP); expect(cached.headers.get("X-Content-Type-Options")).toBe("nosniff"); }); it("returns 415 for a type off the allowlist", async () => { const res = await serve( "https://ebilupstream.test/page", vi.fn(async () => new Response("", { headers: { "Content-Type": "text/html" }, }), ), ); expect(res.status).toBe(415); }); });