headers.test.ts
Language TypeScript2.6 KB60 lines
/*** The CSP must permit every data: URI kind the page actually embeds.** The brand fonts are embedded as data: URIs. Without a font-src, `default-src* 'none'` blocks them for everyone, and nobody with the fonts installed locally* can see it, because the browser resolves the family name from the OS and* renders the intended face anyway. A blocked embed masked by a local install is* invisible on exactly the machines that build and review the page, so this is* pinned by a test rather than by eyeballing.*/import { describe, expect, it } from 'vitest'import { MESSAGE_PAGE_HEADERS, PAGE_HEADERS } from '../src/index.js'describe('page CSP vs what the page embeds', () => {const csp = PAGE_HEADERS['content-security-policy']it('permits data: fonts, because the brand fonts are data: URIs', () => {expect(csp).toContain('font-src data:')})it('permits data: images, which the surfaces use for inline SVG', () => {expect(csp).toContain('img-src data:')})it('still defaults closed for everything unlisted', () => {expect(csp).toContain("default-src 'none'")})})/*** The reply feature needs no CSP directive, and that is a design decision worth* pinning rather than a happy accident.** A modal submitting with fetch() would need `connect-src 'self'`. The compose* window is a native <dialog> around a plain form POST instead, so the page* still cannot open a connection to anywhere, including back to itself. If a future change adds one, this test should be* changed deliberately, with the reason written down.*/describe('the compose window needs no new CSP directive', () => {it('has no connect-src at all: the page cannot open a connection anywhere', () => {expect(PAGE_HEADERS['content-security-policy']).not.toContain('connect-src')expect(MESSAGE_PAGE_HEADERS['content-security-policy']).not.toContain('connect-src')})it('permits a same-origin frame on the message page and nowhere wider', () => {// The message frame and the signature preview both live here.expect(MESSAGE_PAGE_HEADERS['content-security-policy']).toContain("frame-src 'self'")expect(MESSAGE_PAGE_HEADERS['content-security-policy']).not.toMatch(/frame-src[^;]*\*/)})it('still permits a same-origin form POST and nothing wider', () => {// Reply, mark-read, filter and signatures are all plain form POSTs.expect(PAGE_HEADERS['content-security-policy']).toContain("form-action 'self'")})it('the board page itself still cannot grow a frame', () => {expect(PAGE_HEADERS['content-security-policy']).not.toContain('frame-src')})})