import { desc, eq } from "drizzle-orm"; import type { DavScope } from "@/worker/db/types"; import type { AuthDoDb } from "./client"; import { authEvents, pats, sessions, type NewPatRow, type NewSessionRow, type PatRow, type SessionRow } from "./schema"; export interface PatPatch { name?: string; scopes?: DavScope[]; expiresAtMs?: number | null; revokedAtMs?: number | null; lastUsedAtMs?: number | null; } export function createSession(db: AuthDoDb, row: NewSessionRow): void { db.insert(sessions).values(row).run(); } export function getSession(db: AuthDoDb, sessionId: string): SessionRow | undefined { return db.query.sessions.findFirst({ where: eq(sessions.id, sessionId) }).sync(); } export function touchSession(db: AuthDoDb, sessionId: string, nowMs: number): void { db.update(sessions).set({ lastUsedAtMs: nowMs }).where(eq(sessions.id, sessionId)).run(); } export function revokeSession(db: AuthDoDb, sessionId: string, nowMs: number): void { db.update(sessions).set({ revokedAtMs: nowMs }).where(eq(sessions.id, sessionId)).run(); } export function createPat(db: AuthDoDb, row: NewPatRow): void { db.insert(pats).values(row).run(); } export function listPats(db: AuthDoDb): PatRow[] { return db.select().from(pats).orderBy(desc(pats.createdAtMs)).all(); } export function getPat(db: AuthDoDb, patId: string): PatRow | undefined { return db.query.pats.findFirst({ where: eq(pats.id, patId) }).sync(); } export function updatePat(db: AuthDoDb, patId: string, patch: PatPatch): PatRow | undefined { const existing = getPat(db, patId); if (!existing) return undefined; db.update(pats) .set({ name: patch.name ?? existing.name, scopes: patch.scopes ?? existing.scopes, expiresAtMs: patch.expiresAtMs === undefined ? existing.expiresAtMs : patch.expiresAtMs, revokedAtMs: patch.revokedAtMs === undefined ? existing.revokedAtMs : patch.revokedAtMs, lastUsedAtMs: patch.lastUsedAtMs === undefined ? existing.lastUsedAtMs : patch.lastUsedAtMs, }) .where(eq(pats.id, patId)) .run(); return getPat(db, patId); } export function recordAuthEvent( db: AuthDoDb, input: { id: string; eventType: string; createdAtMs: number; data: Record }, ): void { db.insert(authEvents).values(input).run(); }