Skip to content
File

Blob: tests/worker/helpers/dav.ts

typescript49 lines
1import { MeResponseSchema, PatCreateResponseSchema } from "@/worker/openapi/schemas";
2import { completeOidcLogin } from "@tests/worker/helpers/auth";
3import { controlRequest, fetchWorker, subjectRequest } from "@tests/worker/helpers/http";
4 
5export interface DavFixture {
6 subjectId: string;
7 hostLabel: string;
8 token: string;
9 authHeader: string;
10}
11 
12export function basicPat(token: string): string {
13 return `Basic ${btoa(`dav:${token}`)}`;
14}
15 
16export async function createDavFixture(scopes: string[] = ["files.full"]): Promise<DavFixture> {
17 const login = await completeOidcLogin();
18 const meResponse = await fetchWorker(controlRequest("/api/v1/me", { headers: { cookie: login.sessionCookie } }));
19 const me = MeResponseSchema.parse(await meResponse.json());
20 const patResponse = await fetchWorker(
21 controlRequest("/api/v1/pats", {
22 method: "POST",
23 headers: {
24 cookie: login.sessionCookie,
25 origin: "https://dav.example.com",
26 "content-type": "application/json",
27 },
28 body: JSON.stringify({ name: "dav fixture", scopes }),
29 }),
30 );
31 const pat = PatCreateResponseSchema.parse(await patResponse.json());
32 return { subjectId: me.subject_id, hostLabel: me.host_label, token: pat.token, authHeader: basicPat(pat.token) };
33}
34 
35export function davRequest(fixture: DavFixture, path: string, init: RequestInit = {}): Request {
36 const headers = new Headers(init.headers);
37 headers.set("authorization", fixture.authHeader);
38 // PUTs against CalDAV/CardDAV object URIs need an explicit media type; real
39 // clients always send one. Default it here so individual tests don't have to.
40 if ((init.method ?? "GET").toUpperCase() === "PUT" && !headers.has("content-type")) {
41 if (path.startsWith("/calendars/") && /\.ics$/.test(path)) {
42 headers.set("content-type", "text/calendar; charset=utf-8");
43 } else if (path.startsWith("/addressbooks/") && /\.vcf$/.test(path)) {
44 headers.set("content-type", "text/vcard; charset=utf-8");
45 }
46 }
47 return subjectRequest(fixture.hostLabel, path, { ...init, headers });
48}