Skip to content
File

Blob: src/worker/dav/areas.ts

typescript74 lines
1import { hasDavScope } from "@/worker/auth/scopes";
2import { CAL_DAV_ALLOW, CAL_DAV_OPTIONS_HEADERS, handleCalDav } from "@/worker/caldav/handler";
3import { CARD_DAV_ALLOW, CARD_DAV_OPTIONS_HEADERS, handleCardDav } from "@/worker/carddav/handler";
4import { DAV_DISCOVERY_ALLOW, handleDavDiscovery, isDavDiscoveryPath } from "@/worker/dav/discovery";
5import type { DavArea } from "@/worker/dav/runtime";
6import { hasFilesScope, requiresFileWrite } from "@/worker/webdav/access";
7import { FILES_DAV_ALLOW, FILES_DAV_OPTIONS_HEADERS } from "@/worker/webdav/constants";
8import { handleWebDavFiles } from "@/worker/webdav/handler";
9 
10export function isFileDavPath(pathname: string): boolean {
11 return pathname === "/files" || pathname.startsWith("/files/");
12}
13 
14export function isCalDavPath(pathname: string): boolean {
15 return pathname === "/calendars" || pathname.startsWith("/calendars/");
16}
17 
18export function isCardDavPath(pathname: string): boolean {
19 return pathname === "/addressbooks" || pathname.startsWith("/addressbooks/");
20}
21 
22function requiresCalDavWrite(method: string): boolean {
23 return (
24 method === "PUT" || method === "DELETE" || method === "PROPPATCH" || method === "MKCALENDAR" || method === "MKCOL"
25 );
26}
27 
28function requiresCardDavWrite(method: string): boolean {
29 return method === "PUT" || method === "DELETE" || method === "PROPPATCH";
30}
31 
32export const filesDavArea: DavArea = {
33 name: "files",
34 allow: FILES_DAV_ALLOW,
35 optionsHeaders: FILES_DAV_OPTIONS_HEADERS,
36 matches: isFileDavPath,
37 canUseMethod: (auth, method) =>
38 requiresFileWrite(method)
39 ? hasFilesScope(auth.scopes, "dav:files:write")
40 : hasFilesScope(auth.scopes, "dav:files:read"),
41 handle: ({ c, subject, auth }) => handleWebDavFiles(c, subject, auth),
42};
43 
44export const calDavArea: DavArea = {
45 name: "caldav",
46 allow: CAL_DAV_ALLOW,
47 optionsHeaders: CAL_DAV_OPTIONS_HEADERS,
48 matches: isCalDavPath,
49 canUseMethod: (auth, method) =>
50 hasDavScope(auth.scopes, requiresCalDavWrite(method) ? "dav:caldav:write" : "dav:caldav:read"),
51 handle: ({ c, subject, auth }) => handleCalDav(c, subject, auth),
52};
53 
54export const cardDavArea: DavArea = {
55 name: "carddav",
56 allow: CARD_DAV_ALLOW,
57 optionsHeaders: CARD_DAV_OPTIONS_HEADERS,
58 matches: isCardDavPath,
59 canUseMethod: (auth, method) =>
60 hasDavScope(auth.scopes, requiresCardDavWrite(method) ? "dav:carddav:write" : "dav:carddav:read"),
61 handle: ({ c, subject, auth }) => handleCardDav(c, subject, auth),
62};
63 
64export const discoveryDavArea: DavArea = {
65 name: "discovery",
66 allow: DAV_DISCOVERY_ALLOW,
67 optionsHeaders: { Allow: DAV_DISCOVERY_ALLOW, DAV: "1" },
68 matches: isDavDiscoveryPath,
69 canUseMethod: () => true,
70 handle: ({ c, subject, auth }) => handleDavDiscovery(c, subject, auth),
71};
72 
73export const DAV_AREAS = [filesDavArea, calDavArea, cardDavArea, discoveryDavArea] as const;