53 lines · 2.0 KB
import { describe, expect, test } from "bun:test";
import { previewResponse } from "./preview-headers";

const prefix = "/preview/gitfor_pvw_abc/";

describe("previewResponse (INT-A7/INT-A8)", () => {
  test("drops everything but the content allow-list and pins the security headers", () => {
    const upstream = new Response("<p>hi</p>", {
      headers: {
        "content-type": "text/html",
        "set-cookie": "a=b",
        "access-control-allow-origin": "*",
        "access-control-allow-credentials": "true",
        "clear-site-data": '"*"',
        link: "</x.js>; rel=preload; as=script",
        "service-worker-allowed": "/",
        "content-disposition": "attachment",
      },
    });
    const response = previewResponse(upstream, prefix);
    expect(response.headers.get("content-type")).toBe("text/html");
    for (const name of [
      "set-cookie",
      "access-control-allow-origin",
      "access-control-allow-credentials",
      "clear-site-data",
      "link",
      "service-worker-allowed",
      "content-disposition",
    ]) {
      expect(response.headers.get(name)).toBeNull();
    }
    expect(response.headers.get("referrer-policy")).toBe("no-referrer");
    expect(response.headers.get("content-security-policy")).toContain("sandbox");
    expect(response.headers.get("x-content-type-options")).toBe("nosniff");
    expect(response.headers.get("cache-control")).toBe("no-store");
  });

  test("keeps same-host redirects inside the preview prefix and drops cross-origin ones", () => {
    const relative = previewResponse(