import { generatePat, normalizeScopes } from "@/worker/auth/pats"; import { authObject } from "@/worker/auth/session-cookie"; import { createControlPlaneDb } from "@/worker/db/d1/client"; import { bootstrapSubject, createPatProjection } from "@/worker/db/d1/repository"; import type { AppContext } from "@/worker/types"; type DavFixtureInput = { sub: string; email: string; displayName: string; scopes: string[]; patName: string; path: "/files/" | "/calendars/"; storage: "files" | "calendars"; }; function fixturesEnabled(env: Env): boolean { return (env as unknown as Record).DAB_ENABLE_TEST_FIXTURES === "1"; } function fixtureInput(fixture: string): DavFixtureInput | null { switch (fixture) { case "litmus": return { sub: "litmus-subject", email: "litmus@example.test", displayName: "litmus", scopes: ["files.full"], patName: "litmus", path: "/files/", storage: "files", }; case "caldav": return { sub: "caldav-tester-subject", email: "caldav-tester@example.test", displayName: "caldav tester", scopes: ["caldav.full"], patName: "caldav tester", path: "/calendars/", storage: "calendars", }; default: return null; } } async function createDavFixture(c: AppContext, input: DavFixtureInput) { if (!fixturesEnabled(c.env) || c.get("hostInfo").kind !== "control") return c.notFound(); const nowMs = Date.now(); const { subject } = await bootstrapSubject( createControlPlaneDb(c.env.DAV_CONTROL_PLANE), { sub: input.sub, email: input.email, displayName: input.displayName, }, nowMs, ); if (input.storage === "files") { await c.env.FILE_DAV.getByName(subject.storageId).ensureInitialized({ subjectId: subject.id, storageId: subject.storageId, nowMs, }); } else { await c.env.CAL_DAV.getByName(subject.storageId).ensureInitialized({ subjectId: subject.id, nowMs, }); } const scopes = normalizeScopes(input.scopes); if (!scopes) return c.json({ error: "invalid_scopes" }, 500); const generated = await generatePat(); const pat = await authObject(c.env, subject.storageId).createPat({ id: generated.id, name: input.patName, tokenDigest: generated.tokenDigest, scopes, createdAtMs: nowMs, expiresAtMs: null, revokedAtMs: null, lastUsedAtMs: null, }); await createPatProjection(createControlPlaneDb(c.env.DAV_CONTROL_PLANE), { id: pat.id, subjectId: subject.id, name: pat.name, scopes: pat.scopes, createdAtMs: pat.createdAtMs, expiresAtMs: pat.expiresAtMs, revokedAtMs: pat.revokedAtMs, lastUsedAtMs: pat.lastUsedAtMs, }); const requestUrl = new URL(c.req.url); const port = requestUrl.port ? `:${requestUrl.port}` : ""; const davHost = `${subject.hostLabel}${c.env.SUBJECT_HOST_SUFFIX}`; return c.json({ url: `${requestUrl.protocol}//${davHost}${port}${input.path}`, username: subject.hostLabel, pat: generated.token, subject_id: subject.id, host_label: subject.hostLabel, }); } export async function handleTestFixtureRequest(c: AppContext): Promise { const fixture = c.req.param("fixture"); if (!fixture) return c.notFound(); const input = fixtureInput(fixture); if (!input) return c.notFound(); return await createDavFixture(c, input); }