Spreadsheet-UX op een echte relationele engine

main

Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.

1.3 kB Ruw bestand
/**
 * Login and signup throttling, keyed by email and by client address.
 *
 * In-memory on purpose: it protects a single process against online guessing
 * and resets on restart. Anything stronger belongs at the reverse proxy.
 */
export class LoginThrottle {
  private readonly hits = new Map<string, { count: number; first: number; until: number }>();

  constructor(
    private readonly limit = 8,
    private readonly windowMs = 5 * 60_000,
    private readonly lockoutMs = 15 * 60_000,
  ) {}

  /** Milliseconds the caller must wait, or 0 when the attempt may proceed. */
  check(key: string): number {
    const entry = this.hits.get(key);
    if (!entry) return 0;
    const now = Date.now();
    if (entry.until > now) return entry.until - now;
    if (now - entry.first > this.windowMs) {
      this.hits.delete(key);
      return 0;
    }
    return 0;
  }

  fail(key: string): void {
    const now = Date.now();
    const entry = this.hits.get(key);
    if (!entry || now - entry.first > this.windowMs) {
      this.hits.set(key, { count: 1, first: now, until: 0 });
      return;
    }
    entry.count++;
    if (entry.count >= this.limit) {
      entry.until = now + this.lockoutMs;
      entry.count = 0;
      entry.first = now;
    }
  }

  succeed(key: string): void {
    this.hits.delete(key);
  }

  clear(): void {
    this.hits.clear();
  }
}