Skip to content
File

Blob: src/worker/auth/session-cookie.ts

typescript57 lines
1import { randomHex } from "@/worker/auth/bytes";
2import { apiSessionTtlMs, clearSessionCookie, getSessionCookie, setSessionCookie } from "@/worker/auth/cookies";
3import { createControlPlaneDb } from "@/worker/db/d1/client";
4import { getSubjectById } from "@/worker/db/d1/repository";
5import type { AuthObject } from "@/worker/objects/auth-object";
6import type { AppContext, AuthenticatedSession } from "@/worker/types";
7 
8export function authObject(env: Env, storageId: string): DurableObjectStub<AuthObject> {
9 return env.AUTH.getByName(storageId);
10}
11 
12export async function createApiSession(
13 c: AppContext,
14 subject: { id: string; storageId: string },
15 nowMs = Date.now(),
16): Promise<AuthenticatedSession> {
17 const sessionId = `ses_${randomHex(32)}`;
18 const expiresAtMs = nowMs + apiSessionTtlMs;
19 await authObject(c.env, subject.storageId).createSession({
20 id: sessionId,
21 createdAtMs: nowMs,
22 expiresAtMs,
23 revokedAtMs: null,
24 lastUsedAtMs: nowMs,
25 });
26 await setSessionCookie(c, {
27 subjectId: subject.id,
28 storageId: subject.storageId,
29 sessionId,
30 createdAtMs: nowMs,
31 expiresAtMs,
32 });
33 return { subjectId: subject.id, storageId: subject.storageId, sessionId };
34}
35 
36export async function readApiSession(c: AppContext, nowMs = Date.now()): Promise<AuthenticatedSession | null> {
37 const cookie = await getSessionCookie(c);
38 if (!cookie || cookie.expiresAtMs <= nowMs) return null;
39 
40 const subject = await getSubjectById(createControlPlaneDb(c.env.DAV_CONTROL_PLANE), cookie.subjectId);
41 if (!subject || subject.storageId !== cookie.storageId || subject.disabledAtMs !== null) return null;
42 
43 const result = await authObject(c.env, cookie.storageId).validateSession({ sessionId: cookie.sessionId, nowMs });
44 if (!result.ok) return null;
45 
46 return { subjectId: cookie.subjectId, storageId: cookie.storageId, sessionId: cookie.sessionId };
47}
48 
49export async function revokeApiSession(
50 c: AppContext,
51 session: AuthenticatedSession,
52 nowMs = Date.now(),
53): Promise<void> {
54 await authObject(c.env, session.storageId).revokeSession({ sessionId: session.sessionId, nowMs });
55 clearSessionCookie(c);
56}