@axeptio/behavior-detection 1.0.0

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.
Files changed (76) hide show
  1. package/README.md +828 -0
  2. package/dist/behavior-detection.esm.min.js +2 -0
  3. package/dist/behavior-detection.esm.min.js.map +7 -0
  4. package/dist/behavior-detection.min.js +2 -0
  5. package/dist/behavior-detection.min.js.map +7 -0
  6. package/dist/behavior-detector.d.ts +102 -0
  7. package/dist/browser.d.ts +33 -0
  8. package/dist/cjs/behavior-detector.d.ts +102 -0
  9. package/dist/cjs/behavior-detector.js +315 -0
  10. package/dist/cjs/browser.d.ts +33 -0
  11. package/dist/cjs/browser.js +226 -0
  12. package/dist/cjs/index.d.ts +38 -0
  13. package/dist/cjs/index.js +55 -0
  14. package/dist/cjs/math-utils.d.ts +84 -0
  15. package/dist/cjs/math-utils.js +141 -0
  16. package/dist/cjs/strategies/click.d.ts +39 -0
  17. package/dist/cjs/strategies/click.js +173 -0
  18. package/dist/cjs/strategies/environment.d.ts +52 -0
  19. package/dist/cjs/strategies/environment.js +148 -0
  20. package/dist/cjs/strategies/index.d.ts +18 -0
  21. package/dist/cjs/strategies/index.js +36 -0
  22. package/dist/cjs/strategies/keyboard.d.ts +43 -0
  23. package/dist/cjs/strategies/keyboard.js +233 -0
  24. package/dist/cjs/strategies/mouse.d.ts +39 -0
  25. package/dist/cjs/strategies/mouse.js +159 -0
  26. package/dist/cjs/strategies/resize.d.ts +21 -0
  27. package/dist/cjs/strategies/resize.js +97 -0
  28. package/dist/cjs/strategies/scroll.d.ts +37 -0
  29. package/dist/cjs/strategies/scroll.js +149 -0
  30. package/dist/cjs/strategies/tap.d.ts +38 -0
  31. package/dist/cjs/strategies/tap.js +214 -0
  32. package/dist/cjs/strategy.d.ts +107 -0
  33. package/dist/cjs/strategy.js +33 -0
  34. package/dist/cjs/types.d.ts +168 -0
  35. package/dist/cjs/types.js +26 -0
  36. package/dist/esm/behavior-detector.d.ts +102 -0
  37. package/dist/esm/behavior-detector.js +311 -0
  38. package/dist/esm/browser.d.ts +33 -0
  39. package/dist/esm/browser.js +224 -0
  40. package/dist/esm/index.d.ts +38 -0
  41. package/dist/esm/index.js +36 -0
  42. package/dist/esm/math-utils.d.ts +84 -0
  43. package/dist/esm/math-utils.js +127 -0
  44. package/dist/esm/strategies/click.d.ts +39 -0
  45. package/dist/esm/strategies/click.js +169 -0
  46. package/dist/esm/strategies/environment.d.ts +52 -0
  47. package/dist/esm/strategies/environment.js +144 -0
  48. package/dist/esm/strategies/index.d.ts +18 -0
  49. package/dist/esm/strategies/index.js +19 -0
  50. package/dist/esm/strategies/keyboard.d.ts +43 -0
  51. package/dist/esm/strategies/keyboard.js +229 -0
  52. package/dist/esm/strategies/mouse.d.ts +39 -0
  53. package/dist/esm/strategies/mouse.js +155 -0
  54. package/dist/esm/strategies/resize.d.ts +21 -0
  55. package/dist/esm/strategies/resize.js +93 -0
  56. package/dist/esm/strategies/scroll.d.ts +37 -0
  57. package/dist/esm/strategies/scroll.js +145 -0
  58. package/dist/esm/strategies/tap.d.ts +38 -0
  59. package/dist/esm/strategies/tap.js +210 -0
  60. package/dist/esm/strategy.d.ts +107 -0
  61. package/dist/esm/strategy.js +29 -0
  62. package/dist/esm/types.d.ts +168 -0
  63. package/dist/esm/types.js +23 -0
  64. package/dist/index.d.ts +38 -0
  65. package/dist/math-utils.d.ts +84 -0
  66. package/dist/strategies/click.d.ts +39 -0
  67. package/dist/strategies/environment.d.ts +52 -0
  68. package/dist/strategies/index.d.ts +18 -0
  69. package/dist/strategies/keyboard.d.ts +43 -0
  70. package/dist/strategies/mouse.d.ts +39 -0
  71. package/dist/strategies/resize.d.ts +21 -0
  72. package/dist/strategies/scroll.d.ts +37 -0
  73. package/dist/strategies/tap.d.ts +38 -0
  74. package/dist/strategy.d.ts +107 -0
  75. package/dist/types.d.ts +168 -0
  76. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,828 @@
