import { Hono } from "hono"; import { MeResponseSchema } from "@/worker/openapi/schemas"; import { describeJson } from "@/worker/routes/api/openapi"; import { subjectForSession } from "@/worker/routes/api/session"; import type { AppContext, AppEnv } from "@/worker/types"; function controlPlaneBaseUrl(c: AppContext): URL { const url = new URL(c.req.url); url.pathname = "/"; url.search = ""; url.hash = ""; return url; } export async function meBody(c: AppContext) { const subject = await subjectForSession(c); if (!subject) throw new Error("Authenticated subject not found"); const base = controlPlaneBaseUrl(c); const protocol = base.protocol; const controlHost = c.env.CONTROL_PLANE_HOST; const davHost = `${subject.hostLabel}${c.env.SUBJECT_HOST_SUFFIX}`; return { subject_id: subject.id, host_label: subject.hostLabel, control_plane_host: controlHost, dav_host: davHost, urls: { api: `${protocol}//${controlHost}/api/v1/`, root: `${protocol}//${davHost}/`, files: `${protocol}//${davHost}/files/`, caldav: `${protocol}//${davHost}/calendars/`, carddav: `${protocol}//${davHost}/addressbooks/`, }, }; } export function createMeApiRoutes(): Hono { const api = new Hono(); api.get("/", describeJson("Get current subject metadata", "me", MeResponseSchema), async (c) => c.json(await meBody(c)), ); return api; }