import { digestPat, parseBasicAuth, parsePat } from "@/worker/auth/pats"; import { createControlPlaneDb } from "@/worker/db/d1/client"; import { updatePatProjection } from "@/worker/db/d1/repository"; import type { SubjectRow } from "@/worker/db/d1/schema"; import type { DavScope } from "@/worker/db/types"; import { authObject } from "@/worker/auth/session-cookie"; export interface DavPatAuth { subjectId: string; storageId: string; hostLabel: string; patId: string; scopes: DavScope[]; } export async function authenticateDavPat( env: Env, request: Request, subject: SubjectRow, nowMs = Date.now(), ): Promise { if (subject.disabledAtMs !== null) return null; const credentials = parseBasicAuth(request.headers.get("authorization")); if (!credentials) return null; const parsedPat = parsePat(credentials.password); if (!parsedPat) return null; const digest = await digestPat(credentials.password); if (!digest) return null; const result = await authObject(env, subject.storageId).verifyPat({ patId: parsedPat.id, tokenDigest: digest, nowMs, }); if (!result.ok) return null; await updatePatProjection(createControlPlaneDb(env.DAV_CONTROL_PLANE), subject.id, parsedPat.id, { lastUsedAtMs: nowMs, }); return { subjectId: subject.id, storageId: subject.storageId, hostLabel: subject.hostLabel, patId: result.pat.id, scopes: result.pat.scopes, }; }