feat: admin controls

This commit is contained in:
Zoe
2026-10-15 10:07:41 -05:00
parent b6f4d85ed7
commit ff7797d3f8
41 changed files with 612 additions and 427 deletions
+4 -1
View File
@@ -1,7 +1,8 @@
import { createHash, randomBytes } from 'node:crypto';
import { and, eq, gt, lte, sql } from 'drizzle-orm';
import { and, eq, gt, lte } from 'drizzle-orm';
import { accounts, recoveryLinks, users } from '~~/drizzle/schema';
import { db } from '~~/server/lib/db';
import { lockAccount } from "~~/server/lib/account-security";
export const RECOVERY_LINK_LIFETIME_MS = 24 * 60 * 60 * 1000;
// a new person may take a while to get round to it
@@ -36,7 +37,9 @@ export const createRecoveryLink = async (userId: string, resetSecurity: boolean)
const expiresAt = new Date(Date.now() + lifetime);
await db.transaction(async (tx) => {
await lockAccount(tx, userId);
await tx.delete(recoveryLinks).where(eq(recoveryLinks.userId, userId));
// nothing else ever looks at a link that ran out, so they go here
await tx.delete(recoveryLinks).where(lte(recoveryLinks.expiresAt, new Date()));
await tx.insert(recoveryLinks).values({
tokenHash: hashRecoveryToken(token),