36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
import { useMemo } from 'react';
|
|
|
|
type RateBucket = 'coupon' | 'voucher';
|
|
|
|
export function useRateLimitHelper(bucket: RateBucket) {
|
|
return useMemo(() => {
|
|
const key = (code: string) => `${bucket}:${code.toUpperCase()}`;
|
|
|
|
return {
|
|
isLimited: (code: string): boolean => {
|
|
const item = localStorage.getItem(key(code));
|
|
if (!item) return false;
|
|
const parsed = JSON.parse(item) as { attempts: number; ts: number };
|
|
const ageSeconds = (Date.now() - parsed.ts) / 1000;
|
|
if (ageSeconds > 300) {
|
|
localStorage.removeItem(key(code));
|
|
return false;
|
|
}
|
|
return parsed.attempts >= 3;
|
|
},
|
|
bump: (code: string): void => {
|
|
const item = localStorage.getItem(key(code));
|
|
if (!item) {
|
|
localStorage.setItem(key(code), JSON.stringify({ attempts: 1, ts: Date.now() }));
|
|
return;
|
|
}
|
|
const parsed = JSON.parse(item) as { attempts: number; ts: number };
|
|
localStorage.setItem(key(code), JSON.stringify({ attempts: (parsed.attempts || 0) + 1, ts: Date.now() }));
|
|
},
|
|
clear: (code: string): void => {
|
|
localStorage.removeItem(key(code));
|
|
},
|
|
};
|
|
}, [bucket]);
|
|
}
|