fix(2FA): cast transaction return to match return type

This commit is contained in:
Rudy B. committed 2026-04-25 17:57:45 +02:00
1 parent fc32e39ac0
commit 3f8b3e8aee
1 file changed
+9 -4
+9 -4
View File
@@ -16,12 +16,17 @@ export async function checkRateLimit(
return { allowed: true }; return { allowed: true };
} }
export async function recordFailedAttempt(userId: string) { export async function recordFailedAttempt(userId: string): Promise<{ lockedUntil?: Date }> {
let retries = 0; let retries = 0;
while (retries < MAX_RETRIES) { while (retries < MAX_RETRIES) {
try { try {
return await prisma.transaction( /*
async (tx: Prisma.TransactionClient) => { prisma.transaction accepts `any` to support both batch and callback forms,
so TypeScript resolves to the batch overload and infers `any[]`. Cast is safe:
the callback form always returns the callback's return type.
*/
return await (prisma.transaction(
async (tx: Prisma.TransactionClient): Promise<{ lockedUntil?: Date }> => {
const record = await tx.twoFactorRateLimit.upsert({ const record = await tx.twoFactorRateLimit.upsert({
where: { userId }, where: { userId },
update: { attempts: { increment: 1 } }, update: { attempts: { increment: 1 } },
@@ -35,7 +40,7 @@ export async function recordFailedAttempt(userId: string) {
return {}; return {};
}, },
{ isolationLevel: Prisma.TransactionIsolationLevel.Serializable }, { isolationLevel: Prisma.TransactionIsolationLevel.Serializable },
); ) as Promise<{ lockedUntil?: Date }>);
} catch (err: any) { } catch (err: any) {
if (err.code === 'P2034') { if (err.code === 'P2034') {
retries++; retries++;