Skip to content
File

Blob: src/worker/db/auth-do/repository.ts

typescript68 lines
1import { desc, eq } from "drizzle-orm";
2 
3import type { DavScope } from "@/worker/db/types";
4 
5import type { AuthDoDb } from "./client";
6import { authEvents, pats, sessions, type NewPatRow, type NewSessionRow, type PatRow, type SessionRow } from "./schema";
7 
8export interface PatPatch {
9 name?: string;
10 scopes?: DavScope[];
11 expiresAtMs?: number | null;
12 revokedAtMs?: number | null;
13 lastUsedAtMs?: number | null;
14}
15 
16export function createSession(db: AuthDoDb, row: NewSessionRow): void {
17 db.insert(sessions).values(row).run();
18}
19 
20export function getSession(db: AuthDoDb, sessionId: string): SessionRow | undefined {
21 return db.query.sessions.findFirst({ where: eq(sessions.id, sessionId) }).sync();
22}
23 
24export function touchSession(db: AuthDoDb, sessionId: string, nowMs: number): void {
25 db.update(sessions).set({ lastUsedAtMs: nowMs }).where(eq(sessions.id, sessionId)).run();
26}
27 
28export function revokeSession(db: AuthDoDb, sessionId: string, nowMs: number): void {
29 db.update(sessions).set({ revokedAtMs: nowMs }).where(eq(sessions.id, sessionId)).run();
30}
31 
32export function createPat(db: AuthDoDb, row: NewPatRow): void {
33 db.insert(pats).values(row).run();
34}
35 
36export function listPats(db: AuthDoDb): PatRow[] {
37 return db.select().from(pats).orderBy(desc(pats.createdAtMs)).all();
38}
39 
40export function getPat(db: AuthDoDb, patId: string): PatRow | undefined {
41 return db.query.pats.findFirst({ where: eq(pats.id, patId) }).sync();
42}
43 
44export 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 
62export 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}