blob: 0c2a384e4864dc1056ec351bd792a72d57ef3dbf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/**
* Tracks frequency of occurances based on `id` (remote address), then allows or
* denies command execution based on comparison with `threshold`
*
* Version: v2.0.0
* Developer: Marzavec ( https://github.com/marzavec )
* License: WTFPL ( http://www.wtfpl.net/txt/copying/ )
*
*/
class Police {
/**
* Create a ratelimiter instance.
*/
constructor () {
this._records = {};
this._halflife = 30 * 1000; // milliseconds
this._threshold = 25;
this._hashes = [];
}
/**
* Finds current score by `id`
*
* @param {String} id target id / address
* @public
*
* @memberof Police
*/
search (id) {
let record = this._records[id];
if (!record) {
record = this._records[id] = {
time: Date.now(),
score: 0
}
}
return record;
}
/**
* Adjusts the current ratelimit score by `deltaScore`
*
* @param {String} id target id / address
* @param {Number} deltaScore amount to adjust current score by
* @public
*
* @memberof Police
*/
frisk (id, deltaScore) {
let record = this.search(id);
if (record.arrested) {
return true;
}
record.score *= Math.pow(2, -(Date.now() - record.time ) / this._halflife);
record.score += deltaScore;
record.time = Date.now();
if (record.score >= this._threshold) {
return true;
}
return false;
}
/**
* Statically set server to no longer accept traffic from `id`
*
* @param {String} id target id / address
* @public
*
* @memberof Police
*/
arrest (id, hash) {
let record = this.search(id);
record.arrested = true;
this._hashes[hash] = id;
}
/**
* Remove statically assigned limit from `id`
*
* @param {String} id target id / address
* @public
*
* @memberof Police
*/
pardon (id) {
if (typeof this._hashes[id] !== 'undefined') {
id = this._hashes[id];
}
let record = this.search(id);
record.arrested = false;
}
}
module.exports = Police;
|