File size: 2,005 Bytes
8dde1b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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);
}