UNPKG

dt-common-device

Version:

A secure and robust device management library for IoT applications

149 lines (148 loc) 5.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RateLimitUtils = void 0; const redis_1 = require("../../db/redis"); const config_1 = require("../../config/config"); const constants_1 = require("../../constants"); class RateLimitUtils { static async checkRateLimit(connectionId, provider, rateLimitConfigs) { const config = rateLimitConfigs.get(provider); if (!config) { (0, config_1.getConfig)().LOGGER.warn(`No rate limit config found for provider: ${provider}`); return true; } const key = `rate_limit:${provider}:${connectionId}`; const now = Date.now(); const windowStart = now - config.windowMs; try { const data = await this.redisClient.get(key); const requests = data ? JSON.parse(data).filter((t) => t > windowStart) : []; if (requests.length >= config.maxRequests) return false; requests.push(now); await this.redisClient.setex(key, Math.ceil(config.windowMs / 1000), JSON.stringify(requests)); return true; } catch (error) { (0, config_1.getConfig)().LOGGER.error(`Rate limit check error: ${error}`); return true; } } static initializeRateLimitConfigs() { const configs = new Map(); // Configure rate limits for different providers configs.set(constants_1.CONNECTION_PROVIDERS.SENSIBO, { maxRequests: 10, windowMs: 10000, // 10 seconds provider: constants_1.CONNECTION_PROVIDERS.SENSIBO, }); configs.set(constants_1.CONNECTION_PROVIDERS.CLOUDBEDS, { maxRequests: 10, windowMs: 10000, // 10 seconds provider: constants_1.CONNECTION_PROVIDERS.CLOUDBEDS, }); configs.set(constants_1.CONNECTION_PROVIDERS.STAYNTOUCH, { maxRequests: 10, windowMs: 10000, // 10 seconds provider: constants_1.CONNECTION_PROVIDERS.STAYNTOUCH, }); configs.set(constants_1.CONNECTION_PROVIDERS.HOTELKEY, { maxRequests: 10, windowMs: 10000, // 10 seconds provider: constants_1.CONNECTION_PROVIDERS.HOTELKEY, }); configs.set(constants_1.CONNECTION_PROVIDERS.TTLOCK, { maxRequests: 15, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.TTLOCK, }); configs.set(constants_1.CONNECTION_PROVIDERS.SCHLAGE, { maxRequests: 120, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.SCHLAGE, }); configs.set(constants_1.CONNECTION_PROVIDERS.SMARTTHINGS, { maxRequests: 250, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.SMARTTHINGS, }); configs.set(constants_1.CONNECTION_PROVIDERS.YALEWIFI, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.YALEWIFI, }); configs.set(constants_1.CONNECTION_PROVIDERS.TUYA, { maxRequests: 5, windowMs: 1000, provider: constants_1.CONNECTION_PROVIDERS.TUYA, }); configs.set(constants_1.CONNECTION_PROVIDERS.SALTOKS, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.SALTOKS, }); configs.set(constants_1.CONNECTION_PROVIDERS.VERDANT, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.VERDANT, }); return configs; } static async isRateLimitAllowed(connectionId, provider, rateLimitConfigs) { const config = rateLimitConfigs.get(provider); if (!config) { (0, config_1.getConfig)().LOGGER.warn(`No rate limit config found for provider: ${provider}`); return true; } const key = `rate_limit:${provider}:${connectionId}`; const now = Date.now(); const windowStart = now - config.windowMs; try { const data = await this.redisClient.get(key); const requests = data ? JSON.parse(data).filter((t) => t > windowStart) : []; return requests.length < config.maxRequests; } catch (error) { (0, config_1.getConfig)().LOGGER.error(`Rate limit check error: ${error}`); return true; } } static async recordRequest(connectionId, provider) { const config = this.getRateLimitConfig(provider); if (!config) return; const key = `rate_limit:${provider}:${connectionId}`; const now = Date.now(); const windowStart = now - config.windowMs; try { const data = await this.redisClient.get(key); const requests = data ? JSON.parse(data).filter((t) => t > windowStart) : []; requests.push(now); await this.redisClient.setex(key, Math.ceil(config.windowMs / 1000), JSON.stringify(requests)); } catch (error) { (0, config_1.getConfig)().LOGGER.error(`Rate limit record error: ${error}`); } } static async getRawRequestTimestamps(key) { try { const data = await this.redisClient.get(key); return data ? JSON.parse(data) : []; } catch (error) { (0, config_1.getConfig)().LOGGER.error(`Error fetching raw request timestamps: ${error}`); return []; } } static getRateLimitConfig(provider) { return this.initializeRateLimitConfigs().get(provider); } } exports.RateLimitUtils = RateLimitUtils; RateLimitUtils.redisClient = (0, redis_1.getRedisClient)();