12345678910111213141516171819// In-database layered OTP verification & brute-force invalidation via Prisma
export async function verifyOtpInternal(phone: string, code: string): Promise<boolean> {
const record = await prisma.otpRecord.findFirst({
where: { phone: phone.trim(), used: false, expiresAt: { gt: new Date() } },
orderBy: { createdAt: 'desc' },
});
if (!record || record.attempts >= 5) return false;
if (record.code === code) {
await prisma.otpRecord.update({ where: { id: record.id }, data: { used: true } });
return true;
}
const nextAttempts = record.attempts + 1;
await prisma.otpRecord.update({
where: { id: record.id },
data: { attempts: nextAttempts, used: nextAttempts >= 5 }, // Invalidate on 5th failed try
});
return false;
}