1
+ # @axeptio/behavior-detection
2
+
3
+ > Lightweight, privacy-first behavior detection library to distinguish human users from automated bots
4
+
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue)](https://www.typescriptlang.org/)
6
+ [![Tree-shakeable](https://img.shields.io/badge/tree--shakeable-yes-brightgreen.svg)]()
7
+
8
+ A sophisticated JavaScript library that analyzes user behavior patterns to determine if interactions are human-like or bot-like. Unlike traditional CAPTCHA systems, this library works silently in the background, providing a seamless user experience while offering robust bot detection capabilities.
9
+
10
+ ## ✨ Features
11
+
12
+ - **🎯 High Accuracy**: Multi-strategy detection approach with configurable weights
13
+ - **🌲 Tree-shakeable**: Import only the strategies you need
14
+ - **🚀 Zero Dependencies**: Lightweight and fast (< 15KB minified)
15
+ - **📱 Cross-platform**: Works on desktop and mobile browsers
16
+ - **🔒 Privacy-first**: All processing happens client-side, no data sent to servers
17
+ - **⚡ Real-time**: Continuously monitors and scores user behavior
18
+ - **🎨 Framework Agnostic**: Works with vanilla JS, React, Vue, Angular, etc.
19
+ - **📦 Multiple Build Formats**: ESM, CommonJS, and IIFE (browser CDN)
20
+ - **🧪 Battle-tested**: Comprehensive adversarial testing against Playwright, Puppeteer, and Selenium
21
+
22
+ ## 🎬 Demo
23
+
24
+ ![Test Harness Screenshot](docs/test-harness.png)
25
+
26
+ Try the interactive test harness locally:
27
+
28
+ ```bash
29
+ npm run tryme
30
+ ```
31
+
32
+ This will build the library and open the comprehensive test harness in your browser, showing real-time detection scores and visualizations as you interact with the page.
33
+
34
+ **Demo Files:**
35
+ - `demos/test-harness.html` - Full-featured interactive test harness with real-time graphs
36
+ - `demos/browser-demo.html` - Simple CDN usage example with auto-initialization
37
+ - `demos/example.html` - Strategy-based usage example with detailed visualizations
38
+
39
+ ## 📦 Installation
40
+
41
+ ### NPM/Yarn
42
+
43
+ ```bash
44
+ npm install @axeptio/behavior-detection
45
+ # or
46
+ yarn add @axeptio/behavior-detection
47
+ ```
48
+
49
+ ### CDN (Browser)
50
+
51
+ ```html
52
+ <script src="https://static.axept.io/behavior-detector.latest.js"></script>
53
+ ```
54
+
55
+ ## 🚀 Quick Start
56
+
57
+ ### Strategy-based Usage (Recommended)
58
+
59
+ Import only the strategies you need for optimal bundle size:
60
+
61
+ ```typescript
62
+ import { BehaviorDetector, Mouse, Click, Keyboard } from '@axeptio/behavior-detection';
63
+
64
+ const detector = new BehaviorDetector()
65
+ .addStrategy(new Mouse())
66
+ .addStrategy(new Click())
67
+ .addStrategy(new Keyboard());
68
+
69
+ // Start tracking
70
+ detector.start();
71
+
72
+ // Get score (0 = bot-like, 1 = human-like)
73
+ const result = await detector.score({ breakdown: true });
74
+ console.log('Human likelihood:', result.score);
75
+ console.log('Breakdown:', result.breakdown);
76
+
77
+ // Stop tracking when done
78
+ detector.stop();
79
+ ```
80
+
81
+ ### Browser CDN Usage
82
+
83
+ ```html
84
+ <!DOCTYPE html>
85
+ <html>
86
+ <head>
87
+ <title>Bot Detection Demo</title>
88
+ </head>
89
+ <body>
90
+ <h1>Interact with this page</h1>
91
+ <button>Click me</button>
92
+ <input type="text" placeholder="Type something...">
93
+
94
+ <script src="https://static.axept.io/behavior-detector.latest.js"></script>
95
+ <script>
96
+ // Configure before the script loads (or call init after)
97
+ window.bdSettings = {
98
+ autoStart: true,
99
+ checkMs: 2000, // Check every 2 seconds
100
+ onScore: (result) => {
101
+ console.log('Score:', result.score);
102
+ },
103
+ ifBot: (result) => {
104
+ console.warn('Bot detected!', result.score);
105
+ // Take action: show CAPTCHA, limit features, etc.
106
+ },
107
+ ifHuman: (result) => {
108
+ console.log('Human confirmed!', result.score);
109
+ },
110
+ botThreshold: 0.3, // Below this = bot
111
+ humanThreshold: 0.7 // Above this = human
112
+ };
113
+ </script>
114
+ </body>
115
+ </html>
116
+ ```
117
+
118
+ ### Framework Examples
119
+
120
+ #### React
121
+
122
+ ```tsx
123
+ import { useEffect, useRef } from 'react';
124
+ import { BehaviorDetector, Mouse, Click, Scroll } from '@axeptio/behavior-detection';
125
+
126
+ function App() {
127
+ const detectorRef = useRef<BehaviorDetector>();
128
+
129
+ useEffect(() => {
130
+ const detector = new BehaviorDetector()
131
+ .addStrategy(new Mouse())
132
+ .addStrategy(new Click())
133
+ .addStrategy(new Scroll());
134
+
135
+ detector.start();
136
+ detectorRef.current = detector;
137
+
138
+ // Check score periodically
139
+ const interval = setInterval(async () => {
140
+ const result = await detector.score();
141
+ if (result.score < 0.3) {
142
+ console.warn('Bot detected!');
143
+ // Show CAPTCHA or take other action
144
+ }
145
+ }, 3000);
146
+
147
+ return () => {
148
+ clearInterval(interval);
149
+ detector.stop();
150
+ };
151
+ }, []);
152
+
153
+ return <div>Your app content</div>;
154
+ }
155
+ ```
156
+
157
+ #### Vue
158
+
159
+ ```vue
160
+ <template>
161
+ <div>Your app content</div>
162
+ </template>
163
+
164
+ <script setup>
165
+ import { onMounted, onUnmounted } from 'vue';
166
+ import { BehaviorDetector, Mouse, Click, Scroll } from '@axeptio/behavior-detection';
167
+
168
+ let detector;
169
+ let checkInterval;
170
+
171
+ onMounted(() => {
172
+ detector = new BehaviorDetector()
173
+ .addStrategy(new Mouse())
174
+ .addStrategy(new Click())
175
+ .addStrategy(new Scroll());
176
+
177
+ detector.start();
178
+
179
+ checkInterval = setInterval(async () => {
180
+ const result = await detector.score();
181
+ if (result.score < 0.3) {
182
+ console.warn('Bot detected!');
183
+ }
184
+ }, 3000);
185
+ });
186
+
187
+ onUnmounted(() => {
188
+ clearInterval(checkInterval);
189
+ detector?.stop();
190
+ });
191
+ </script>
192
+ ```
193
+
194
+ ## 🎯 Detection Strategies
195
+
196
+ The library uses multiple autonomous detection strategies, each analyzing different aspects of user behavior:
197
+
198
+ ### 🖱️ Mouse Strategy
199
+
200
+ **Weight:** 0.30 (default)
201
+
202
+ Analyzes mouse movement patterns for human-like characteristics:
203
+
204
+ - **Velocity Variation**: Humans have natural acceleration/deceleration (CV ~0.8-1.2)
205
+ - **Direction Changes**: Organic curves vs. linear interpolation
206
+ - **Movement Smoothness**: Natural micro-corrections vs. perfect paths
207
+
208
+ ```typescript
209
+ import { MouseStrategy } from '@axeptio/behavior-detection';
210
+
211
+ const mouse = new MouseStrategy({
212
+ rollingWindow: 5000 // Keep last 5 seconds of data
213
+ });
214
+
215
+ detector.addStrategy(mouse, 0.30); // Custom weight
216
+ ```
217
+
218
+ **Bot Indicators:**
219
+ - Constant velocity movements
220
+ - Perfect straight lines or curves
221
+ - Instant position jumps
222
+ - No micro-corrections
223
+
224
+ ### 👆 Click Strategy
225
+
226
+ **Weight:** 0.30 (default)
227
+
228
+ Monitors click positioning accuracy on interactive elements:
229
+
230
+ ```typescript
231
+ import { ClickStrategy } from '@axeptio/behavior-detection';
232
+
233
+ const click = new ClickStrategy({
234
+ targetSelectors: ['button', 'a', '[role="button"]']
235
+ });
236
+
237
+ detector.addStrategy(click);
238
+
239
+ // Add custom targets dynamically
240
+ click.addTarget('.custom-clickable');
241
+ ```
242
+
243
+ **Detection Patterns:**
244
+ - ✅ **Human**: Mouse positioned over element before click
245
+ - ⚠️ **Suspicious**: Click at exact center (pixel-perfect)
246
+ - ❌ **Bot**: Click without mouse movement or mouse outside element
247
+
248
+ ### 📜 Scroll Strategy
249
+
250
+ **Weight:** 0.15 (default)
251
+
252
+ Analyzes scrolling behavior patterns:
253
+
254
+ ```typescript
255
+ import { ScrollStrategy } from '@axeptio/behavior-detection';
256
+
257
+ const scroll = new ScrollStrategy({
258
+ rollingWindow: 5000
259
+ });
260
+ ```
261
+
262
+ **Bot Indicators:**
263
+ - Identical scroll distances (smoking gun)
264
+ - Instant jumps (programmatic scrollTo)
265
+ - Too consistent velocity
266
+ - No natural acceleration/deceleration
267
+
268
+ ### ⌨️ Keyboard Strategy
269
+
270
+ **Weight:** 0.10 (default)
271
+
272
+ Examines typing patterns and timing:
273
+
274
+ ```typescript
275
+ import { KeyboardStrategy } from '@axeptio/behavior-detection';
276
+
277
+ const keyboard = new KeyboardStrategy({
278
+ targetSelectors: ['input[type="text"]', 'textarea']
279
+ });
280
+
281
+ // Add custom input targets
282
+ keyboard.addTarget('#custom-input');
283
+ ```
284
+
285
+ **Detection Factors:**
286
+ - Keystroke interval variation (natural human timing has CV ~0.4-0.6)
287
+ - Key press duration variance
288
+ - Backspace usage (error correction = human)
289
+ - Too fast/instant key releases (<5ms = bot)
290
+
291
+ ### 📱 Tap Strategy (Mobile)
292
+
293
+ **Weight:** 0.35 (mobile default)
294
+
295
+ Mobile-specific touch interaction detection:
296
+
297
+ ```typescript
298
+ import { TapStrategy } from '@axeptio/behavior-detection';
299
+
300
+ const tap = new TapStrategy({
301
+ targetSelectors: ['button', 'a']
302
+ });
303
+ ```
304
+
305
+ **Analyzes:**
306
+ - Touch pressure patterns
307
+ - Tap duration and timing
308
+ - Multi-touch gestures
309
+
310
+ ### 🌐 Environment Strategy
311
+
312
+ **Weight:** 0.08 (default)
313
+
314
+ Fingerprints browser environment for automation indicators:
315
+
316
+ ```typescript
317
+ import { EnvironmentStrategy } from '@axeptio/behavior-detection';
318
+
319
+ const env = new EnvironmentStrategy();
320
+ ```
321
+
322
+ **Checks:**
323
+ - Suspicious dimensions (800x600, 1024x768)
324
+ - Missing browser features (WebGL, localStorage)
325
+ - Plugin/MIME type inconsistencies
326
+ - Headless browser indicators
327
+ - Navigator property anomalies
328
+
329
+ ### 📐 Resize Strategy
330
+
331
+ **Weight:** 0.02 (default)
332
+
333
+ Monitors window resize behavior:
334
+
335
+ ```typescript
336
+ import { ResizeStrategy } from '@axeptio/behavior-detection';
337
+
338
+ const resize = new ResizeStrategy();
339
+ ```
340
+
341
+ **Detects:**
342
+ - Programmatic resizing patterns
343
+ - Suspicious resize timing
344
+ - Mouse position during resize
345
+
346
+ ## 📊 API Reference
347
+
348
+ ### BehaviorDetector
349
+
350
+ Main class for managing detection strategies.
351
+
352
+ #### Constructor
353
+
354
+ ```typescript
355
+ constructor(options?: TickOptions)
356
+ ```
357
+
358
+ **Options:**
359
+ - `interval?: number` - Tick interval in milliseconds (default: 1000)
360
+ - `pauseOnHidden?: boolean` - Automatically pause detection when tab is hidden (default: true)
361
+
362
+ #### Methods
363
+
364
+ ##### `addStrategy(strategy: DetectionStrategy, weight?: number): this`
365
+
366
+ Add a detection strategy with optional custom weight.
367
+
368
+ ```typescript
369
+ detector.addStrategy(new Mouse(), 0.35);
370
+ ```
371
+
372
+ ##### `removeStrategy(name: string): this`
373
+
374
+ Remove a strategy by name.
375
+
376
+ ```typescript
377
+ detector.removeStrategy('mouse');
378
+ ```
379
+
380
+ ##### `setStrategyEnabled(name: string, enabled: boolean): this`
381
+
382
+ Enable or disable a strategy without removing it.
383
+
384
+ ```typescript
385
+ detector.setStrategyEnabled('mouse', false);
386
+ ```
387
+
388
+ ##### `start(): void`
389
+
390
+ Start all enabled strategies.
391
+
392
+ ```typescript
393
+ detector.start();
394
+ ```
395
+
396
+ ##### `stop(): void`
397
+
398
+ Stop all strategies and cleanup listeners.
399
+
400
+ ```typescript
401
+ detector.stop();
402
+ ```
403
+
404
+ ##### `reset(): void`
405
+
406
+ Clear all collected data without stopping.
407
+
408
+ ```typescript
409
+ detector.reset();
410
+ ```
411
+
412
+ ##### `score(options?: ScoreOptions): Promise<ScoreResult>`
413
+
414
+ Calculate the human likelihood score.
415
+
416
+ ```typescript
417
+ const result = await detector.score({
418
+ breakdown: true, // Include per-strategy scores
419
+ });
420
+ ```
421
+
422
+ **ScoreOptions:**
423
+ - `breakdown?: boolean` - Include detailed breakdown of each strategy
424
+
425
+ **ScoreResult:**
426
+ ```typescript
427
+ {
428
+ score: number; // 0-1 (0=bot, 1=human)
429
+ breakdown?: {
430
+ overall: number;
431
+ factors: {
432
+ mouse?: number;
433
+ click?: number;
434
+ scroll?: number;
435
+ keyboard?: number;
436
+ environment?: number;
437
+ // ...
438
+ };
439
+ weights: {
440
+ mouse: number;
441
+ click: number;
442
+ // ...
443
+ };
444
+ };
445
+ }
446
+ ```
447
+
448
+ ##### `isActive(): boolean`
449
+
450
+ Check if detector is currently tracking.
451
+
452
+ ```typescript
453
+ if (detector.isActive()) {
454
+ console.log('Detector is running');
455
+ }
456
+ ```
457
+
458
+ ##### `isPaused(): boolean`
459
+
460
+ Check if detector is currently paused due to tab visibility.
461
+
462
+ ```typescript
463
+ if (detector.isPaused()) {
464
+ console.log('Detector is paused (tab hidden)');
465
+ }
466
+ ```
467
+
468
+ Note: A detector can be both active and paused. When the tab is hidden with `pauseOnHidden: true`, the detector remains active but is temporarily paused.
469
+
470
+ ##### `getEventCount(): Record<string, number>`
471
+
472
+ Get event counts from all strategies.
473
+
474
+ ##### `getStrategyDebugInfo(): Record<string, any>`
475
+
476
+ Get debug information from all strategies.
477
+
478
+ ##### `destroy(): void`
479
+
480
+ Complete cleanup and remove all strategies.
481
+
482
+ ```typescript
483
+ detector.destroy();
484
+ ```
485
+
486
+ ## ⚙️ Configuration
487
+
488
+ ### Strategy Weights
489
+
490
+ Customize how much each strategy contributes to the final score:
491
+
492
+ ```typescript
493
+ const detector = new BehaviorDetector()
494
+ .addStrategy(new Mouse(), 0.40) // 40% weight
495
+ .addStrategy(new Click(), 0.35) // 35% weight
496
+ .addStrategy(new Scroll(), 0.15) // 15% weight
497
+ .addStrategy(new Keyboard(), 0.10); // 10% weight
498
+ ```
499
+
500
+ ### Desktop vs Mobile
501
+
502
+ The library automatically adjusts strategies based on device type:
503
+
504
+ **Desktop (default):**
505
+ - Mouse: 0.30
506
+ - Click: 0.30
507
+ - Scroll: 0.15
508
+ - Keyboard: 0.10
509
+ - Environment: 0.08
510
+ - Resize: 0.02
511
+
512
+ **Mobile (automatic):**
513
+ - Tap: 0.35 (replaces click)
514
+ - Scroll: 0.35 (increased)
515
+ - Keyboard: 0.15
516
+ - Environment: 0.10
517
+ - Resize: 0.05
518
+
519
+ ### Tick Interval
520
+
521
+ Control how often strategies receive tick updates:
522
+
523
+ ```typescript
524
+ const detector = new BehaviorDetector({
525
+ interval: 500 // Check every 500ms
526
+ });
527
+ ```
528
+
529
+ ### Automatic Pause on Hidden Tab
530
+
531
+ By default, the detector automatically pauses when the browser tab becomes hidden (using the Page Visibility API) and resumes when the tab becomes visible again. This provides several benefits:
532
+
533
+ - **Better Performance**: Saves CPU cycles when the tab isn't visible
534
+ - **Battery Life**: Reduces power consumption on mobile devices
535
+ - **Accuracy**: Avoids collecting misleading data from background tabs
536
+
537
+ ```typescript
538
+ // Default: pause on hidden (recommended)
539
+ const detector = new BehaviorDetector({
540
+ pauseOnHidden: true // Default
541
+ });
542
+
543
+ // Disable if you need to track background behavior
544
+ const detector = new BehaviorDetector({
545
+ pauseOnHidden: false
546
+ });
547
+
548
+ // Check if currently paused
549
+ if (detector.isPaused()) {
550
+ console.log('Detection is paused (tab hidden)');
551
+ }
552
+ ```
553
+
554
+ **Browser CDN Usage:**
555
+
556
+ ```javascript
557
+ window.bdSettings = {
558
+ autoStart: true,
559
+ pauseOnHidden: true, // Default: true
560
+ // ... other settings
561
+ };
562
+ ```
563
+
564
+ The detector remains "active" (via `isActive()`) while paused, but strategies and tick updates are temporarily stopped until the tab becomes visible again. All collected data is preserved during the pause.
565
+
566
+ ## 🎨 Browser Support
567
+
568
+ - ✅ Chrome/Edge 90+
569
+ - ✅ Firefox 88+
570
+ - ✅ Safari 14+
571
+ - ✅ Mobile Safari (iOS 14+)
572
+ - ✅ Chrome Mobile (Android 90+)
573
+
574
+ ## 🧪 Testing & Validation
575
+
576
+ The library includes comprehensive adversarial testing against popular automation frameworks:
577
+
578
+ ### Run All Tests
579
+
580
+ ```bash
581
+ npm run test:adversarial
582
+ ```
583
+
584
+ ### Individual Framework Tests
585
+
586
+ ```bash
587
+ # Test against Playwright
588
+ npm run test:playwright
589
+
590
+ # Test against Puppeteer
591
+ npm run test:puppeteer
592
+
593
+ # Test against Selenium
594
+ npm run test:selenium
595
+
596
+ # Stress test (extensive scenarios)
597
+ npm run test:stress
598
+ ```
599
+
600
+ ### Test Scenarios
601
+
602
+ Each framework is tested with:
603
+
604
+ 1. **Bot-like behavior** - Rapid actions, no delays (expected: score < 0.4)
605
+ 2. **Human-like behavior** - Natural delays and movements (expected: score > 0.6)
606
+ 3. **Stealth mode** - Automation with evasion techniques
607
+ 4. **Headless vs Headed** - Different browser modes
608
+
609
+ See [tests/adversarial/README.md](tests/adversarial/README.md) for detailed testing documentation.
610
+
611
+ ## 🏗️ Architecture
612
+
613
+ ### Strategy Pattern
614
+
615
+ Each detection strategy is a fully autonomous module:
616
+
617
+ ```typescript
618
+ interface DetectionStrategy {
619
+ readonly name: string;
620
+ readonly defaultWeight: number;
621
+
622
+ start(): void; // Register listeners
623
+ stop(): void; // Cleanup
624
+ reset(): void; // Clear data
625
+ score(): number | undefined; // Calculate score
626
+
627
+ onTick?(timestamp: number): void; // Optional polling
628
+ getDebugInfo?(): any; // Optional debug data
629
+ }
630
+ ```
631
+
632
+ **Benefits:**
633
+ - 🌲 Tree-shakeable (import only what you need)
634
+ - 🔌 Fully autonomous (manages own listeners and state)
635
+ - 🎯 Single responsibility
636
+ - 🧩 Easy to extend with custom strategies
637
+
638
+ ### Mathematical Scoring
639
+
640
+ Uses smooth mathematical functions instead of magic numbers:
641
+
642
+ ```typescript
643
+ import { gaussian, sigmoid, inverseSigmoid } from './math-utils';
644
+
645
+ // Gaussian: ideal value with symmetric falloff
646
+ score = gaussian(actualCV, idealCV, width);
647
+
648
+ // Sigmoid: smooth 0-1 mapping
649
+ score = sigmoid(value, midpoint, steepness);
650
+
651
+ // Inverse sigmoid: penalize high values
652
+ score = inverseSigmoid(value, midpoint, steepness);
653
+ ```
654
+
655
+ ## 📈 Performance
656
+
657
+ - **Minimal CPU Impact**: Sampling and rolling windows prevent data buildup
658
+ - **Memory Efficient**: ~1-2MB typical memory usage
659
+ - **No Network Calls**: Everything runs client-side
660
+ - **Async Scoring**: Non-blocking score calculations
661
+
662
+ ## 🔐 Privacy & Security
663
+
664
+ - ✅ **Client-side only**: No data transmitted to servers
665
+ - ✅ **No PII collected**: Only behavioral patterns (no keystrokes content)
666
+ - ✅ **GDPR friendly**: No cookies, no tracking, no storage
667
+ - ✅ **Transparent**: Open source and auditable
668
+
669
+ ## 🛠️ Development
670
+
671
+ ### Build
672
+
673
+ ```bash
674
+ # Build all formats (ESM, CJS, IIFE)
675
+ npm run build:all
676
+
677
+ # Build only ESM/CJS
678
+ npm run build
679
+
680
+ # Build browser bundle
681
+ npm run build:browser
682
+ ```
683
+
684
+ ### Project Structure
685
+
686
+ ```
687
+ behavior-detection/
688
+ ├── src/
689
+ │ ├── behavior-detector.ts # Main detector class
690
+ │ ├── strategy.ts # Strategy interface
691
+ │ ├── types.ts # TypeScript types
692
+ │ ├── math-utils.ts # Mathematical functions
693
+ │ ├── browser.ts # Browser CDN wrapper
694
+ │ └── strategies/
695
+ │ ├── mouse.ts # Mouse movement detection
696
+ │ ├── click.ts # Click accuracy detection
697
+ │ ├── scroll.ts # Scroll behavior detection
698
+ │ ├── keyboard.ts # Keyboard timing detection
699
+ │ ├── tap.ts # Mobile tap detection
700
+ │ ├── environment.ts # Environment fingerprinting
701
+ │ └── resize.ts # Window resize detection
702
+ ├── dist/ # Build output
703
+ ├── demos/
704
+ │ ├── test-harness.html # Interactive testing UI with graphs
705
+ │ ├── browser-demo.html # CDN usage example
706
+ │ └── example.html # Strategy-based usage example
707
+ ├── tests/
708
+ │ └── adversarial/ # Automation framework tests
709
+ └── docs/ # Documentation assets
710
+ ```
711
+
712
+ ### Scripts
713
+
714
+ ```bash
715
+ npm run build # Build library (ESM + CJS)
716
+ npm run build:all # Build all formats
717
+ npm run build:browser # Build browser IIFE bundle
718
+ npm run clean # Clean dist directory
719
+ npm run tryme # Build and start demo server
720
+ npm run deploy # Deploy to CDN (AWS S3/CloudFront)
721
+ npm run test # Run basic tests
722
+ npm run test:adversarial # Run all adversarial tests
723
+ npm run test:stress # Stress test with extensive scenarios
724
+ ```
725
+
726
+ ## 🤝 Contributing
727
+
728
+ Contributions are welcome! This library can be extended with:
729
+
730
+ - **New strategies**: Add detection for new behavioral patterns
731
+ - **Improved algorithms**: Enhance existing detection logic
732
+ - **Mobile optimizations**: Better touch/gesture detection
733
+ - **Performance improvements**: Reduce overhead
734
+ - **Test coverage**: Add more adversarial test scenarios
735
+
736
+ ### Creating Custom Strategies
737
+
738
+ ```typescript
739
+ import { DetectionStrategy } from '@axeptio/behavior-detection';
740
+
741
+ export class CustomStrategy implements DetectionStrategy {
742
+ readonly name = 'custom';
743
+ readonly defaultWeight = 0.10;
744
+
745
+ private data: any[] = [];
746
+ private listener: any;
747
+
748
+ start(): void {
749
+ this.listener = (e: Event) => {
750
+ // Collect data
751
+ this.data.push(/* ... */);
752
+ };
753
+ document.addEventListener('someevent', this.listener);
754
+ }
755
+
756
+ stop(): void {
757
+ if (this.listener) {
758
+ document.removeEventListener('someevent', this.listener);
759
+ }
760
+ }
761
+
762
+ reset(): void {
763
+ this.data = [];
764
+ }
765
+
766
+ score(): number | undefined {
767
+ if (this.data.length < 5) return undefined;
768
+
769
+ // Calculate and return score (0-1)
770
+ return 0.85;
771
+ }
772
+
773
+ getDebugInfo() {
774
+ return {
775
+ eventCount: this.data.length,
776
+ data: this.data
777
+ };
778
+ }
779
+ }
780
+ ```
781
+
782
+ ## 📝 Use Cases
783
+
784
+ - **Form Protection**: Detect automated form submissions
785
+ - **Account Security**: Identify credential stuffing attacks
786
+ - **E-commerce**: Prevent inventory hoarding bots
787
+ - **Analytics**: Filter bot traffic from user metrics
788
+ - **Rate Limiting**: Adaptive limits based on behavior
789
+ - **A/B Testing**: Exclude bots from experiments
790
+ - **Progressive CAPTCHAs**: Only show CAPTCHA to suspicious users
791
+
792
+ ## 🎯 Detection Thresholds
793
+
794
+ Recommended score interpretation:
795
+
796
+ | Score Range | Interpretation | Action |
797
+ |-------------|---------------|--------|
798
+ | 0.8 - 1.0 | Very likely human | Full access |
799
+ | 0.6 - 0.8 | Probably human | Monitor |
800
+ | 0.3 - 0.6 | Suspicious | Add friction (CAPTCHA) |
801
+ | 0.0 - 0.3 | Very likely bot | Block or severely limit |
802
+
803
+ **Note:** Thresholds should be tuned based on your specific use case and acceptable false positive rate.
804
+
805
+ ## ⚠️ Limitations
806
+
807
+ - **Not foolproof**: Sophisticated bots with human-like behavior can evade detection
808
+ - **Initial period**: Requires user interaction to build confidence
809
+ - **False positives**: Accessibility tools, keyboard-only navigation may score lower
810
+ - **Context matters**: Some legitimate use cases (automation testing, scripts) will be flagged
811
+
812
+ **Best Practice:** Use as one layer in a defense-in-depth strategy, not as the sole security measure.
813
+
814
+ ## 📄 License
815
+
816
+ Proprietary © [Axeptio](https://www.axeptio.eu)
817
+
818
+ ## 🙏 Acknowledgments
819
+
820
+ - Inspired by research in behavioral biometrics and bot detection
821
+ - Built with TypeScript for type safety
822
+ - Tested against real-world automation frameworks
823
+ - Mathematical approach based on statistical pattern recognition
824
+
825
+ ---
826
+
827
+ **Made with ❤️ by [Axeptio](https://www.axeptio.eu)**
828
+