express-range-tracker
Advanced tools
Comparing version 1.0.4 to 1.0.5
33
index.js
@@ -9,2 +9,3 @@ const defaultStorage = {}; | ||
onDownloaded, | ||
onSimilarTrait, | ||
onDeadlineReached, | ||
@@ -60,3 +61,3 @@ timestampFunction, | ||
bannedTraits.forEach((trait) => { | ||
bannedTraits.forEach((traitMatches) => { | ||
if (!previous) { | ||
@@ -66,3 +67,3 @@ return; | ||
if (trait(previous, downloadLog)) { | ||
if (traitMatches(previous, downloadLog)) { | ||
throw new RangeError("Banned trait match"); | ||
@@ -72,3 +73,3 @@ } | ||
allowedTraits.forEach((trait) => { | ||
allowedTraits.forEach((traitMatches) => { | ||
if (!previous) { | ||
@@ -78,3 +79,3 @@ return; | ||
if (!trait(previous, downloadLog)) { | ||
if (!traitMatches(previous, downloadLog)) { | ||
throw new RangeError("Allowed trait mismatch"); | ||
@@ -87,2 +88,26 @@ } | ||
if (typeof onSimilarTrait === "function") { | ||
const reducer = (acc, { from, to }) => (acc += `${from},${to};`); | ||
const currentIpHash = storage[ip].reduce(reducer, ""); | ||
const matchingIps = Object.keys(storage).reduce((acc, key) => { | ||
if (key === ip) { | ||
return acc; | ||
} | ||
const hash = storage[key].reduce(reducer, ""); | ||
if (hash === currentIpHash) { | ||
acc.push(key); | ||
} | ||
return acc; | ||
}, []); | ||
if (matchingIps.length) { | ||
onSimilarTrait(matchingIps); | ||
} | ||
} | ||
req.chunks = storage[ip]; | ||
@@ -89,0 +114,0 @@ |
{ | ||
"name": "express-range-tracker", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "Detects bots by tracking the timings of range header", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -51,2 +51,13 @@ # express-range-tracker | ||
`onSimilarTrait` - fires when another ips had the same range behavior as the current ip. The current ip will not be in the list | ||
```js | ||
const track = rangeTracker({ | ||
storage, | ||
onSimilarTrait: (ips) => { | ||
console.log(ips.length); | ||
}, | ||
}); | ||
``` | ||
# Test | ||
@@ -53,0 +64,0 @@ |
@@ -378,2 +378,93 @@ const assert = require("node:assert"); | ||
}); | ||
it("should fire similar trait event on similar trait", async () => { | ||
const storage = {}; | ||
const req1 = { | ||
ip: "::1", | ||
headers: { | ||
range: "bytes=2-50", | ||
}, | ||
}; | ||
const req2 = { | ||
ip: "::1", | ||
headers: { | ||
range: "bytes=2-100", | ||
}, | ||
}; | ||
const req3 = { | ||
ip: "::2", | ||
headers: { | ||
range: "bytes=2-50", | ||
}, | ||
}; | ||
const req4 = { | ||
ip: "::2", | ||
headers: { | ||
range: "bytes=2-100", | ||
}, | ||
}; | ||
await new Promise((resolve) => { | ||
const track = rangeTracker({ | ||
storage, | ||
onSimilarTrait: (ips) => { | ||
assert.ok(ips.length === 1); | ||
assert.ok(ips[0] === req1.ip); | ||
resolve(); | ||
}, | ||
}); | ||
track(req1, res, next); | ||
track(req2, res, next); | ||
track(req3, res, next); | ||
track(req4, res, next); | ||
}); | ||
}); | ||
it("should not fire similar trait event on not similar trait", async () => { | ||
const storage = {}; | ||
const req1 = { | ||
ip: "::1", | ||
headers: { | ||
range: "bytes=2-50", | ||
}, | ||
}; | ||
const req2 = { | ||
ip: "::1", | ||
headers: { | ||
range: "bytes=2-100", | ||
}, | ||
}; | ||
const req3 = { | ||
ip: "::2", | ||
headers: { | ||
range: "bytes=2-50", | ||
}, | ||
}; | ||
const req4 = { | ||
ip: "::2", | ||
headers: { | ||
range: "bytes=2-101", | ||
}, | ||
}; | ||
await new Promise((resolve, reject) => { | ||
const track = rangeTracker({ | ||
storage, | ||
onSimilarTrait: () => { | ||
reject(assert.fail()); | ||
}, | ||
}); | ||
track(req1, res, next); | ||
track(req2, res, next); | ||
track(req3, res, next); | ||
track(req4, res, next); | ||
resolve(); | ||
}); | ||
}); | ||
}); |
13302
513
67