import { hasDavScope } from "@/worker/auth/scopes"; import { CAL_DAV_ALLOW, CAL_DAV_OPTIONS_HEADERS, handleCalDav } from "@/worker/caldav/handler"; import { CARD_DAV_ALLOW, CARD_DAV_OPTIONS_HEADERS, handleCardDav } from "@/worker/carddav/handler"; import { DAV_DISCOVERY_ALLOW, handleDavDiscovery, isDavDiscoveryPath } from "@/worker/dav/discovery"; import type { DavArea } from "@/worker/dav/runtime"; import { hasFilesScope, requiresFileWrite } from "@/worker/webdav/access"; import { FILES_DAV_ALLOW, FILES_DAV_OPTIONS_HEADERS } from "@/worker/webdav/constants"; import { handleWebDavFiles } from "@/worker/webdav/handler"; export function isFileDavPath(pathname: string): boolean { return pathname === "/files" || pathname.startsWith("/files/"); } export function isCalDavPath(pathname: string): boolean { return pathname === "/calendars" || pathname.startsWith("/calendars/"); } export function isCardDavPath(pathname: string): boolean { return pathname === "/addressbooks" || pathname.startsWith("/addressbooks/"); } function requiresCalDavWrite(method: string): boolean { return ( method === "PUT" || method === "DELETE" || method === "PROPPATCH" || method === "MKCALENDAR" || method === "MKCOL" ); } function requiresCardDavWrite(method: string): boolean { return method === "PUT" || method === "DELETE" || method === "PROPPATCH"; } export const filesDavArea: DavArea = { name: "files", allow: FILES_DAV_ALLOW, optionsHeaders: FILES_DAV_OPTIONS_HEADERS, matches: isFileDavPath, canUseMethod: (auth, method) => requiresFileWrite(method) ? hasFilesScope(auth.scopes, "dav:files:write") : hasFilesScope(auth.scopes, "dav:files:read"), handle: ({ c, subject, auth }) => handleWebDavFiles(c, subject, auth), }; export const calDavArea: DavArea = { name: "caldav", allow: CAL_DAV_ALLOW, optionsHeaders: CAL_DAV_OPTIONS_HEADERS, matches: isCalDavPath, canUseMethod: (auth, method) => hasDavScope(auth.scopes, requiresCalDavWrite(method) ? "dav:caldav:write" : "dav:caldav:read"), handle: ({ c, subject, auth }) => handleCalDav(c, subject, auth), }; export const cardDavArea: DavArea = { name: "carddav", allow: CARD_DAV_ALLOW, optionsHeaders: CARD_DAV_OPTIONS_HEADERS, matches: isCardDavPath, canUseMethod: (auth, method) => hasDavScope(auth.scopes, requiresCardDavWrite(method) ? "dav:carddav:write" : "dav:carddav:read"), handle: ({ c, subject, auth }) => handleCardDav(c, subject, auth), }; export const discoveryDavArea: DavArea = { name: "discovery", allow: DAV_DISCOVERY_ALLOW, optionsHeaders: { Allow: DAV_DISCOVERY_ALLOW, DAV: "1" }, matches: isDavDiscoveryPath, canUseMethod: () => true, handle: ({ c, subject, auth }) => handleDavDiscovery(c, subject, auth), }; export const DAV_AREAS = [filesDavArea, calDavArea, cardDavArea, discoveryDavArea] as const;