Skip to content

feat: implement rate limiting middleware with client overrides and sqlite auditing#108

Merged
Abd-Standard merged 1 commit into
Core-Foundry:mainfrom
jahrulezfrancis:feature/rate-limiter
Jun 19, 2026
Merged

feat: implement rate limiting middleware with client overrides and sqlite auditing#108
Abd-Standard merged 1 commit into
Core-Foundry:mainfrom
jahrulezfrancis:feature/rate-limiter

Conversation

@jahrulezfrancis

Copy link
Copy Markdown
Contributor

Description

This PR implements rate limiting middleware to protect the Notify-Chain listener API endpoints from abuse and brute-force traffic. Client requests are identified via API keys (supporting custom override thresholds) or IP addresses (as a fallback). Violations are warning-logged and recorded in the SQLite database for audit purposes. Pre-existing test failures due to timing issues, event ID duplicates, and Jest fake timer microtask queue races have also been fully resolved.

Tasks Completed

  • Rate Limiter Middleware: Added in-memory sliding-window request tracking.
  • Client Identification & Overrides: Identifies clients using the x-api-key header, Authorization: Bearer <key> header, x-forwarded-for proxy headers, or remote sockets. Supports custom rate limits mapped per key or IP address.
  • Informative Error Responses: Returns 429 Too Many Requests status, informative JSON response body, and standard HTTP rate limit headers:
    • X-RateLimit-Limit: Maximum requests allowed in the window.
    • X-RateLimit-Remaining: Remaining request quota.
    • X-RateLimit-Reset: Unix epoch reset time.
    • Retry-After: Seconds to wait before next attempt (on 429).
  • Auditing: Violations are logged to Winston and inserted into the rate_limit_events SQLite database table.
  • Existing Test Suite Repairs: Repaired timing/date logic, duplicate detection returns, and microtask flushing in scheduler, Discord notification, and retry queue test files.

Database Schema Additions

Added a new rate_limit_events table to trace rate limit violations:

CREATE TABLE IF NOT EXISTS rate_limit_events (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  client_id TEXT NOT NULL,                  -- IP address or API key
  client_type VARCHAR(20) NOT NULL,         -- 'IP' or 'API_KEY'
  endpoint TEXT NOT NULL,                   -- Request path/method
  method VARCHAR(10) NOT NULL,              -- Request method
  timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  limit_threshold INTEGER NOT NULL,
  window_ms INTEGER NOT NULL
);

Configuration Settings

Available environment variables:

  • RATE_LIMIT_ENABLED (boolean, default: true): Enable or disable rate limiting.
  • RATE_LIMIT_WINDOW_MS (number, default: 60000 / 1 minute): Length of sliding rate window.
  • RATE_LIMIT_MAX_REQUESTS (number, default: 60 requests): Maximum requests allowed per window.
  • RATE_LIMIT_CLIENT_OVERRIDES (JSON string, default: '{}'): Client-specific limits, e.g., '{"vip-key": {"maxRequests": 1000}, "127.0.0.1": {"maxRequests": 500}}'.

Verification Details

Automated Tests

Run the Jest test suite:

npm test

All 16 test suites (211 unit and HTTP integration tests) pass successfully.

Manual Verification

  1. Start the server:
    npm run dev
  2. Query the endpoint repeatedly to trigger the rate limiter (e.g. limit is set to 2 requests/min):
    curl -i http://localhost:8787/api/events
    Expected Response (3rd request):
    HTTP/1.1 429 Too Many Requests
    Access-Control-Allow-Origin: http://localhost:5173
    Access-Control-Allow-Methods: GET, POST, OPTIONS
    Access-Control-Allow-Headers: Content-Type, X-API-Key, Authorization
    X-Request-Id: <request-uuid>
    X-RateLimit-Limit: 2
    X-RateLimit-Remaining: 0
    X-RateLimit-Reset: <reset-timestamp>
    Retry-After: 60
    Content-Type: application/json
    
    {"error":"Too Many Requests","message":"Rate limit exceeded. Try again in 60 seconds."}

Closes #30

@Abd-Standard Abd-Standard merged commit b2d1e85 into Core-Foundry:main Jun 19, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Notification Rate Limiting

2 participants