UNPKG

dt-common-device

Version:

A secure and robust device management library for IoT applications

196 lines (195 loc) 7.95 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, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.CLOUDBEDS, { maxRequests: 8, windowMs: 1000, // 1 second - CloudBed allows 10 requests per second provider: constants_1.CONNECTION_PROVIDERS.CLOUDBEDS, maxTimeoutWindowMs: 1800000, }); configs.set(constants_1.CONNECTION_PROVIDERS.STAYNTOUCH, { maxRequests: 10, windowMs: 10000, // 10 seconds provider: constants_1.CONNECTION_PROVIDERS.STAYNTOUCH, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.HOTELKEY, { maxRequests: 10, windowMs: 10000, // 10 seconds provider: constants_1.CONNECTION_PROVIDERS.HOTELKEY, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.TTLOCK, { maxRequests: 15, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.TTLOCK, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.LOCKLY, { maxRequests: 10, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.LOCKLY, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.SCHLAGE, { maxRequests: 120, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.SCHLAGE, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.SMARTTHINGS, { maxRequests: 30, windowMs: 60000, // 1 minute provider: constants_1.CONNECTION_PROVIDERS.SMARTTHINGS, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.YALEWIFI, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.YALEWIFI, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.TUYA, { maxRequests: 5, windowMs: 1000, provider: constants_1.CONNECTION_PROVIDERS.TUYA, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.SALTOKS, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.SALTOKS, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.SALTOSPACE, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.SALTOSPACE, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.VERDANT, { maxRequests: 5, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.VERDANT, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.SMOOBU, { maxRequests: 1000, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.SMOOBU, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.WEBREZPRO, { maxRequests: 10, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.WEBREZPRO, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.CHECKFRONT, { maxRequests: 10, windowMs: 60000, provider: constants_1.CONNECTION_PROVIDERS.CHECKFRONT, maxTimeoutWindowMs: 120000, }); configs.set(constants_1.CONNECTION_PROVIDERS.MEWS, { maxRequests: 200, windowMs: 30000, // 30 seconds - 200 requests per AccessToken within 30 seconds provider: constants_1.CONNECTION_PROVIDERS.MEWS, maxTimeoutWindowMs: 120000, }); 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)();