← back to Dw Signup Fulfillment

lib/rate-limit.js

24 lines

'use strict';
// Shared in-memory per-key sliding-window rate limiter. Used by BOTH the
// customers/create webhook and the public /trade/apply intake so the two throttle
// consistently (extracted from the inline webhook limiter, TK-11185). Each caller
// gets its own bucket via a separate factory instance, so buckets never cross.
//
// limited(key) records `now`, prunes timestamps older than windowMs, and returns true
// once the key has exceeded `max` hits inside the window. The map self-prunes stale
// keys once it grows past mapMaxEntries so it can't leak memory under a spray of IPs.
function createRateLimiter({ windowMs, max, mapMaxEntries = 5000 }) {
  const hits = new Map(); // key -> [timestamps(ms)]
  return function limited(key) {
    const k = key || '';
    const now = Date.now();
    const arr = (hits.get(k) || []).filter(t => now - t < windowMs);
    arr.push(now);
    hits.set(k, arr);
    if (hits.size > mapMaxEntries) for (const [kk, v] of hits) if (!v.some(t => now - t < windowMs)) hits.delete(kk);
    return arr.length > max;
  };
}

module.exports = { createRateLimiter };