| import { loadEncryptedJson, saveEncryptedJson } from './cryptoUtils.js'; |
|
|
| const REQUESTS_FILE = '/data/guest_request_counts.json'; |
| const WINDOW_MS = 24 * 60 * 60 * 1000; |
| const MAX_LOGGED_OUT_REQUESTS = 50; |
|
|
| const ipCounters = new Map(); |
| let loaded = false; |
|
|
| async function loadGuestCounters() { |
| if (loaded) return; |
| loaded = true; |
| const data = await loadEncryptedJson(REQUESTS_FILE); |
| if (!data) return; |
| for (const [ip, entry] of Object.entries(data)) { |
| ipCounters.set(ip, { |
| count: typeof entry.count === 'number' ? entry.count : 0, |
| resetAt: typeof entry.resetAt === 'number' ? entry.resetAt : Date.now() + WINDOW_MS, |
| }); |
| } |
| } |
|
|
| async function saveGuestCounters() { |
| const data = {}; |
| for (const [ip, entry] of ipCounters) { |
| data[ip] = { count: entry.count, resetAt: entry.resetAt }; |
| } |
| await saveEncryptedJson(REQUESTS_FILE, data); |
| } |
|
|
| function cleanupExpired() { |
| const now = Date.now(); |
| for (const [ip, entry] of ipCounters) { |
| if (entry.resetAt <= now) { |
| ipCounters.delete(ip); |
| } |
| } |
| } |
|
|
| export async function initGuestRequestLimiter() { |
| await loadGuestCounters().catch(err => console.error('Failed to load guest request counters:', err)); |
| cleanupExpired(); |
| setInterval(() => { |
| cleanupExpired(); |
| }, 60 * 60 * 1000); |
| } |
|
|
| export async function consumeGuestRequest(ip) { |
| await loadGuestCounters(); |
| const now = Date.now(); |
| let entry = ipCounters.get(ip); |
| if (!entry || entry.resetAt <= now) { |
| entry = { count: 0, resetAt: now + WINDOW_MS }; |
| ipCounters.set(ip, entry); |
| } |
| if (entry.count >= MAX_LOGGED_OUT_REQUESTS) { |
| return false; |
| } |
| entry.count += 1; |
| await saveGuestCounters().catch(err => console.error('Failed to save guest request counters:', err)); |
| return true; |
| } |
|
|
| export function getGuestRequestsRemaining(ip) { |
| const now = Date.now(); |
| const entry = ipCounters.get(ip); |
| if (!entry || entry.resetAt <= now) return MAX_LOGGED_OUT_REQUESTS; |
| return Math.max(0, MAX_LOGGED_OUT_REQUESTS - entry.count); |
| } |
|
|