devn-bot-detector-client 0.1.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.
- package/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/index.cjs +1020 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +211 -0
- package/dist/index.d.ts +211 -0
- package/dist/index.js +1007 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/collectors/browser.ts","../src/collectors/pointer.ts","../src/collectors/keyboard.ts","../src/collectors/touch.ts","../src/collectors/scroll.ts","../src/collectors/focus.ts","../src/collectors/visibility.ts","../src/collectors/interaction.ts","../src/session.ts","../src/transport.ts","../src/BotDetector.ts"],"names":["DEFAULT_SESSION_DURATION_MS","SITE_KEY_HEADER","DEFAULT_TELEMETRY_INTERVAL_MS","MAX_TELEMETRY_BYTES","API_PATHS","TELEMETRY_VERSION","utf8ByteLength"],"mappings":"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","file":"index.cjs","sourcesContent":["export function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined'\n}\n\nexport function nowMs(): number {\n return Date.now()\n}\n\nexport function perfNow(): number {\n return typeof performance !== 'undefined' ? performance.now() : Date.now()\n}\n\n/** Cryptographically secure random id with prefix. */\nexport function secureId(prefix: string, bytes = 16): string {\n const arr = new Uint8Array(bytes)\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n crypto.getRandomValues(arr)\n } else {\n throw new Error('Secure random generation is unavailable')\n }\n let hex = ''\n for (let i = 0; i < arr.length; i++) {\n hex += arr[i]!.toString(16).padStart(2, '0')\n }\n return `${prefix}_${hex}`\n}\n\nexport function debugLog(enabled: boolean, ...args: unknown[]): void {\n if (enabled && typeof console !== 'undefined' && typeof console.debug === 'function') {\n console.debug('[bot-detector-client]', ...args)\n }\n}\n\nexport class IntervalTracker {\n private lastAt: number | null = null\n private sum = 0\n private count = 0\n private min: number | null = null\n private max: number | null = null\n private sumSq = 0\n\n mark(t: number): void {\n if (this.lastAt != null) {\n const interval = t - this.lastAt\n if (interval >= 0) {\n this.sum += interval\n this.sumSq += interval * interval\n this.count += 1\n this.min = this.min == null ? interval : Math.min(this.min, interval)\n this.max = this.max == null ? interval : Math.max(this.max, interval)\n }\n }\n this.lastAt = t\n }\n\n average(): number | null {\n return this.count === 0 ? null : this.sum / this.count\n }\n\n minInterval(): number | null {\n return this.min\n }\n\n maxInterval(): number | null {\n return this.max\n }\n\n variance(): number | null {\n if (this.count < 2) return null\n const mean = this.sum / this.count\n return this.sumSq / this.count - mean * mean\n }\n\n reset(): void {\n this.lastAt = null\n this.sum = 0\n this.count = 0\n this.min = null\n this.max = null\n this.sumSq = 0\n }\n}\n","import type { BrowserSignals } from 'devn-bot-detector-core'\nimport { isBrowser } from '../utils'\n\nfunction getWebglInfo(): { renderer: string | null; vendor: string | null } {\n try {\n if (typeof document === 'undefined') return { renderer: null, vendor: null }\n if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.includes('jsdom')) {\n return { renderer: null, vendor: null }\n }\n const canvas = document.createElement('canvas')\n if (typeof canvas.getContext !== 'function') return { renderer: null, vendor: null }\n const gl = (canvas.getContext('webgl') ||\n canvas.getContext('experimental-webgl')) as WebGLRenderingContext | null\n if (!gl) return { renderer: null, vendor: null }\n const ext = gl.getExtension('WEBGL_debug_renderer_info')\n if (!ext) return { renderer: null, vendor: null }\n const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL)\n const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL)\n return {\n renderer: typeof renderer === 'string' ? renderer.slice(0, 128) : null,\n vendor: typeof vendor === 'string' ? vendor.slice(0, 128) : null,\n }\n } catch {\n return { renderer: null, vendor: null }\n }\n}\n\nexport function collectBrowserSignals(): BrowserSignals {\n if (!isBrowser()) {\n return {\n userAgent: '',\n language: '',\n languagesLength: 0,\n timezone: 'UTC',\n timezoneOffset: 0,\n platform: '',\n screenWidth: 0,\n screenHeight: 0,\n colorDepth: 0,\n devicePixelRatio: 1,\n hardwareConcurrency: null,\n maxTouchPoints: 0,\n cookieEnabled: false,\n webdriver: false,\n }\n }\n\n const nav = navigator as Navigator & { webdriver?: boolean; hardwareConcurrency?: number }\n let timezone = 'UTC'\n try {\n timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'\n } catch {\n // ignore\n }\n\n const webgl = getWebglInfo()\n const hasChrome = Boolean((window as unknown as { chrome?: unknown }).chrome)\n const pluginsCount = typeof nav.plugins !== 'undefined' ? nav.plugins.length : 0\n const screenOrientation =\n typeof screen !== 'undefined' && screen.orientation && screen.orientation.type\n ? screen.orientation.type\n : null\n\n return {\n userAgent: (nav.userAgent || '').slice(0, 512),\n language: (nav.language || '').slice(0, 32),\n languagesLength: Array.isArray(nav.languages) ? nav.languages.length : 0,\n timezone: timezone.slice(0, 64),\n timezoneOffset: new Date().getTimezoneOffset(),\n platform: (nav.platform || '').slice(0, 64),\n screenWidth: typeof screen !== 'undefined' ? screen.width || 0 : 0,\n screenHeight: typeof screen !== 'undefined' ? screen.height || 0 : 0,\n colorDepth: typeof screen !== 'undefined' ? screen.colorDepth || 0 : 0,\n devicePixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1,\n hardwareConcurrency:\n typeof nav.hardwareConcurrency === 'number' ? nav.hardwareConcurrency : null,\n maxTouchPoints: nav.maxTouchPoints || 0,\n cookieEnabled: Boolean(nav.cookieEnabled),\n webdriver: Boolean(nav.webdriver),\n webglRenderer: webgl.renderer,\n webglVendor: webgl.vendor,\n hasChrome,\n pluginsCount,\n screenOrientation,\n }\n}\n\n","import type { PointerSignals } from 'devn-bot-detector-core'\nimport { IntervalTracker, isBrowser, perfNow } from '../utils'\n\nconst IDLE_GAP_MS = 1500\n\nexport class PointerCollector {\n private listening = false\n private eventCount = 0\n private movementDistance = 0\n private directionChanges = 0\n private idlePeriods = 0\n private clickCount = 0\n private activeDuration = 0\n private lastX: number | null = null\n private lastY: number | null = null\n private lastAngle: number | null = null\n private lastEventAt: number | null = null\n private activityStartedAt: number | null = null\n private readonly intervals = new IntervalTracker()\n\n private readonly onMove = (e: PointerEvent | MouseEvent): void => {\n const t = perfNow()\n const x = e.clientX\n const y = e.clientY\n this.eventCount += 1\n this.intervals.mark(t)\n\n if (this.lastEventAt != null && t - this.lastEventAt > IDLE_GAP_MS) {\n this.idlePeriods += 1\n if (this.activityStartedAt != null) {\n this.activeDuration += this.lastEventAt - this.activityStartedAt\n }\n this.activityStartedAt = t\n } else if (this.activityStartedAt == null) {\n this.activityStartedAt = t\n }\n\n if (this.lastX != null && this.lastY != null) {\n const dx = x - this.lastX\n const dy = y - this.lastY\n const dist = Math.hypot(dx, dy)\n this.movementDistance += dist\n if (dist > 2) {\n const angle = Math.atan2(dy, dx)\n if (this.lastAngle != null) {\n let delta = Math.abs(angle - this.lastAngle)\n if (delta > Math.PI) delta = 2 * Math.PI - delta\n if (delta > 0.6) this.directionChanges += 1\n }\n this.lastAngle = angle\n }\n }\n\n this.lastX = x\n this.lastY = y\n this.lastEventAt = t\n // Do not retain coordinate history — only last point for deltas.\n }\n\n private readonly onClick = (): void => {\n this.clickCount += 1\n this.eventCount += 1\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n window.addEventListener('pointermove', this.onMove, { passive: true })\n window.addEventListener('click', this.onClick, { passive: true })\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n window.removeEventListener('pointermove', this.onMove)\n window.removeEventListener('click', this.onClick)\n this.flushActive()\n }\n\n snapshot(): PointerSignals {\n this.flushActive()\n return {\n eventCount: this.eventCount,\n movementDistance: Math.round(this.movementDistance),\n averageInterval: this.intervals.average(),\n minInterval: this.intervals.minInterval(),\n maxInterval: this.intervals.maxInterval(),\n directionChanges: this.directionChanges,\n idlePeriods: this.idlePeriods,\n activeDuration: Math.round(this.activeDuration),\n clickCount: this.clickCount,\n }\n }\n\n reset(): void {\n this.eventCount = 0\n this.movementDistance = 0\n this.directionChanges = 0\n this.idlePeriods = 0\n this.clickCount = 0\n this.activeDuration = 0\n this.lastX = null\n this.lastY = null\n this.lastAngle = null\n this.lastEventAt = null\n this.activityStartedAt = null\n this.intervals.reset()\n }\n\n private flushActive(): void {\n if (this.activityStartedAt != null && this.lastEventAt != null) {\n this.activeDuration += this.lastEventAt - this.activityStartedAt\n this.activityStartedAt = this.lastEventAt\n }\n }\n}\n","import type { KeyboardSignals } from 'devn-bot-detector-core'\nimport { IntervalTracker, isBrowser, perfNow } from '../utils'\n\n/**\n * Keyboard timing only — never reads event.key / event.code / input values.\n */\nexport class KeyboardCollector {\n private listening = false\n private keydownCount = 0\n private keyupCount = 0\n private pasteCount = 0\n private readonly intervals = new IntervalTracker()\n\n private readonly onKeyDown = (): void => {\n this.keydownCount += 1\n this.intervals.mark(perfNow())\n }\n\n private readonly onKeyUp = (): void => {\n this.keyupCount += 1\n }\n\n private readonly onPaste = (): void => {\n // Record that paste happened — never clipboard contents.\n this.pasteCount += 1\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n window.addEventListener('keydown', this.onKeyDown, { passive: true })\n window.addEventListener('keyup', this.onKeyUp, { passive: true })\n window.addEventListener('paste', this.onPaste, { passive: true })\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n window.removeEventListener('keydown', this.onKeyDown)\n window.removeEventListener('keyup', this.onKeyUp)\n window.removeEventListener('paste', this.onPaste)\n }\n\n snapshot(): KeyboardSignals {\n return {\n keydownCount: this.keydownCount,\n keyupCount: this.keyupCount,\n averageInterval: this.intervals.average(),\n minInterval: this.intervals.minInterval(),\n maxInterval: this.intervals.maxInterval(),\n timingVariance: this.intervals.variance(),\n pasteCount: this.pasteCount,\n }\n }\n\n reset(): void {\n this.keydownCount = 0\n this.keyupCount = 0\n this.pasteCount = 0\n this.intervals.reset()\n }\n}\n","import type { TouchSignals } from 'devn-bot-detector-core'\nimport { IntervalTracker, isBrowser, perfNow } from '../utils'\n\nexport class TouchCollector {\n private listening = false\n private touchCount = 0\n private multiTouchCount = 0\n private activeDuration = 0\n private touchStartedAt: number | null = null\n private readonly intervals = new IntervalTracker()\n\n private readonly onStart = (e: TouchEvent): void => {\n const t = perfNow()\n this.touchCount += 1\n this.intervals.mark(t)\n this.touchStartedAt = t\n const touches = e.touches?.length ?? 0\n if (touches > 1) this.multiTouchCount += 1\n }\n\n private readonly onEnd = (): void => {\n if (this.touchStartedAt != null) {\n this.activeDuration += perfNow() - this.touchStartedAt\n this.touchStartedAt = null\n }\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n window.addEventListener('touchstart', this.onStart, { passive: true })\n window.addEventListener('touchend', this.onEnd, { passive: true })\n window.addEventListener('touchcancel', this.onEnd, { passive: true })\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n window.removeEventListener('touchstart', this.onStart)\n window.removeEventListener('touchend', this.onEnd)\n window.removeEventListener('touchcancel', this.onEnd)\n }\n\n snapshot(): TouchSignals {\n return {\n touchCount: this.touchCount,\n averageInterval: this.intervals.average(),\n activeDuration: Math.round(this.activeDuration),\n multiTouchCount: this.multiTouchCount,\n }\n }\n\n reset(): void {\n this.touchCount = 0\n this.multiTouchCount = 0\n this.activeDuration = 0\n this.touchStartedAt = null\n this.intervals.reset()\n }\n}\n","import type { ScrollSignals } from 'devn-bot-detector-core'\nimport { IntervalTracker, isBrowser, perfNow } from '../utils'\n\nexport class ScrollCollector {\n private listening = false\n private scrollCount = 0\n private totalDistance = 0\n private directionChanges = 0\n private activeDuration = 0\n private lastY: number | null = null\n private lastDir: number | null = null\n private lastAt: number | null = null\n private activityStartedAt: number | null = null\n private readonly intervals = new IntervalTracker()\n private scheduled = false\n\n private readonly onScroll = (): void => {\n if (this.scheduled) return\n this.scheduled = true\n const run = (): void => {\n this.scheduled = false\n this.handleScroll()\n }\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(run)\n } else {\n setTimeout(run, 16)\n }\n }\n\n private handleScroll(): void {\n const t = perfNow()\n const y = typeof window !== 'undefined' ? window.scrollY || 0 : 0\n this.scrollCount += 1\n this.intervals.mark(t)\n\n if (this.lastY != null) {\n const dy = y - this.lastY\n this.totalDistance += Math.abs(dy)\n const dir = dy === 0 ? 0 : dy > 0 ? 1 : -1\n if (dir !== 0 && this.lastDir != null && dir !== this.lastDir) {\n this.directionChanges += 1\n }\n if (dir !== 0) this.lastDir = dir\n }\n\n if (this.activityStartedAt == null) this.activityStartedAt = t\n if (this.lastAt != null && t - this.lastAt > 800) {\n this.activeDuration += this.lastAt - this.activityStartedAt\n this.activityStartedAt = t\n }\n\n this.lastY = y\n this.lastAt = t\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n window.addEventListener('scroll', this.onScroll, { passive: true })\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n window.removeEventListener('scroll', this.onScroll)\n if (this.activityStartedAt != null && this.lastAt != null) {\n this.activeDuration += this.lastAt - this.activityStartedAt\n this.activityStartedAt = this.lastAt\n }\n }\n\n snapshot(): ScrollSignals {\n return {\n scrollCount: this.scrollCount,\n averageInterval: this.intervals.average(),\n totalDistance: Math.round(this.totalDistance),\n directionChanges: this.directionChanges,\n activeDuration: Math.round(this.activeDuration),\n }\n }\n\n reset(): void {\n this.scrollCount = 0\n this.totalDistance = 0\n this.directionChanges = 0\n this.activeDuration = 0\n this.lastY = null\n this.lastDir = null\n this.lastAt = null\n this.activityStartedAt = null\n this.intervals.reset()\n }\n}\n","import type { FocusSignals } from 'devn-bot-detector-core'\nimport { isBrowser } from '../utils'\n\nexport class FocusCollector {\n private listening = false\n private focusCount = 0\n private blurCount = 0\n\n private readonly onFocus = (): void => {\n this.focusCount += 1\n }\n\n private readonly onBlur = (): void => {\n this.blurCount += 1\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n window.addEventListener('focus', this.onFocus)\n window.addEventListener('blur', this.onBlur)\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n window.removeEventListener('focus', this.onFocus)\n window.removeEventListener('blur', this.onBlur)\n }\n\n snapshot(): FocusSignals {\n return {\n focusCount: this.focusCount,\n blurCount: this.blurCount,\n }\n }\n\n reset(): void {\n this.focusCount = 0\n this.blurCount = 0\n }\n}\n","import type { VisibilitySignals } from 'devn-bot-detector-core'\nimport { isBrowser, nowMs } from '../utils'\n\nexport class VisibilityCollector {\n private listening = false\n private visibilityChanges = 0\n private visibleDuration = 0\n private hiddenDuration = 0\n private segmentStartedAt = nowMs()\n private currentlyHidden = false\n\n private readonly onChange = (): void => {\n const t = nowMs()\n const elapsed = t - this.segmentStartedAt\n if (this.currentlyHidden) this.hiddenDuration += elapsed\n else this.visibleDuration += elapsed\n this.currentlyHidden = document.visibilityState === 'hidden'\n this.segmentStartedAt = t\n this.visibilityChanges += 1\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n this.currentlyHidden = document.visibilityState === 'hidden'\n this.segmentStartedAt = nowMs()\n document.addEventListener('visibilitychange', this.onChange)\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n document.removeEventListener('visibilitychange', this.onChange)\n this.flush()\n }\n\n snapshot(): VisibilitySignals {\n this.flush()\n return {\n visibilityChanges: this.visibilityChanges,\n visibleDuration: Math.round(this.visibleDuration),\n hiddenDuration: Math.round(this.hiddenDuration),\n }\n }\n\n reset(): void {\n this.visibilityChanges = 0\n this.visibleDuration = 0\n this.hiddenDuration = 0\n this.segmentStartedAt = nowMs()\n this.currentlyHidden = isBrowser() ? document.visibilityState === 'hidden' : false\n }\n\n private flush(): void {\n const t = nowMs()\n const elapsed = t - this.segmentStartedAt\n if (this.currentlyHidden) this.hiddenDuration += elapsed\n else this.visibleDuration += elapsed\n this.segmentStartedAt = t\n }\n}\n","import type { InteractionSignals } from 'devn-bot-detector-core'\nimport { isBrowser, nowMs } from '../utils'\n\nexport class InteractionCollector {\n private listening = false\n private pageLoadTime = nowMs()\n private firstInteractionTime: number | null = null\n private clickCount = 0\n private interactionCount = 0\n private formInteractionCount = 0\n private scrollCount = 0\n private focusCount = 0\n\n private readonly markInteraction = (): void => {\n if (this.firstInteractionTime == null) {\n this.firstInteractionTime = nowMs()\n }\n this.interactionCount += 1\n }\n\n private readonly onClick = (): void => {\n this.clickCount += 1\n this.markInteraction()\n }\n\n private readonly onKey = (): void => {\n this.markInteraction()\n }\n\n private readonly onTouch = (): void => {\n this.markInteraction()\n }\n\n private readonly onScroll = (): void => {\n this.scrollCount += 1\n this.markInteraction()\n }\n\n private readonly onFocusIn = (e: FocusEvent): void => {\n this.focusCount += 1\n const target = e.target\n if (\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n target instanceof HTMLSelectElement\n ) {\n // Count only — never read values.\n this.formInteractionCount += 1\n }\n }\n\n start(): void {\n if (this.listening || !isBrowser()) return\n this.listening = true\n this.pageLoadTime = nowMs()\n window.addEventListener('click', this.onClick, { passive: true })\n window.addEventListener('keydown', this.onKey, { passive: true })\n window.addEventListener('touchstart', this.onTouch, { passive: true })\n window.addEventListener('scroll', this.onScroll, { passive: true })\n document.addEventListener('focusin', this.onFocusIn, { passive: true })\n }\n\n stop(): void {\n if (!this.listening || !isBrowser()) return\n this.listening = false\n window.removeEventListener('click', this.onClick)\n window.removeEventListener('keydown', this.onKey)\n window.removeEventListener('touchstart', this.onTouch)\n window.removeEventListener('scroll', this.onScroll)\n document.removeEventListener('focusin', this.onFocusIn)\n }\n\n snapshot(): InteractionSignals {\n return {\n pageLoadTime: this.pageLoadTime,\n firstInteractionTime: this.firstInteractionTime,\n timeToFirstInteraction:\n this.firstInteractionTime != null\n ? this.firstInteractionTime - this.pageLoadTime\n : null,\n clickCount: this.clickCount,\n interactionCount: this.interactionCount,\n formInteractionCount: this.formInteractionCount,\n scrollCount: this.scrollCount,\n focusCount: this.focusCount,\n }\n }\n\n reset(): void {\n this.pageLoadTime = nowMs()\n this.firstInteractionTime = null\n this.clickCount = 0\n this.interactionCount = 0\n this.formInteractionCount = 0\n this.scrollCount = 0\n this.focusCount = 0\n }\n}\n","import type { ClientSession } from 'devn-bot-detector-core'\nimport { DEFAULT_SESSION_DURATION_MS } from 'devn-bot-detector-core'\nimport { nowMs, secureId } from './utils'\n\nexport function createLocalSession(sessionDurationMs = DEFAULT_SESSION_DURATION_MS): ClientSession {\n const createdAt = nowMs()\n return {\n sessionId: secureId('ses'),\n nonce: secureId('nonce', 12),\n createdAt,\n expiresAt: createdAt + sessionDurationMs,\n }\n}\n\nexport function isSessionExpired(session: ClientSession, now = nowMs()): boolean {\n return now >= session.expiresAt\n}\n\nexport function rotateNonce(session: ClientSession): ClientSession {\n return {\n ...session,\n nonce: secureId('nonce', 12),\n }\n}\n","import { SITE_KEY_HEADER, type ClientCredentialsMode } from 'devn-bot-detector-core'\n\nexport interface HttpTransportOptions {\n readonly baseUrl: string\n readonly siteKey: string\n readonly timeoutMs?: number\n readonly headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n readonly fetchFn?: typeof fetch\n readonly credentials?: ClientCredentialsMode\n readonly retries?: number\n readonly retryDelayMs?: number\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport class HttpTransport {\n private readonly baseUrl: string\n private readonly siteKey: string\n private readonly timeoutMs: number\n private readonly headersProvider?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>)\n private readonly fetchFn: typeof fetch\n private readonly credentials: ClientCredentialsMode\n private readonly retries: number\n private readonly retryDelayMs: number\n\n constructor(options: HttpTransportOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.siteKey = options.siteKey\n this.timeoutMs = options.timeoutMs ?? 10_000\n this.headersProvider = options.headers\n this.fetchFn = options.fetchFn ?? ((...args) => fetch(...args))\n this.credentials = options.credentials ?? 'omit'\n this.retries = Math.max(0, options.retries ?? 0)\n this.retryDelayMs = options.retryDelayMs ?? 300\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.executeWithRetry<T>('POST', path, body)\n }\n\n async get<T>(path: string): Promise<T> {\n return this.executeWithRetry<T>('GET', path)\n }\n\n private async resolveHeaders(): Promise<Record<string, string>> {\n if (!this.headersProvider) return {}\n if (typeof this.headersProvider === 'function') {\n return (await this.headersProvider()) ?? {}\n }\n return this.headersProvider\n }\n\n private async executeWithRetry<T>(method: string, path: string, body?: unknown): Promise<T> {\n let lastError: unknown\n for (let attempt = 0; attempt <= this.retries; attempt++) {\n try {\n return await this.request<T>(method, path, body)\n } catch (err) {\n lastError = err\n if (attempt < this.retries) {\n const delay = this.retryDelayMs * Math.pow(2, attempt)\n await wait(delay)\n }\n }\n }\n throw lastError\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), this.timeoutMs)\n try {\n const customHeaders = await this.resolveHeaders()\n const res = await this.fetchFn(`${this.baseUrl}${path}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n [SITE_KEY_HEADER]: this.siteKey,\n ...customHeaders,\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n credentials: this.credentials,\n })\n\n const text = await res.text()\n let data: unknown = null\n if (text) {\n try {\n data = JSON.parse(text) as unknown\n } catch {\n throw new Error(`Invalid JSON response (${res.status})`)\n }\n }\n\n if (!res.ok) {\n const message =\n typeof data === 'object' &&\n data !== null &&\n 'error' in data &&\n typeof (data as { error?: { message?: unknown } }).error?.message === 'string'\n ? (data as { error: { message: string } }).error.message\n : `HTTP ${res.status}`\n throw new Error(message)\n }\n\n return data as T\n } finally {\n clearTimeout(timer)\n }\n }\n}\n\n","import {\n API_PATHS,\n DEFAULT_SESSION_DURATION_MS,\n DEFAULT_TELEMETRY_INTERVAL_MS,\n MAX_TELEMETRY_BYTES,\n TELEMETRY_VERSION,\n utf8ByteLength,\n type AnalyzeResponse,\n type CheckOptions,\n type ClientConfig,\n type ClientSession,\n type CreateSessionResponse,\n type RiskResult,\n type Telemetry,\n} from 'devn-bot-detector-core'\nimport {\n FocusCollector,\n InteractionCollector,\n KeyboardCollector,\n PointerCollector,\n ScrollCollector,\n TouchCollector,\n VisibilityCollector,\n collectBrowserSignals,\n} from './collectors'\nimport { createLocalSession, isSessionExpired, rotateNonce } from './session'\nimport { HttpTransport } from './transport'\nimport { debugLog, isBrowser, nowMs } from './utils'\n\ntype ResolvedClientConfig = Required<\n Pick<\n ClientConfig,\n | 'siteKey'\n | 'endpoint'\n | 'autoStart'\n | 'telemetryInterval'\n | 'sessionDuration'\n | 'collectPointer'\n | 'collectKeyboardTiming'\n | 'collectTouch'\n | 'collectScroll'\n | 'collectFocus'\n | 'collectVisibility'\n | 'collectBrowser'\n | 'failOpen'\n | 'maxTelemetryBytes'\n | 'debug'\n | 'sampleRate'\n >\n> & {\n readonly headers?: ClientConfig['headers']\n readonly fetchFn?: ClientConfig['fetchFn']\n readonly credentials?: ClientConfig['credentials']\n readonly timeoutMs?: number\n readonly retries?: number\n readonly retryDelayMs?: number\n readonly onSessionCreated?: ClientConfig['onSessionCreated']\n readonly onCheck?: ClientConfig['onCheck']\n readonly onError?: ClientConfig['onError']\n}\n\nfunction resolveConfig(config: ClientConfig): ResolvedClientConfig {\n if (!config.siteKey) throw new Error('BotDetector requires siteKey')\n if (!config.endpoint) throw new Error('BotDetector requires endpoint')\n return {\n siteKey: config.siteKey,\n endpoint: config.endpoint.replace(/\\/$/, ''),\n autoStart: config.autoStart ?? true,\n telemetryInterval: config.telemetryInterval ?? DEFAULT_TELEMETRY_INTERVAL_MS,\n sessionDuration: config.sessionDuration ?? DEFAULT_SESSION_DURATION_MS,\n collectPointer: config.collectPointer ?? true,\n collectKeyboardTiming: config.collectKeyboardTiming ?? true,\n collectTouch: config.collectTouch ?? true,\n collectScroll: config.collectScroll ?? true,\n collectFocus: config.collectFocus ?? true,\n collectVisibility: config.collectVisibility ?? true,\n collectBrowser: config.collectBrowser ?? true,\n failOpen: config.failOpen ?? true,\n maxTelemetryBytes: config.maxTelemetryBytes ?? MAX_TELEMETRY_BYTES,\n debug: config.debug ?? false,\n sampleRate: Math.max(0, Math.min(1, config.sampleRate ?? 1)),\n headers: config.headers,\n fetchFn: config.fetchFn,\n credentials: config.credentials,\n timeoutMs: config.timeoutMs,\n retries: config.retries,\n retryDelayMs: config.retryDelayMs,\n onSessionCreated: config.onSessionCreated,\n onCheck: config.onCheck,\n onError: config.onError,\n }\n}\n\n/**\n * Browser behavioral telemetry SDK.\n * Collects aggregated signals and asks your backend to score risk.\n */\nexport class BotDetector {\n private readonly config: ResolvedClientConfig\n private readonly transport: HttpTransport\n private readonly pointer = new PointerCollector()\n private readonly keyboard = new KeyboardCollector()\n private readonly touch = new TouchCollector()\n private readonly scroll = new ScrollCollector()\n private readonly focus = new FocusCollector()\n private readonly visibility = new VisibilityCollector()\n private readonly interaction = new InteractionCollector()\n\n private session: ClientSession | null = null\n private sequence = 0\n private running = false\n private paused = false\n private destroyed = false\n private flushTimer: ReturnType<typeof setInterval> | null = null\n private startPromise: Promise<void> | null = null\n\n constructor(config: ClientConfig) {\n this.config = resolveConfig(config)\n this.transport = new HttpTransport({\n baseUrl: this.config.endpoint,\n siteKey: this.config.siteKey,\n headers: this.config.headers,\n fetchFn: this.config.fetchFn,\n credentials: this.config.credentials,\n timeoutMs: this.config.timeoutMs,\n retries: this.config.retries,\n retryDelayMs: this.config.retryDelayMs,\n })\n if (this.config.autoStart && isBrowser()) {\n void this.start()\n }\n }\n\n async start(): Promise<void> {\n if (this.destroyed) throw new Error('BotDetector has been destroyed')\n if (this.running) return\n if (this.startPromise) return this.startPromise\n\n this.startPromise = this.doStart()\n try {\n await this.startPromise\n } finally {\n this.startPromise = null\n }\n }\n\n private async doStart(): Promise<void> {\n if (!isBrowser()) {\n debugLog(this.config.debug, 'start() outside browser — collectors skipped')\n return\n }\n\n this.attachCollectors()\n this.running = true\n await this.ensureSession()\n this.scheduleFlush()\n debugLog(this.config.debug, 'started', { sessionId: this.session?.sessionId })\n }\n\n /** Temporarily pause active collectors (e.g. background tab or navigation). */\n pause(): void {\n if (!this.running || this.paused || this.destroyed) return\n this.detachCollectors()\n this.paused = true\n debugLog(this.config.debug, 'paused')\n }\n\n /** Resume collecting signals after pausing. */\n resume(): void {\n if (!this.running || !this.paused || this.destroyed) return\n this.attachCollectors()\n this.paused = false\n debugLog(this.config.debug, 'resumed')\n }\n\n isPaused(): boolean {\n return this.paused\n }\n\n isRunning(): boolean {\n return this.running && !this.destroyed\n }\n\n /**\n * Collect telemetry and analyze risk via the configured endpoint.\n * On network failure with failOpen=true, returns a monitor decision.\n */\n async check(options?: CheckOptions): Promise<RiskResult> {\n if (this.destroyed) throw new Error('BotDetector has been destroyed')\n if (!this.running) await this.start()\n\n if (this.config.sampleRate < 1 && Math.random() > this.config.sampleRate) {\n debugLog(this.config.debug, 'skipped check due to sampleRate')\n const sampled = this.fallbackResult('allow', 95)\n this.config.onCheck?.(sampled)\n return sampled\n }\n\n try {\n await this.ensureSession()\n const session = this.session\n if (!session) throw new Error('No session')\n\n this.sequence += 1\n const telemetry = this.getTelemetry()\n const body: Record<string, unknown> = {\n sessionId: session.sessionId,\n sequence: this.sequence,\n nonce: session.nonce,\n timestamp: nowMs(),\n hostname: isBrowser() ? location.hostname : '',\n telemetry,\n }\n if (options?.action) body.action = options.action\n if (options?.metadata) body.metadata = options.metadata\n\n debugLog(this.config.debug, 'analyze request', {\n sessionId: session.sessionId,\n sequence: this.sequence,\n action: options?.action,\n })\n\n const result = await this.transport.post<AnalyzeResponse>(API_PATHS.analyze, body)\n this.session = rotateNonce(session)\n this.config.onCheck?.(result)\n return result\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(String(err))\n this.config.onError?.(errorObj)\n debugLog(this.config.debug, 'check failed', errorObj.message)\n if (this.config.failOpen) {\n const fallback = this.fallbackResult('monitor')\n this.config.onCheck?.(fallback)\n return fallback\n }\n throw err\n }\n }\n\n /** Shorthand for check({ action, metadata }). */\n async checkAction(action: string, metadata?: Record<string, unknown>): Promise<RiskResult> {\n return this.check({ action, metadata })\n }\n\n\n getSession(): ClientSession | null {\n return this.session\n }\n\n getTelemetry(): Telemetry {\n const telemetry: Telemetry = {\n version: TELEMETRY_VERSION,\n ...(this.config.collectBrowser ? { browser: collectBrowserSignals() } : {}),\n ...(this.config.collectPointer ? { pointer: this.pointer.snapshot() } : {}),\n ...(this.config.collectKeyboardTiming ? { keyboard: this.keyboard.snapshot() } : {}),\n ...(this.config.collectTouch ? { touch: this.touch.snapshot() } : {}),\n ...(this.config.collectScroll ? { scroll: this.scroll.snapshot() } : {}),\n ...(this.config.collectFocus ? { focus: this.focus.snapshot() } : {}),\n ...(this.config.collectVisibility ? { visibility: this.visibility.snapshot() } : {}),\n interaction: this.interaction.snapshot(),\n }\n\n return this.enforceSize(telemetry)\n }\n\n reset(): void {\n this.pointer.reset()\n this.keyboard.reset()\n this.touch.reset()\n this.scroll.reset()\n this.focus.reset()\n this.visibility.reset()\n this.interaction.reset()\n this.sequence = 0\n }\n\n /** Remove listeners, timers, and clear state. */\n destroy(): void {\n this.destroyed = true\n this.running = false\n this.clearFlush()\n this.detachCollectors()\n this.session = null\n this.reset()\n debugLog(this.config.debug, 'destroyed')\n }\n\n private attachCollectors(): void {\n if (this.config.collectPointer) this.pointer.start()\n if (this.config.collectKeyboardTiming) this.keyboard.start()\n if (this.config.collectTouch) this.touch.start()\n if (this.config.collectScroll) this.scroll.start()\n if (this.config.collectFocus) this.focus.start()\n if (this.config.collectVisibility) this.visibility.start()\n this.interaction.start()\n }\n\n private detachCollectors(): void {\n this.pointer.stop()\n this.keyboard.stop()\n this.touch.stop()\n this.scroll.stop()\n this.focus.stop()\n this.visibility.stop()\n this.interaction.stop()\n }\n\n private async ensureSession(): Promise<void> {\n if (this.session && !isSessionExpired(this.session)) return\n\n try {\n const response = await this.transport.post<CreateSessionResponse>(API_PATHS.session, {\n hostname: isBrowser() ? location.hostname : '',\n userAgent: isBrowser() ? navigator.userAgent.slice(0, 512) : '',\n timestamp: nowMs(),\n })\n\n this.session = {\n sessionId: response.sessionId,\n nonce: response.nonce,\n createdAt: nowMs(),\n expiresAt: Date.parse(response.expiresAt) || nowMs() + this.config.sessionDuration,\n }\n this.sequence = 0\n debugLog(this.config.debug, 'session created', { sessionId: this.session.sessionId })\n this.config.onSessionCreated?.(this.session)\n } catch (err) {\n debugLog(this.config.debug, 'session API failed, using local session')\n // Local fallback session — analyze will also fail-open if endpoint is down.\n this.session = createLocalSession(this.config.sessionDuration)\n this.sequence = 0\n this.config.onSessionCreated?.(this.session)\n if (!this.config.failOpen) throw err\n }\n }\n\n private scheduleFlush(): void {\n this.clearFlush()\n if (this.config.telemetryInterval <= 0) return\n this.flushTimer = setInterval(() => {\n // Keep aggregation warm; no network unless check() is called.\n void this.getTelemetry()\n }, this.config.telemetryInterval)\n }\n\n private clearFlush(): void {\n if (this.flushTimer != null) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n }\n\n private enforceSize(telemetry: Telemetry): Telemetry {\n const fits = (value: Telemetry): boolean =>\n utf8ByteLength(JSON.stringify(value)) <= this.config.maxTelemetryBytes\n\n if (fits(telemetry)) return telemetry\n\n const candidates: Telemetry[] = [\n {\n version: TELEMETRY_VERSION,\n interaction: telemetry.interaction,\n browser: telemetry.browser,\n },\n {\n version: TELEMETRY_VERSION,\n interaction: telemetry.interaction,\n },\n { version: TELEMETRY_VERSION },\n ]\n\n for (const candidate of candidates) {\n if (fits(candidate)) return candidate\n }\n\n return { version: TELEMETRY_VERSION }\n }\n\n private fallbackResult(decision: RiskResult['decision'], score?: number): RiskResult {\n return {\n requestId: `req_fallback_${nowMs()}`,\n score: score ?? (decision === 'monitor' ? 55 : decision === 'allow' ? 90 : 50),\n confidence: 0.3,\n decision,\n riskLevel: decision === 'allow' ? 'low' : 'medium',\n timestamp: nowMs(),\n }\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { ClientConfig, CheckOptions, RiskResult, ClientSession, Telemetry, ClientCredentialsMode, BrowserSignals, PointerSignals, KeyboardSignals, TouchSignals, ScrollSignals, FocusSignals, VisibilitySignals, InteractionSignals } from 'devn-bot-detector-core';
|
|
2
|
+
export { CheckOptions, ClientConfig, ClientSession, RiskResult, Telemetry } from 'devn-bot-detector-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Browser behavioral telemetry SDK.
|
|
6
|
+
* Collects aggregated signals and asks your backend to score risk.
|
|
7
|
+
*/
|
|
8
|
+
declare class BotDetector {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly transport;
|
|
11
|
+
private readonly pointer;
|
|
12
|
+
private readonly keyboard;
|
|
13
|
+
private readonly touch;
|
|
14
|
+
private readonly scroll;
|
|
15
|
+
private readonly focus;
|
|
16
|
+
private readonly visibility;
|
|
17
|
+
private readonly interaction;
|
|
18
|
+
private session;
|
|
19
|
+
private sequence;
|
|
20
|
+
private running;
|
|
21
|
+
private paused;
|
|
22
|
+
private destroyed;
|
|
23
|
+
private flushTimer;
|
|
24
|
+
private startPromise;
|
|
25
|
+
constructor(config: ClientConfig);
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
private doStart;
|
|
28
|
+
/** Temporarily pause active collectors (e.g. background tab or navigation). */
|
|
29
|
+
pause(): void;
|
|
30
|
+
/** Resume collecting signals after pausing. */
|
|
31
|
+
resume(): void;
|
|
32
|
+
isPaused(): boolean;
|
|
33
|
+
isRunning(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Collect telemetry and analyze risk via the configured endpoint.
|
|
36
|
+
* On network failure with failOpen=true, returns a monitor decision.
|
|
37
|
+
*/
|
|
38
|
+
check(options?: CheckOptions): Promise<RiskResult>;
|
|
39
|
+
/** Shorthand for check({ action, metadata }). */
|
|
40
|
+
checkAction(action: string, metadata?: Record<string, unknown>): Promise<RiskResult>;
|
|
41
|
+
getSession(): ClientSession | null;
|
|
42
|
+
getTelemetry(): Telemetry;
|
|
43
|
+
reset(): void;
|
|
44
|
+
/** Remove listeners, timers, and clear state. */
|
|
45
|
+
destroy(): void;
|
|
46
|
+
private attachCollectors;
|
|
47
|
+
private detachCollectors;
|
|
48
|
+
private ensureSession;
|
|
49
|
+
private scheduleFlush;
|
|
50
|
+
private clearFlush;
|
|
51
|
+
private enforceSize;
|
|
52
|
+
private fallbackResult;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface HttpTransportOptions {
|
|
56
|
+
readonly baseUrl: string;
|
|
57
|
+
readonly siteKey: string;
|
|
58
|
+
readonly timeoutMs?: number;
|
|
59
|
+
readonly headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
60
|
+
readonly fetchFn?: typeof fetch;
|
|
61
|
+
readonly credentials?: ClientCredentialsMode;
|
|
62
|
+
readonly retries?: number;
|
|
63
|
+
readonly retryDelayMs?: number;
|
|
64
|
+
}
|
|
65
|
+
declare class HttpTransport {
|
|
66
|
+
private readonly baseUrl;
|
|
67
|
+
private readonly siteKey;
|
|
68
|
+
private readonly timeoutMs;
|
|
69
|
+
private readonly headersProvider?;
|
|
70
|
+
private readonly fetchFn;
|
|
71
|
+
private readonly credentials;
|
|
72
|
+
private readonly retries;
|
|
73
|
+
private readonly retryDelayMs;
|
|
74
|
+
constructor(options: HttpTransportOptions);
|
|
75
|
+
post<T>(path: string, body: unknown): Promise<T>;
|
|
76
|
+
get<T>(path: string): Promise<T>;
|
|
77
|
+
private resolveHeaders;
|
|
78
|
+
private executeWithRetry;
|
|
79
|
+
private request;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare function createLocalSession(sessionDurationMs?: number): ClientSession;
|
|
83
|
+
declare function isSessionExpired(session: ClientSession, now?: number): boolean;
|
|
84
|
+
|
|
85
|
+
declare function collectBrowserSignals(): BrowserSignals;
|
|
86
|
+
|
|
87
|
+
declare class PointerCollector {
|
|
88
|
+
private listening;
|
|
89
|
+
private eventCount;
|
|
90
|
+
private movementDistance;
|
|
91
|
+
private directionChanges;
|
|
92
|
+
private idlePeriods;
|
|
93
|
+
private clickCount;
|
|
94
|
+
private activeDuration;
|
|
95
|
+
private lastX;
|
|
96
|
+
private lastY;
|
|
97
|
+
private lastAngle;
|
|
98
|
+
private lastEventAt;
|
|
99
|
+
private activityStartedAt;
|
|
100
|
+
private readonly intervals;
|
|
101
|
+
private readonly onMove;
|
|
102
|
+
private readonly onClick;
|
|
103
|
+
start(): void;
|
|
104
|
+
stop(): void;
|
|
105
|
+
snapshot(): PointerSignals;
|
|
106
|
+
reset(): void;
|
|
107
|
+
private flushActive;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Keyboard timing only — never reads event.key / event.code / input values.
|
|
112
|
+
*/
|
|
113
|
+
declare class KeyboardCollector {
|
|
114
|
+
private listening;
|
|
115
|
+
private keydownCount;
|
|
116
|
+
private keyupCount;
|
|
117
|
+
private pasteCount;
|
|
118
|
+
private readonly intervals;
|
|
119
|
+
private readonly onKeyDown;
|
|
120
|
+
private readonly onKeyUp;
|
|
121
|
+
private readonly onPaste;
|
|
122
|
+
start(): void;
|
|
123
|
+
stop(): void;
|
|
124
|
+
snapshot(): KeyboardSignals;
|
|
125
|
+
reset(): void;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
declare class TouchCollector {
|
|
129
|
+
private listening;
|
|
130
|
+
private touchCount;
|
|
131
|
+
private multiTouchCount;
|
|
132
|
+
private activeDuration;
|
|
133
|
+
private touchStartedAt;
|
|
134
|
+
private readonly intervals;
|
|
135
|
+
private readonly onStart;
|
|
136
|
+
private readonly onEnd;
|
|
137
|
+
start(): void;
|
|
138
|
+
stop(): void;
|
|
139
|
+
snapshot(): TouchSignals;
|
|
140
|
+
reset(): void;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class ScrollCollector {
|
|
144
|
+
private listening;
|
|
145
|
+
private scrollCount;
|
|
146
|
+
private totalDistance;
|
|
147
|
+
private directionChanges;
|
|
148
|
+
private activeDuration;
|
|
149
|
+
private lastY;
|
|
150
|
+
private lastDir;
|
|
151
|
+
private lastAt;
|
|
152
|
+
private activityStartedAt;
|
|
153
|
+
private readonly intervals;
|
|
154
|
+
private scheduled;
|
|
155
|
+
private readonly onScroll;
|
|
156
|
+
private handleScroll;
|
|
157
|
+
start(): void;
|
|
158
|
+
stop(): void;
|
|
159
|
+
snapshot(): ScrollSignals;
|
|
160
|
+
reset(): void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
declare class FocusCollector {
|
|
164
|
+
private listening;
|
|
165
|
+
private focusCount;
|
|
166
|
+
private blurCount;
|
|
167
|
+
private readonly onFocus;
|
|
168
|
+
private readonly onBlur;
|
|
169
|
+
start(): void;
|
|
170
|
+
stop(): void;
|
|
171
|
+
snapshot(): FocusSignals;
|
|
172
|
+
reset(): void;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
declare class VisibilityCollector {
|
|
176
|
+
private listening;
|
|
177
|
+
private visibilityChanges;
|
|
178
|
+
private visibleDuration;
|
|
179
|
+
private hiddenDuration;
|
|
180
|
+
private segmentStartedAt;
|
|
181
|
+
private currentlyHidden;
|
|
182
|
+
private readonly onChange;
|
|
183
|
+
start(): void;
|
|
184
|
+
stop(): void;
|
|
185
|
+
snapshot(): VisibilitySignals;
|
|
186
|
+
reset(): void;
|
|
187
|
+
private flush;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
declare class InteractionCollector {
|
|
191
|
+
private listening;
|
|
192
|
+
private pageLoadTime;
|
|
193
|
+
private firstInteractionTime;
|
|
194
|
+
private clickCount;
|
|
195
|
+
private interactionCount;
|
|
196
|
+
private formInteractionCount;
|
|
197
|
+
private scrollCount;
|
|
198
|
+
private focusCount;
|
|
199
|
+
private readonly markInteraction;
|
|
200
|
+
private readonly onClick;
|
|
201
|
+
private readonly onKey;
|
|
202
|
+
private readonly onTouch;
|
|
203
|
+
private readonly onScroll;
|
|
204
|
+
private readonly onFocusIn;
|
|
205
|
+
start(): void;
|
|
206
|
+
stop(): void;
|
|
207
|
+
snapshot(): InteractionSignals;
|
|
208
|
+
reset(): void;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export { BotDetector, FocusCollector, HttpTransport, InteractionCollector, KeyboardCollector, PointerCollector, ScrollCollector, TouchCollector, VisibilityCollector, collectBrowserSignals, createLocalSession, isSessionExpired };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { ClientConfig, CheckOptions, RiskResult, ClientSession, Telemetry, ClientCredentialsMode, BrowserSignals, PointerSignals, KeyboardSignals, TouchSignals, ScrollSignals, FocusSignals, VisibilitySignals, InteractionSignals } from 'devn-bot-detector-core';
|
|
2
|
+
export { CheckOptions, ClientConfig, ClientSession, RiskResult, Telemetry } from 'devn-bot-detector-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Browser behavioral telemetry SDK.
|
|
6
|
+
* Collects aggregated signals and asks your backend to score risk.
|
|
7
|
+
*/
|
|
8
|
+
declare class BotDetector {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly transport;
|
|
11
|
+
private readonly pointer;
|
|
12
|
+
private readonly keyboard;
|
|
13
|
+
private readonly touch;
|
|
14
|
+
private readonly scroll;
|
|
15
|
+
private readonly focus;
|
|
16
|
+
private readonly visibility;
|
|
17
|
+
private readonly interaction;
|
|
18
|
+
private session;
|
|
19
|
+
private sequence;
|
|
20
|
+
private running;
|
|
21
|
+
private paused;
|
|
22
|
+
private destroyed;
|
|
23
|
+
private flushTimer;
|
|
24
|
+
private startPromise;
|
|
25
|
+
constructor(config: ClientConfig);
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
private doStart;
|
|
28
|
+
/** Temporarily pause active collectors (e.g. background tab or navigation). */
|
|
29
|
+
pause(): void;
|
|
30
|
+
/** Resume collecting signals after pausing. */
|
|
31
|
+
resume(): void;
|
|
32
|
+
isPaused(): boolean;
|
|
33
|
+
isRunning(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Collect telemetry and analyze risk via the configured endpoint.
|
|
36
|
+
* On network failure with failOpen=true, returns a monitor decision.
|
|
37
|
+
*/
|
|
38
|
+
check(options?: CheckOptions): Promise<RiskResult>;
|
|
39
|
+
/** Shorthand for check({ action, metadata }). */
|
|
40
|
+
checkAction(action: string, metadata?: Record<string, unknown>): Promise<RiskResult>;
|
|
41
|
+
getSession(): ClientSession | null;
|
|
42
|
+
getTelemetry(): Telemetry;
|
|
43
|
+
reset(): void;
|
|
44
|
+
/** Remove listeners, timers, and clear state. */
|
|
45
|
+
destroy(): void;
|
|
46
|
+
private attachCollectors;
|
|
47
|
+
private detachCollectors;
|
|
48
|
+
private ensureSession;
|
|
49
|
+
private scheduleFlush;
|
|
50
|
+
private clearFlush;
|
|
51
|
+
private enforceSize;
|
|
52
|
+
private fallbackResult;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface HttpTransportOptions {
|
|
56
|
+
readonly baseUrl: string;
|
|
57
|
+
readonly siteKey: string;
|
|
58
|
+
readonly timeoutMs?: number;
|
|
59
|
+
readonly headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
60
|
+
readonly fetchFn?: typeof fetch;
|
|
61
|
+
readonly credentials?: ClientCredentialsMode;
|
|
62
|
+
readonly retries?: number;
|
|
63
|
+
readonly retryDelayMs?: number;
|
|
64
|
+
}
|
|
65
|
+
declare class HttpTransport {
|
|
66
|
+
private readonly baseUrl;
|
|
67
|
+
private readonly siteKey;
|
|
68
|
+
private readonly timeoutMs;
|
|
69
|
+
private readonly headersProvider?;
|
|
70
|
+
private readonly fetchFn;
|
|
71
|
+
private readonly credentials;
|
|
72
|
+
private readonly retries;
|
|
73
|
+
private readonly retryDelayMs;
|
|
74
|
+
constructor(options: HttpTransportOptions);
|
|
75
|
+
post<T>(path: string, body: unknown): Promise<T>;
|
|
76
|
+
get<T>(path: string): Promise<T>;
|
|
77
|
+
private resolveHeaders;
|
|
78
|
+
private executeWithRetry;
|
|
79
|
+
private request;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare function createLocalSession(sessionDurationMs?: number): ClientSession;
|
|
83
|
+
declare function isSessionExpired(session: ClientSession, now?: number): boolean;
|
|
84
|
+
|
|
85
|
+
declare function collectBrowserSignals(): BrowserSignals;
|
|
86
|
+
|
|
87
|
+
declare class PointerCollector {
|
|
88
|
+
private listening;
|
|
89
|
+
private eventCount;
|
|
90
|
+
private movementDistance;
|
|
91
|
+
private directionChanges;
|
|
92
|
+
private idlePeriods;
|
|
93
|
+
private clickCount;
|
|
94
|
+
private activeDuration;
|
|
95
|
+
private lastX;
|
|
96
|
+
private lastY;
|
|
97
|
+
private lastAngle;
|
|
98
|
+
private lastEventAt;
|
|
99
|
+
private activityStartedAt;
|
|
100
|
+
private readonly intervals;
|
|
101
|
+
private readonly onMove;
|
|
102
|
+
private readonly onClick;
|
|
103
|
+
start(): void;
|
|
104
|
+
stop(): void;
|
|
105
|
+
snapshot(): PointerSignals;
|
|
106
|
+
reset(): void;
|
|
107
|
+
private flushActive;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Keyboard timing only — never reads event.key / event.code / input values.
|
|
112
|
+
*/
|
|
113
|
+
declare class KeyboardCollector {
|
|
114
|
+
private listening;
|
|
115
|
+
private keydownCount;
|
|
116
|
+
private keyupCount;
|
|
117
|
+
private pasteCount;
|
|
118
|
+
private readonly intervals;
|
|
119
|
+
private readonly onKeyDown;
|
|
120
|
+
private readonly onKeyUp;
|
|
121
|
+
private readonly onPaste;
|
|
122
|
+
start(): void;
|
|
123
|
+
stop(): void;
|
|
124
|
+
snapshot(): KeyboardSignals;
|
|
125
|
+
reset(): void;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
declare class TouchCollector {
|
|
129
|
+
private listening;
|
|
130
|
+
private touchCount;
|
|
131
|
+
private multiTouchCount;
|
|
132
|
+
private activeDuration;
|
|
133
|
+
private touchStartedAt;
|
|
134
|
+
private readonly intervals;
|
|
135
|
+
private readonly onStart;
|
|
136
|
+
private readonly onEnd;
|
|
137
|
+
start(): void;
|
|
138
|
+
stop(): void;
|
|
139
|
+
snapshot(): TouchSignals;
|
|
140
|
+
reset(): void;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class ScrollCollector {
|
|
144
|
+
private listening;
|
|
145
|
+
private scrollCount;
|
|
146
|
+
private totalDistance;
|
|
147
|
+
private directionChanges;
|
|
148
|
+
private activeDuration;
|
|
149
|
+
private lastY;
|
|
150
|
+
private lastDir;
|
|
151
|
+
private lastAt;
|
|
152
|
+
private activityStartedAt;
|
|
153
|
+
private readonly intervals;
|
|
154
|
+
private scheduled;
|
|
155
|
+
private readonly onScroll;
|
|
156
|
+
private handleScroll;
|
|
157
|
+
start(): void;
|
|
158
|
+
stop(): void;
|
|
159
|
+
snapshot(): ScrollSignals;
|
|
160
|
+
reset(): void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
declare class FocusCollector {
|
|
164
|
+
private listening;
|
|
165
|
+
private focusCount;
|
|
166
|
+
private blurCount;
|
|
167
|
+
private readonly onFocus;
|
|
168
|
+
private readonly onBlur;
|
|
169
|
+
start(): void;
|
|
170
|
+
stop(): void;
|
|
171
|
+
snapshot(): FocusSignals;
|
|
172
|
+
reset(): void;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
declare class VisibilityCollector {
|
|
176
|
+
private listening;
|
|
177
|
+
private visibilityChanges;
|
|
178
|
+
private visibleDuration;
|
|
179
|
+
private hiddenDuration;
|
|
180
|
+
private segmentStartedAt;
|
|
181
|
+
private currentlyHidden;
|
|
182
|
+
private readonly onChange;
|
|
183
|
+
start(): void;
|
|
184
|
+
stop(): void;
|
|
185
|
+
snapshot(): VisibilitySignals;
|
|
186
|
+
reset(): void;
|
|
187
|
+
private flush;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
declare class InteractionCollector {
|
|
191
|
+
private listening;
|
|
192
|
+
private pageLoadTime;
|
|
193
|
+
private firstInteractionTime;
|
|
194
|
+
private clickCount;
|
|
195
|
+
private interactionCount;
|
|
196
|
+
private formInteractionCount;
|
|
197
|
+
private scrollCount;
|
|
198
|
+
private focusCount;
|
|
199
|
+
private readonly markInteraction;
|
|
200
|
+
private readonly onClick;
|
|
201
|
+
private readonly onKey;
|
|
202
|
+
private readonly onTouch;
|
|
203
|
+
private readonly onScroll;
|
|
204
|
+
private readonly onFocusIn;
|
|
205
|
+
start(): void;
|
|
206
|
+
stop(): void;
|
|
207
|
+
snapshot(): InteractionSignals;
|
|
208
|
+
reset(): void;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export { BotDetector, FocusCollector, HttpTransport, InteractionCollector, KeyboardCollector, PointerCollector, ScrollCollector, TouchCollector, VisibilityCollector, collectBrowserSignals, createLocalSession, isSessionExpired };
|