Files
Termix/src/backend/database/repositories/webauthn-credential-repository.ts
T

89 lines
2.2 KiB
TypeScript
Raw Normal View History

+8
2026-07-19 12:29:52 -05:00
import { and, eq } from "drizzle-orm";
import { webauthnCredentials } from "../db/schema.js";
import type { DatabaseContext } from "./database-context.js";
+3
2026-08-06 14:41:39 -05:00
import { rowsAffected } from "./mutation-result.js";
import { insertReturning } from "./returning.js";
+8
2026-07-19 12:29:52 -05:00
export type WebauthnCredentialRecord = typeof webauthnCredentials.$inferSelect;
export type NewWebauthnCredentialRecord =
typeof webauthnCredentials.$inferInsert;
export interface WebauthnCredentialAuthState {
counter: number;
backedUp: boolean;
deviceType: string | null;
lastUsedAt: string;
}
export class WebauthnCredentialRepository {
constructor(
private readonly context: DatabaseContext,
private readonly onWrite?: () => void | Promise<void>,
) {}
async listByUserId(userId: string): Promise<WebauthnCredentialRecord[]> {
return this.context.drizzle
.select()
.from(webauthnCredentials)
.where(eq(webauthnCredentials.userId, userId));
}
async findByCredentialId(
credentialId: string,
): Promise<WebauthnCredentialRecord | null> {
const rows = await this.context.drizzle
.select()
.from(webauthnCredentials)
.where(eq(webauthnCredentials.credentialId, credentialId))
.limit(1);
return rows[0] ?? null;
}
async create(
record: NewWebauthnCredentialRecord,
): Promise<WebauthnCredentialRecord> {
+3
2026-08-06 14:41:39 -05:00
const rows = await insertReturning(
this.context,
webauthnCredentials,
record,
);
+8
2026-07-19 12:29:52 -05:00
await this.afterWrite();
return rows[0];
}
async updateAuthState(
id: string,
state: WebauthnCredentialAuthState,
): Promise<void> {
await this.context.drizzle
.update(webauthnCredentials)
.set(state)
.where(eq(webauthnCredentials.id, id));
await this.afterWrite();
}
async deleteForUser(userId: string, id: string): Promise<boolean> {
+3
2026-08-06 14:41:39 -05:00
const result = await this.context.drizzle
+8
2026-07-19 12:29:52 -05:00
.delete(webauthnCredentials)
.where(
and(
eq(webauthnCredentials.id, id),
eq(webauthnCredentials.userId, userId),
),
+3
2026-08-06 14:41:39 -05:00
);
+8
2026-07-19 12:29:52 -05:00
+3
2026-08-06 14:41:39 -05:00
if (rowsAffected(result) > 0) {
+8
2026-07-19 12:29:52 -05:00
await this.afterWrite();
}
+3
2026-08-06 14:41:39 -05:00
return rowsAffected(result) > 0;
+8
2026-07-19 12:29:52 -05:00
}
private async afterWrite(): Promise<void> {
await this.onWrite?.();
}
}