@niksbanna/bot-detector 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/bot-detector.cjs.js +115 -75
- package/dist/bot-detector.cjs.js.map +2 -2
- package/dist/bot-detector.esm.js +115 -75
- package/dist/bot-detector.esm.js.map +2 -2
- package/dist/bot-detector.iife.js +115 -75
- package/dist/bot-detector.iife.js.map +2 -2
- package/dist/bot-detector.iife.min.js +3 -1
- package/package.json +1 -2
- package/src/core/BotDetector.js +0 -284
- package/src/core/ScoringEngine.js +0 -134
- package/src/core/Signal.js +0 -181
- package/src/core/VerdictEngine.js +0 -132
- package/src/index.js +0 -273
- package/src/signals/automation/PhantomJSSignal.js +0 -137
- package/src/signals/automation/PlaywrightSignal.js +0 -129
- package/src/signals/automation/PuppeteerSignal.js +0 -122
- package/src/signals/automation/SeleniumSignal.js +0 -151
- package/src/signals/automation/index.js +0 -8
- package/src/signals/behavior/InteractionTimingSignal.js +0 -170
- package/src/signals/behavior/KeyboardPatternSignal.js +0 -235
- package/src/signals/behavior/MouseMovementSignal.js +0 -215
- package/src/signals/behavior/ScrollBehaviorSignal.js +0 -236
- package/src/signals/behavior/index.js +0 -8
- package/src/signals/environment/HeadlessSignal.js +0 -97
- package/src/signals/environment/NavigatorAnomalySignal.js +0 -117
- package/src/signals/environment/PermissionsSignal.js +0 -76
- package/src/signals/environment/WebDriverSignal.js +0 -58
- package/src/signals/environment/index.js +0 -8
- package/src/signals/fingerprint/AudioContextSignal.js +0 -158
- package/src/signals/fingerprint/CanvasSignal.js +0 -133
- package/src/signals/fingerprint/PluginsSignal.js +0 -106
- package/src/signals/fingerprint/ScreenSignal.js +0 -157
- package/src/signals/fingerprint/WebGLSignal.js +0 -146
- package/src/signals/fingerprint/index.js +0 -9
- package/src/signals/timing/DOMContentTimingSignal.js +0 -159
- package/src/signals/timing/PageLoadSignal.js +0 -165
- package/src/signals/timing/index.js +0 -6
package/README.md
CHANGED
|
@@ -266,6 +266,28 @@ npm run dev
|
|
|
266
266
|
|
|
267
267
|
## Changelog
|
|
268
268
|
|
|
269
|
+
### v1.0.4
|
|
270
|
+
- **Optimization:** Drastically reduced npm package "unpacked size" (from ~1MB down to ~300KB) by disabling source map generation and excluding the raw `src/` directory from the published NPM tarball.
|
|
271
|
+
|
|
272
|
+
### v1.0.3
|
|
273
|
+
- **Stability Fixes:**
|
|
274
|
+
- Fixed a major memory leak where `setTimeout` timers were never cleared in `BotDetector.detect()`.
|
|
275
|
+
- Fixed `getBreakdown()` calling `calculate()` in an $O(n^2)$ loop; now computes instantly ($O(n)$).
|
|
276
|
+
- Fixed an issue where multiple `BotDetector` instances on the same page shared mutable singleton state. `createDetector()` now guarantees fresh detection instances.
|
|
277
|
+
- `BotDetector.withDefaults()` now throws a descriptive error pointing to `createDetector()` instead of silently breaking and returning a useless detector.
|
|
278
|
+
- Capped tracking duration of all behavior signals (`MouseMovementSignal`, `KeyboardPatternSignal`, `ScrollBehaviorSignal`) at `2500ms` so they safely fit within the default `5000ms` global timeout without non-deterministic racing.
|
|
279
|
+
- **False-Positive Fixes:**
|
|
280
|
+
- `PuppeteerSignal` & `HeadlessSignal`: Fixed a critical bug where `window.chrome.runtime` being undefined caused a false positive for all standard, non-extension Chrome users.
|
|
281
|
+
- `NavigatorAnomalySignal`: Chrome 110+ user-agent reduction returns `''` for `navigator.platform`; this is now correctly handled as normal behavior on Chrome.
|
|
282
|
+
- `PuppeteerSignal`: Increased `suspiciousBindings` threshold and excluded React, Webpack, Vite, Nuxt, and Next.js global prefixes to avoid false positives on heavy framework sites.
|
|
283
|
+
- `PageLoadSignal`: Fixed a "negative-timing" false positive caused by evaluating performance metrics before events had fired (zero epoch bug).
|
|
284
|
+
- `PageLoadSignal`: Fixed a "frozen-performance" false positive caused by the browser's deliberate Spectre timer quantization (1-2ms).
|
|
285
|
+
- **Correctness Fixes:**
|
|
286
|
+
- Removed redundant `navigator.webdriver` checks from `PuppeteerSignal`, `PlaywrightSignal`, and `SeleniumSignal` to prevent triple-counting the same underlying signal; this check is now exclusively handled by `WebDriverSignal`.
|
|
287
|
+
- `PhantomJSSignal`: Cleaned up dead code evaluating `Buffer` and `process`.
|
|
288
|
+
- `DOMContentTimingSignal`: Randomized the ID of the injected test div to prevent detection scripts from keying off the hardcoded `__bot_detection_test__` id.
|
|
289
|
+
- **Examples:** Fixed CORS issues with `file://` protocol in demo HTML files by utilizing the IIFE build instead of ESM imports.
|
|
290
|
+
|
|
269
291
|
### v1.0.2
|
|
270
292
|
- **Fix:** `PuppeteerSignal` no longer false-positives on Angular apps — `__zone_symbol__*` bindings injected by Zone.js are now excluded from the suspicious-bindings check.
|
|
271
293
|
- **Fix:** `PuppeteerSignal` no longer false-positives on normal Chrome pages — `incomplete-chrome-object` now only triggers when `window.chrome.runtime` is absent, not when `runtime.id` is undefined (which is normal outside of extensions).
|
package/dist/bot-detector.cjs.js
CHANGED
|
@@ -254,6 +254,7 @@ var ScoringEngine = class {
|
|
|
254
254
|
*/
|
|
255
255
|
getBreakdown() {
|
|
256
256
|
const breakdown = [];
|
|
257
|
+
const score = this.calculate();
|
|
257
258
|
for (const [signalId, data] of this._results) {
|
|
258
259
|
breakdown.push({
|
|
259
260
|
signalId,
|
|
@@ -261,7 +262,7 @@ var ScoringEngine = class {
|
|
|
261
262
|
confidence: data.confidence,
|
|
262
263
|
weight: data.weight,
|
|
263
264
|
contribution: data.contribution,
|
|
264
|
-
percentOfScore:
|
|
265
|
+
percentOfScore: score > 0 ? (data.contribution / score * 100).toFixed(1) : "0.0"
|
|
265
266
|
});
|
|
266
267
|
}
|
|
267
268
|
return breakdown.sort((a, b) => b.contribution - a.contribution);
|
|
@@ -404,7 +405,7 @@ __publicField(_VerdictEngine, "DEFAULT_THRESHOLDS", {
|
|
|
404
405
|
var VerdictEngine = _VerdictEngine;
|
|
405
406
|
|
|
406
407
|
// src/core/BotDetector.js
|
|
407
|
-
var BotDetector = class
|
|
408
|
+
var BotDetector = class {
|
|
408
409
|
/**
|
|
409
410
|
* Creates a new BotDetector instance.
|
|
410
411
|
* @param {Object} [options={}] - Configuration options
|
|
@@ -517,17 +518,17 @@ var BotDetector = class _BotDetector {
|
|
|
517
518
|
return true;
|
|
518
519
|
});
|
|
519
520
|
const detectionPromises = signalsToRun.map(async (signal) => {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
521
|
+
let timeoutId;
|
|
522
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
523
|
+
timeoutId = setTimeout(() => resolve({
|
|
524
|
+
triggered: false,
|
|
525
|
+
value: null,
|
|
526
|
+
confidence: 0,
|
|
527
|
+
error: "timeout"
|
|
528
|
+
}), this._detectionTimeout);
|
|
529
|
+
});
|
|
530
|
+
const result = await Promise.race([signal.run(), timeoutPromise]);
|
|
531
|
+
clearTimeout(timeoutId);
|
|
531
532
|
return { signal, result };
|
|
532
533
|
});
|
|
533
534
|
const results = await Promise.all(detectionPromises);
|
|
@@ -614,12 +615,20 @@ var BotDetector = class _BotDetector {
|
|
|
614
615
|
}
|
|
615
616
|
}
|
|
616
617
|
/**
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
618
|
+
* @deprecated Use `createDetector()` from '@niksbanna/bot-detector' instead.
|
|
619
|
+
* This method cannot load default signals from here due to module boundaries.
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* // Correct:
|
|
623
|
+
* import { createDetector } from '@niksbanna/bot-detector';
|
|
624
|
+
* const detector = createDetector();
|
|
625
|
+
*
|
|
626
|
+
* @throws {Error} Always — to prevent silent empty-detector bugs.
|
|
620
627
|
*/
|
|
621
|
-
static withDefaults(
|
|
622
|
-
|
|
628
|
+
static withDefaults() {
|
|
629
|
+
throw new Error(
|
|
630
|
+
"BotDetector.withDefaults() is not supported. Use createDetector() from '@niksbanna/bot-detector' instead:\n import { createDetector } from '@niksbanna/bot-detector';\n const detector = createDetector();"
|
|
631
|
+
);
|
|
623
632
|
}
|
|
624
633
|
};
|
|
625
634
|
|
|
@@ -675,9 +684,6 @@ var HeadlessSignal = class extends Signal {
|
|
|
675
684
|
if (typeof window.chrome === "undefined") {
|
|
676
685
|
indicators.push("missing-chrome-object");
|
|
677
686
|
confidence = Math.max(confidence, 0.6);
|
|
678
|
-
} else if (!window.chrome.runtime) {
|
|
679
|
-
indicators.push("missing-chrome-runtime");
|
|
680
|
-
confidence = Math.max(confidence, 0.4);
|
|
681
687
|
}
|
|
682
688
|
}
|
|
683
689
|
if (navigator.plugins && navigator.plugins.length === 0) {
|
|
@@ -743,7 +749,8 @@ var NavigatorAnomalySignal = class extends Signal {
|
|
|
743
749
|
totalScore += 1;
|
|
744
750
|
}
|
|
745
751
|
checksPerformed++;
|
|
746
|
-
|
|
752
|
+
const isModernChrome = ua.includes("Chrome") && !ua.includes("Chromium");
|
|
753
|
+
if (!isModernChrome && (!platform || platform === "" || platform === "undefined")) {
|
|
747
754
|
anomalies.push("empty-platform");
|
|
748
755
|
totalScore += 1;
|
|
749
756
|
}
|
|
@@ -855,7 +862,7 @@ var MouseMovementSignal = class extends Signal {
|
|
|
855
862
|
super(options);
|
|
856
863
|
this._movements = [];
|
|
857
864
|
this._isTracking = false;
|
|
858
|
-
this._trackingDuration = options.trackingDuration ||
|
|
865
|
+
this._trackingDuration = Math.min(options.trackingDuration || 2500, 2500);
|
|
859
866
|
this._minMovements = options.minMovements || 5;
|
|
860
867
|
this._boundHandler = null;
|
|
861
868
|
}
|
|
@@ -1009,7 +1016,7 @@ var KeyboardPatternSignal = class extends Signal {
|
|
|
1009
1016
|
super(options);
|
|
1010
1017
|
this._keystrokes = [];
|
|
1011
1018
|
this._isTracking = false;
|
|
1012
|
-
this._trackingDuration = options.trackingDuration ||
|
|
1019
|
+
this._trackingDuration = Math.min(options.trackingDuration || 2500, 2500);
|
|
1013
1020
|
this._minKeystrokes = options.minKeystrokes || 10;
|
|
1014
1021
|
this._boundKeydownHandler = null;
|
|
1015
1022
|
this._boundKeyupHandler = null;
|
|
@@ -1304,7 +1311,7 @@ var ScrollBehaviorSignal = class extends Signal {
|
|
|
1304
1311
|
super(options);
|
|
1305
1312
|
this._scrollEvents = [];
|
|
1306
1313
|
this._isTracking = false;
|
|
1307
|
-
this._trackingDuration = options.trackingDuration ||
|
|
1314
|
+
this._trackingDuration = Math.min(options.trackingDuration || 2500, 2500);
|
|
1308
1315
|
this._boundHandler = null;
|
|
1309
1316
|
}
|
|
1310
1317
|
/**
|
|
@@ -1968,22 +1975,26 @@ var PageLoadSignal = class extends Signal {
|
|
|
1968
1975
|
}
|
|
1969
1976
|
const timing = performance.timing;
|
|
1970
1977
|
const navigationStart = timing.navigationStart;
|
|
1971
|
-
const
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
const
|
|
1976
|
-
const
|
|
1977
|
-
const
|
|
1978
|
-
|
|
1978
|
+
const safeTimingDiff = (end, start) => {
|
|
1979
|
+
if (end === 0 || start === 0) return null;
|
|
1980
|
+
return end - start;
|
|
1981
|
+
};
|
|
1982
|
+
const domContentLoaded = safeTimingDiff(timing.domContentLoadedEventEnd, navigationStart);
|
|
1983
|
+
const domComplete = safeTimingDiff(timing.domComplete, navigationStart);
|
|
1984
|
+
const loadComplete = safeTimingDiff(timing.loadEventEnd, navigationStart);
|
|
1985
|
+
const dnsLookup = safeTimingDiff(timing.domainLookupEnd, timing.domainLookupStart);
|
|
1986
|
+
const tcpConnection = safeTimingDiff(timing.connectEnd, timing.connectStart);
|
|
1987
|
+
const serverResponse = safeTimingDiff(timing.responseEnd, timing.requestStart);
|
|
1988
|
+
const domProcessing = safeTimingDiff(timing.domComplete, timing.domLoading);
|
|
1989
|
+
if (domContentLoaded !== null && domContentLoaded > 0 && domContentLoaded < 10) {
|
|
1979
1990
|
anomalies.push("instant-dom-content-loaded");
|
|
1980
1991
|
confidence = Math.max(confidence, 0.7);
|
|
1981
1992
|
}
|
|
1982
|
-
if (dnsLookup === 0 && tcpConnection === 0 && serverResponse < 5) {
|
|
1993
|
+
if (dnsLookup === 0 && tcpConnection === 0 && serverResponse !== null && serverResponse < 5) {
|
|
1983
1994
|
anomalies.push("zero-network-timing");
|
|
1984
1995
|
confidence = Math.max(confidence, 0.4);
|
|
1985
1996
|
}
|
|
1986
|
-
if (domContentLoaded < 0 || domComplete < 0 || loadComplete < 0) {
|
|
1997
|
+
if (domContentLoaded !== null && domContentLoaded < 0 || domComplete !== null && domComplete < 0 || loadComplete !== null && loadComplete < 0) {
|
|
1987
1998
|
anomalies.push("negative-timing");
|
|
1988
1999
|
confidence = Math.max(confidence, 0.8);
|
|
1989
2000
|
}
|
|
@@ -1993,18 +2004,21 @@ var PageLoadSignal = class extends Signal {
|
|
|
1993
2004
|
confidence = Math.max(confidence, 0.7);
|
|
1994
2005
|
}
|
|
1995
2006
|
}
|
|
1996
|
-
if (domProcessing > 3e4) {
|
|
2007
|
+
if (domProcessing !== null && domProcessing > 3e4) {
|
|
1997
2008
|
anomalies.push("excessive-dom-processing");
|
|
1998
2009
|
confidence = Math.max(confidence, 0.3);
|
|
1999
2010
|
}
|
|
2000
2011
|
const scriptsLoadedTime = timing.domContentLoadedEventStart - timing.responseEnd;
|
|
2001
|
-
if (scriptsLoadedTime > 0 && scriptsLoadedTime < 5) {
|
|
2012
|
+
if (timing.responseEnd > 0 && timing.domContentLoadedEventStart > 0 && scriptsLoadedTime > 0 && scriptsLoadedTime < 5) {
|
|
2002
2013
|
anomalies.push("instant-script-execution");
|
|
2003
2014
|
confidence = Math.max(confidence, 0.4);
|
|
2004
2015
|
}
|
|
2005
|
-
const
|
|
2006
|
-
const
|
|
2007
|
-
|
|
2016
|
+
const perfBefore = performance.now();
|
|
2017
|
+
const spinEnd = perfBefore + 2;
|
|
2018
|
+
while (performance.now() < spinEnd) {
|
|
2019
|
+
}
|
|
2020
|
+
const perfAfter = performance.now();
|
|
2021
|
+
if (perfAfter === perfBefore) {
|
|
2008
2022
|
anomalies.push("frozen-performance-now");
|
|
2009
2023
|
confidence = Math.max(confidence, 0.6);
|
|
2010
2024
|
}
|
|
@@ -2114,9 +2128,10 @@ var DOMContentTimingSignal = class extends Signal {
|
|
|
2114
2128
|
confidence = Math.max(confidence, 0.4);
|
|
2115
2129
|
}
|
|
2116
2130
|
try {
|
|
2131
|
+
const randomId = `__bdt_${Math.random().toString(36).slice(2)}`;
|
|
2117
2132
|
const startMutation = performance.now();
|
|
2118
2133
|
const testDiv = document.createElement("div");
|
|
2119
|
-
testDiv.id =
|
|
2134
|
+
testDiv.id = randomId;
|
|
2120
2135
|
document.body.appendChild(testDiv);
|
|
2121
2136
|
const afterAppend = performance.now();
|
|
2122
2137
|
document.body.removeChild(testDiv);
|
|
@@ -2226,23 +2241,30 @@ var PuppeteerSignal = class extends Signal {
|
|
|
2226
2241
|
indicators.push("default-viewport");
|
|
2227
2242
|
confidence = Math.max(confidence, 0.3);
|
|
2228
2243
|
}
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2244
|
+
const FRAMEWORK_PREFIXES = [
|
|
2245
|
+
"__zone_symbol__",
|
|
2246
|
+
// Angular / Zone.js
|
|
2247
|
+
"__next",
|
|
2248
|
+
// Next.js
|
|
2249
|
+
"__webpack",
|
|
2250
|
+
// webpack
|
|
2251
|
+
"__react",
|
|
2252
|
+
// React DevTools
|
|
2253
|
+
"__REACT",
|
|
2254
|
+
"__vite",
|
|
2255
|
+
// Vite
|
|
2256
|
+
"__nuxt"
|
|
2257
|
+
// Nuxt.js
|
|
2258
|
+
];
|
|
2233
2259
|
const suspiciousBindings = Object.keys(window).filter((key) => {
|
|
2234
|
-
|
|
2260
|
+
if (!key.startsWith("__")) return false;
|
|
2261
|
+
if (typeof window[key] !== "function") return false;
|
|
2262
|
+
return !FRAMEWORK_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
2235
2263
|
});
|
|
2236
|
-
if (suspiciousBindings.length >
|
|
2264
|
+
if (suspiciousBindings.length > 10) {
|
|
2237
2265
|
indicators.push("suspicious-bindings");
|
|
2238
2266
|
confidence = Math.max(confidence, 0.5);
|
|
2239
2267
|
}
|
|
2240
|
-
if (typeof window.chrome !== "undefined") {
|
|
2241
|
-
if (!window.chrome.runtime) {
|
|
2242
|
-
indicators.push("incomplete-chrome-object");
|
|
2243
|
-
confidence = Math.max(confidence, 0.4);
|
|
2244
|
-
}
|
|
2245
|
-
}
|
|
2246
2268
|
const triggered = indicators.length > 0;
|
|
2247
2269
|
return this.createResult(triggered, { indicators }, confidence);
|
|
2248
2270
|
}
|
|
@@ -2282,10 +2304,6 @@ var PlaywrightSignal = class extends Signal {
|
|
|
2282
2304
|
indicators.push("playwright-ua-marker");
|
|
2283
2305
|
confidence = Math.max(confidence, ua.includes("Playwright") ? 1 : 0.7);
|
|
2284
2306
|
}
|
|
2285
|
-
if (navigator.webdriver === true) {
|
|
2286
|
-
indicators.push("webdriver-flag");
|
|
2287
|
-
confidence = Math.max(confidence, 0.8);
|
|
2288
|
-
}
|
|
2289
2307
|
try {
|
|
2290
2308
|
const windowKeys = Object.keys(window);
|
|
2291
2309
|
const pwBindings = windowKeys.filter((k) => k.startsWith("__pw"));
|
|
@@ -2343,10 +2361,6 @@ var SeleniumSignal = class extends Signal {
|
|
|
2343
2361
|
async detect() {
|
|
2344
2362
|
const indicators = [];
|
|
2345
2363
|
let confidence = 0;
|
|
2346
|
-
if (navigator.webdriver === true) {
|
|
2347
|
-
indicators.push("webdriver-flag");
|
|
2348
|
-
confidence = Math.max(confidence, 1);
|
|
2349
|
-
}
|
|
2350
2364
|
const seleniumGlobals = [
|
|
2351
2365
|
"_selenium",
|
|
2352
2366
|
"callSelenium",
|
|
@@ -2513,14 +2527,10 @@ var PhantomJSSignal = class extends Signal {
|
|
|
2513
2527
|
}
|
|
2514
2528
|
const phantomProps = [
|
|
2515
2529
|
"__PHANTOM__",
|
|
2516
|
-
"PHANTOM"
|
|
2517
|
-
"Buffer",
|
|
2518
|
-
// PhantomJS exposes Node.js Buffer
|
|
2519
|
-
"process"
|
|
2520
|
-
// May expose Node.js process
|
|
2530
|
+
"PHANTOM"
|
|
2521
2531
|
];
|
|
2522
2532
|
for (const prop of phantomProps) {
|
|
2523
|
-
if (prop in window
|
|
2533
|
+
if (prop in window) {
|
|
2524
2534
|
indicators.push(`phantom-prop-${prop.toLowerCase()}`);
|
|
2525
2535
|
confidence = Math.max(confidence, 0.9);
|
|
2526
2536
|
}
|
|
@@ -2595,13 +2605,44 @@ function createDetector(options = {}) {
|
|
|
2595
2605
|
instantBotSignals = ["webdriver", "puppeteer", "playwright", "selenium", "phantomjs"],
|
|
2596
2606
|
...detectorOptions
|
|
2597
2607
|
} = options;
|
|
2598
|
-
const
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2608
|
+
const signalClasses = includeInteractionSignals ? [
|
|
2609
|
+
WebDriverSignal,
|
|
2610
|
+
HeadlessSignal,
|
|
2611
|
+
NavigatorAnomalySignal,
|
|
2612
|
+
PermissionsSignal,
|
|
2613
|
+
PluginsSignal,
|
|
2614
|
+
WebGLSignal,
|
|
2615
|
+
CanvasSignal,
|
|
2616
|
+
AudioContextSignal,
|
|
2617
|
+
ScreenSignal,
|
|
2618
|
+
PageLoadSignal,
|
|
2619
|
+
DOMContentTimingSignal,
|
|
2620
|
+
PuppeteerSignal,
|
|
2621
|
+
PlaywrightSignal,
|
|
2622
|
+
SeleniumSignal,
|
|
2623
|
+
PhantomJSSignal,
|
|
2624
|
+
MouseMovementSignal,
|
|
2625
|
+
KeyboardPatternSignal,
|
|
2626
|
+
InteractionTimingSignal,
|
|
2627
|
+
ScrollBehaviorSignal
|
|
2628
|
+
] : [
|
|
2629
|
+
WebDriverSignal,
|
|
2630
|
+
HeadlessSignal,
|
|
2631
|
+
NavigatorAnomalySignal,
|
|
2632
|
+
PermissionsSignal,
|
|
2633
|
+
PluginsSignal,
|
|
2634
|
+
WebGLSignal,
|
|
2635
|
+
CanvasSignal,
|
|
2636
|
+
AudioContextSignal,
|
|
2637
|
+
ScreenSignal,
|
|
2638
|
+
PageLoadSignal,
|
|
2639
|
+
DOMContentTimingSignal,
|
|
2640
|
+
PuppeteerSignal,
|
|
2641
|
+
PlaywrightSignal,
|
|
2642
|
+
SeleniumSignal,
|
|
2643
|
+
PhantomJSSignal
|
|
2644
|
+
];
|
|
2645
|
+
const signals = signalClasses.map((Cls) => new Cls());
|
|
2605
2646
|
return new BotDetector({
|
|
2606
2647
|
signals,
|
|
2607
2648
|
instantBotSignals,
|
|
@@ -2626,4 +2667,3 @@ var index_default = {
|
|
|
2626
2667
|
Signals,
|
|
2627
2668
|
Verdict
|
|
2628
2669
|
};
|
|
2629
|
-
//# sourceMappingURL=bot-detector.cjs.js.map
|