File
Blob: src/worker/db/auth-do/repository.ts
| 1 | import { desc, eq } from "drizzle-orm"; |
| 2 | |
| 3 | import type { DavScope } from "@/worker/db/types"; |
| 4 | |
| 5 | import type { AuthDoDb } from "./client"; |
| 6 | import { authEvents, pats, sessions, type NewPatRow, type NewSessionRow, type PatRow, type SessionRow } from "./schema"; |
| 7 | |
| 8 | export interface PatPatch { |
| 9 | name?: string; |
| 10 | scopes?: DavScope[]; |
| 11 | expiresAtMs?: number | null; |
| 12 | revokedAtMs?: number | null; |
| 13 | lastUsedAtMs?: number | null; |
| 14 | } |
| 15 | |
| 16 | export function createSession(db: AuthDoDb, row: NewSessionRow): void { |
| 17 | db.insert(sessions).values(row).run(); |
| 18 | } |
| 19 | |
| 20 | export function getSession(db: AuthDoDb, sessionId: string): SessionRow | undefined { |
| 21 | return db.query.sessions.findFirst({ where: eq(sessions.id, sessionId) }).sync(); |
| 22 | } |
| 23 | |
| 24 | export function touchSession(db: AuthDoDb, sessionId: string, nowMs: number): void { |
| 25 | db.update(sessions).set({ lastUsedAtMs: nowMs }).where(eq(sessions.id, sessionId)).run(); |
| 26 | } |
| 27 | |
| 28 | export function revokeSession(db: AuthDoDb, sessionId: string, nowMs: number): void { |
| 29 | db.update(sessions).set({ revokedAtMs: nowMs }).where(eq(sessions.id, sessionId)).run(); |
| 30 | } |
| 31 | |
| 32 | export function createPat(db: AuthDoDb, row: NewPatRow): void { |
| 33 | db.insert(pats).values(row).run(); |
| 34 | } |
| 35 | |
| 36 | export function listPats(db: AuthDoDb): PatRow[] { |
| 37 | return db.select().from(pats).orderBy(desc(pats.createdAtMs)).all(); |
| 38 | } |
| 39 | |
| 40 | export function getPat(db: AuthDoDb, patId: string): PatRow | undefined { |
| 41 | return db.query.pats.findFirst({ where: eq(pats.id, patId) }).sync(); |
| 42 | } |
| 43 | |
| 44 | export function updatePat(db: AuthDoDb, patId: string, patch: PatPatch): PatRow | undefined { |
| 45 | const existing = getPat(db, patId); |
| 46 | if (!existing) return undefined; |
| 47 | |
| 48 | db.update(pats) |
| 49 | .set({ |
| 50 | name: patch.name ?? existing.name, |
| 51 | scopes: patch.scopes ?? existing.scopes, |
| 52 | expiresAtMs: patch.expiresAtMs === undefined ? existing.expiresAtMs : patch.expiresAtMs, |
| 53 | revokedAtMs: patch.revokedAtMs === undefined ? existing.revokedAtMs : patch.revokedAtMs, |
| 54 | lastUsedAtMs: patch.lastUsedAtMs === undefined ? existing.lastUsedAtMs : patch.lastUsedAtMs, |
| 55 | }) |
| 56 | .where(eq(pats.id, patId)) |
| 57 | .run(); |
| 58 | |
| 59 | return getPat(db, patId); |
| 60 | } |
| 61 | |
| 62 | export function recordAuthEvent( |
| 63 | db: AuthDoDb, |
| 64 | input: { id: string; eventType: string; createdAtMs: number; data: Record<string, unknown> }, |
| 65 | ): void { |
| 66 | db.insert(authEvents).values(input).run(); |
| 67 | } |