UNPKG

@seckav/security-sdk

Version:

Lightweight API Security SDK for Enterprises - One-click protection with rate limiting, threat detection, security analytics, and real-time monitoring for Express.js and Next.js applications

112 lines 4.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RateLimitSDK = void 0; exports.createRateLimitMiddleware = createRateLimitMiddleware; exports.createNextRateLimitMiddleware = createNextRateLimitMiddleware; const axios_1 = __importDefault(require("axios")); class RateLimitSDK { constructor(config) { this.config = config; } async checkRateLimit(endpoint, method, clientId, userAgent, ipAddress) { try { const response = await axios_1.default.post(`${this.config.apiUrl}/api/v1/ratelimit/check`, { organizationId: this.config.organizationId, endpoint, method, clientId, userAgent, ipAddress, }, { headers: { 'X-API-Key': this.config.apiKey, 'Content-Type': 'application/json', }, timeout: this.config.timeout || 5000, }); return response.data; } catch (error) { if (this.config.onError) { this.config.onError(error); } // Fail open for reliability return { allowed: true, rateLimitHit: false, error: 'RATE_LIMIT_SERVICE_ERROR', message: 'Rate limit service temporarily unavailable', }; } } } exports.RateLimitSDK = RateLimitSDK; // Convenience functions for backward compatibility function createRateLimitMiddleware(config) { const sdk = new RateLimitSDK(config); return async (req, res, next) => { try { const endpoint = req.path || req.url; const method = req.method; const clientId = req.headers['x-client-id'] || req.user?.id; const userAgent = req.headers['user-agent']; const ipAddress = req.ip || req.connection.remoteAddress; const result = await sdk.checkRateLimit(endpoint, method, clientId, userAgent, ipAddress); if (!result.allowed) { return res.status(429).json({ error: 'Rate limited', retryAfter: result.retryAfter, }); } // Set rate limit headers Object.entries(result.headers || {}).forEach(([key, value]) => { res.setHeader(key, value); }); next(); } catch (error) { if (config.onError) { config.onError(error); } // Fail open next(); } }; } function createNextRateLimitMiddleware(config) { const sdk = new RateLimitSDK(config); return async (req) => { try { const endpoint = req.nextUrl?.pathname || req.url; const method = req.method; const clientId = req.headers.get('x-client-id'); const userAgent = req.headers.get('user-agent') || undefined; const ipAddress = req.ip || req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'); const result = await sdk.checkRateLimit(endpoint, method, clientId, userAgent, ipAddress); if (!result.allowed) { return new Response(JSON.stringify({ error: 'Rate limited', retryAfter: result.retryAfter, }), { status: 429, headers: { 'Content-Type': 'application/json', ...result.headers, }, }); } return null; // Allow request to continue } catch (error) { if (config.onError) { config.onError(error); } // Fail open return null; } }; } //# sourceMappingURL=rateLimitMiddleware.js.map