Something went wrong. Try again.
Automations and webhooks for the AT Protocol airglow.run
automation webhook atproto atprotocol
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677import { describe, it, expect } from "vitest";import { Hono } from "hono";import { securityHeaders } from "./security-headers.js";
function createApp() { const app = new Hono(); app.use("*", securityHeaders()); app.get("/", (c) => c.text("ok")); return app;}
describe("securityHeaders", () => { it("sets the baseline security headers on every response", async () => { const res = await createApp().request("http://localhost/"); expect(res.headers.get("X-Content-Type-Options")).toBe("nosniff"); expect(res.headers.get("X-Frame-Options")).toBe("DENY"); expect(res.headers.get("Referrer-Policy")).toBe("strict-origin-when-cross-origin"); expect(res.headers.get("Strict-Transport-Security")).toContain("max-age="); expect(res.headers.get("Permissions-Policy")).toBe("camera=(), microphone=(), geolocation=()"); });
it("emits a CSP that pins script-src to self + a fresh nonce", async () => { const res = await createApp().request("http://localhost/"); const csp = res.headers.get("Content-Security-Policy"); expect(csp).not.toBeNull(); expect(csp).toContain("default-src 'self'"); expect(csp).toContain("frame-ancestors 'none'"); const match = csp!.match(/script-src 'self' 'nonce-([^']+)'/); expect(match).not.toBeNull(); expect(match![1]!.length).toBeGreaterThanOrEqual(16); expect(csp).not.toContain("'unsafe-inline'; script-src"); });
it("allows the Cloudflare Web Analytics beacon script and its reporting endpoint", async () => { const res = await createApp().request("http://localhost/"); const csp = res.headers.get("Content-Security-Policy")!; const directive = (name: string) => csp .split(";") .map((d) => d.trim()) .find((d) => d.startsWith(`${name} `)); expect(directive("script-src")).toContain("https://static.cloudflareinsights.com"); expect(directive("connect-src")).toContain("https://cloudflareinsights.com"); expect(directive("script-src")).not.toContain("'unsafe-inline'"); });
it("generates a different nonce per request", async () => { const app = createApp(); const r1 = await app.request("http://localhost/"); const r2 = await app.request("http://localhost/"); const n1 = r1.headers.get("Content-Security-Policy")!.match(/'nonce-([^']+)'/)![1]; const n2 = r2.headers.get("Content-Security-Policy")!.match(/'nonce-([^']+)'/)![1]; expect(n1).not.toBe(n2); });
it("exposes the nonce to route handlers via c.get('cspNonce')", async () => { const app = new Hono(); app.use("*", securityHeaders()); app.get("/", (c) => c.text(c.get("cspNonce") as string)); const res = await app.request("http://localhost/"); const body = await res.text(); const headerNonce = res.headers.get("Content-Security-Policy")!.match(/'nonce-([^']+)'/)![1]; expect(body).toBe(headerNonce); });
it("does not override a CSP set by an inner handler", async () => { const app = new Hono(); app.use("*", securityHeaders()); app.get("/", (c) => { c.header("Content-Security-Policy", "default-src 'none'"); return c.body(null, 204); }); const res = await app.request("http://localhost/"); expect(res.headers.get("Content-Security-Policy")).toBe("default-src 'none'"); });});