@seckav/security-sdk
Version:
SecKav Security SDK - Enterprise-grade security platform with AI-powered threat detection, LLM-powered misconfiguration scanning (Gemini/GPT-4/Claude), end-to-end encryption, behavioral analysis, enhanced file scanning, adaptive rate limiting, GDPR/DPDP/C
112 lines • 4.1 kB
JavaScript
;
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