import { randomHex } from "@/worker/auth/bytes"; import { apiSessionTtlMs, clearSessionCookie, getSessionCookie, setSessionCookie } from "@/worker/auth/cookies"; import { createControlPlaneDb } from "@/worker/db/d1/client"; import { getSubjectById } from "@/worker/db/d1/repository"; import type { AuthObject } from "@/worker/objects/auth-object"; import type { AppContext, AuthenticatedSession } from "@/worker/types"; export function authObject(env: Env, storageId: string): DurableObjectStub { return env.AUTH.getByName(storageId); } export async function createApiSession( c: AppContext, subject: { id: string; storageId: string }, nowMs = Date.now(), ): Promise { const sessionId = `ses_${randomHex(32)}`; const expiresAtMs = nowMs + apiSessionTtlMs; await authObject(c.env, subject.storageId).createSession({ id: sessionId, createdAtMs: nowMs, expiresAtMs, revokedAtMs: null, lastUsedAtMs: nowMs, }); await setSessionCookie(c, { subjectId: subject.id, storageId: subject.storageId, sessionId, createdAtMs: nowMs, expiresAtMs, }); return { subjectId: subject.id, storageId: subject.storageId, sessionId }; } export async function readApiSession(c: AppContext, nowMs = Date.now()): Promise { const cookie = await getSessionCookie(c); if (!cookie || cookie.expiresAtMs <= nowMs) return null; const subject = await getSubjectById(createControlPlaneDb(c.env.DAV_CONTROL_PLANE), cookie.subjectId); if (!subject || subject.storageId !== cookie.storageId || subject.disabledAtMs !== null) return null; const result = await authObject(c.env, cookie.storageId).validateSession({ sessionId: cookie.sessionId, nowMs }); if (!result.ok) return null; return { subjectId: cookie.subjectId, storageId: cookie.storageId, sessionId: cookie.sessionId }; } export async function revokeApiSession( c: AppContext, session: AuthenticatedSession, nowMs = Date.now(), ): Promise { await authObject(c.env, session.storageId).revokeSession({ sessionId: session.sessionId, nowMs }); clearSessionCookie(c); }