jevstrudel.git / worker / src / session.test.ts
1import { describe, expect, it } from 'vitest';
2import { fromThisSite, refuseCrossOrigin } from './session';
3
4const SITE = 'https://jevstrudel.example';
5const req = (method: string, origin?: string) =>
6  new Request(`${SITE}/jev/listeners/comments`, { method, headers: origin === undefined ? {} : { Origin: origin } });
7
8describe('this site only', () => {
9  it('takes a request with no Origin, or this site’s, as this site’s', () => {
10    expect(fromThisSite(req('GET'))).toBe(true);
11    expect(fromThisSite(req('POST', SITE))).toBe(true);
12    // the sandbox a listener's song plays in has an opaque origin: null
13    expect(fromThisSite(req('POST', 'null'))).toBe(false);
14    expect(fromThisSite(req('POST', 'https://evil.example'))).toBe(false);
15    expect(fromThisSite(req('POST', 'http://jevstrudel.example'))).toBe(false);
16  });
17
18  it('refuses every write from another origin, the sandbox’s included, and no read', () => {
19    for (const method of ['POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']) {
20      for (const origin of ['null', 'https://evil.example']) {
21        expect(refuseCrossOrigin(req(method, origin))?.status).toBe(403);
22      }
23      expect(refuseCrossOrigin(req(method, SITE))).toBeNull();
24      expect(refuseCrossOrigin(req(method))).toBeNull();
25    }
26    expect(refuseCrossOrigin(req('GET', 'null'))).toBeNull();
27    expect(refuseCrossOrigin(req('HEAD', 'https://evil.example'))).toBeNull();
28  });
29});