/** * RateLimit class * Based on classes/modules/core/RateLimit.class.php * * id: string to group similar calls * allowed_calls: integer that represents the number of calls in the time_frame * time_frame: integer number of seconds in which defined number of allowed_calls of specified id may be made * * Basic use case: * * RateLimit.setID( 101 ); //unique identifier for this group of calls * RateLimit.setAllowedCalls( 10 ); //max number of calls in time frame * RateLimit.setTimeFrame( 900 ); //15 minutes in seconds * if ( RateLimit.check() ) { * //do rate limited activity * } else { * //do not do rate limited activity * } * */ export var RateLimit = function() { }; //attributes RateLimit.memory = {}; RateLimit.id = ''; RateLimit.allowed_calls = 10; RateLimit.time_frame = 3600; //1 hr RateLimit.getID = function() { return this.id; }; RateLimit.setID = function( value ) { if ( value != '' ) { this.id = value; return true; } return false; }; RateLimit.getAllowedCalls = function() { return this.allowed_calls; }; RateLimit.setAllowedCalls = function( value ) { if ( value != '' ) { this.allowed_calls = value; return true; } return false; }; RateLimit.getTimeFrame = function() { return this.time_frame; }; RateLimit.setTimeFrame = function( value ) { if ( value != '' ) { this.time_frame = value; return true; } return false; }; RateLimit.getRateData = function() { if ( typeof ( this.memory[this.id] ) == 'undefined' ) { return null; } return this.memory[this.id]; }; RateLimit.setRateData = function( value ) { if ( typeof ( this.memory[this.id] ) == 'undefined' ) { this.memory[this.id] = {}; } if ( value != '' ) { this.memory[this.id] = value; return true; } return false; }; RateLimit.getAttempts = function() { var rate_data = this.getRateData(); if ( Global.isSet( rate_data['attempts'] ) ) { return rate_data['attempts']; } return false; }; /** * @returns {boolean} */ RateLimit.check = function() { if ( this.getID() != '' ) { var rate_data = this.getRateData(); var new_time = ( new Date() ).getTime(); if ( Global.isSet( rate_data ) == false ) { rate_data = { first_date: new_time, attempts: 0 }; } else if ( Global.isSet( rate_data ) ) { var time_frame_milliseconds = this.getTimeFrame() * 1000; if ( rate_data.attempts > this.getAllowedCalls() && rate_data.first_date >= ( new_time - time_frame_milliseconds ) ) { Debug.Text( 'RateLimit limiting [' + rate_data.attempts + '/' + this.getAllowedCalls() + '] in ' + ( Math.floor( ( new_time - rate_data.first_date ) / 1000 ) ) + '/' + this.getTimeFrame() + 'sec', 'RateLimit.js', 'RateLimit', 'check', 10 ); return false; } else if ( rate_data.first_date < new_time - time_frame_milliseconds ) { rate_data = { first_date: new_time, attempts: 0 }; } } rate_data.attempts++; this.setRateData( rate_data ); } return true; }; RateLimit.delete = function( id ) { if ( id != null ) { this.id = id; } delete this.memory[this.id]; };