usehuma 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.
- package/README.md +188 -0
- package/dist/index.d.mts +90 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +179 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +148 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.d.mts +157 -0
- package/dist/react.d.ts +157 -0
- package/dist/react.js +330 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +310 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx","../src/core.ts"],"sourcesContent":["/**\n * useHUMA — React Integration\n * Hook + Provider + Gate component\n *\n * Usage:\n * import { useHuma, HumaGate } from 'usehuma/react'\n */\n\n\"use client\"; // Next.js App Router compatible\n\nimport {\n createContext, useContext, useEffect, useRef, useState, useCallback,\n type ReactNode,\n} from \"react\";\nimport { HumaCollector, callHumaApi } from \"./core\";\nimport type { HumaOptions, HumaState, HumaVerifyResult } from \"./types\";\n\n/* ─────────────────────────────────────────\n useHuma — core hook\n ───────────────────────────────────────── */\n\n/**\n * Collect behavioral signals and verify a user as human.\n *\n * @example\n * const { isHuman, score, loading, verify } = useHuma({\n * apiKey: 'huma_live_...',\n * userId: 'user_123',\n * });\n */\nexport function useHuma(opts: HumaOptions): HumaState {\n const collectorRef = useRef<HumaCollector | null>(null);\n const [loading, setLoading] = useState(false);\n const [result, setResult] = useState<HumaVerifyResult | null>(null);\n const [error, setError] = useState<HumaState[\"error\"]>(null);\n\n // Start collecting signals immediately on mount\n useEffect(() => {\n const collector = new HumaCollector();\n collector.start();\n collectorRef.current = collector;\n return () => collector.stop();\n }, []);\n\n const verify = useCallback(async (): Promise<HumaVerifyResult | null> => {\n if (!collectorRef.current) return null;\n setLoading(true);\n setError(null);\n try {\n const sessionData = collectorRef.current.extract();\n const res = await callHumaApi(opts, sessionData);\n setResult(res);\n return res;\n } catch (err) {\n const humaError = err as HumaState[\"error\"];\n setError(humaError);\n return null;\n } finally {\n setLoading(false);\n }\n }, [opts.apiKey, opts.userId, opts.endpoint]);\n\n return {\n loading,\n result,\n error,\n isHuman: result ? result.human : null,\n score: result ? Math.round(result.confidence * 100) : null,\n verify,\n };\n}\n\n/* ─────────────────────────────────────────\n HumaContext — optional global provider\n ───────────────────────────────────────── */\n\ntype HumaContextValue = HumaState & { ready: boolean };\n\nconst HumaContext = createContext<HumaContextValue | null>(null);\n\ntype HumaProviderProps = {\n apiKey: string;\n userId: string;\n endpoint?: string;\n /** Auto-verify on mount (default: false — call verify() manually) */\n autoVerify?: boolean;\n children: ReactNode;\n};\n\n/**\n * Wrap your app (or a subtree) with HumaProvider so any child\n * can call useHumaContext() without re-collecting signals.\n *\n * @example\n * <HumaProvider apiKey=\"huma_live_...\" userId={session.userId}>\n * <App />\n * </HumaProvider>\n */\nexport function HumaProvider({ apiKey, userId, endpoint, autoVerify = false, children }: HumaProviderProps) {\n const state = useHuma({ apiKey, userId, endpoint });\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n setReady(true);\n if (autoVerify) state.verify();\n }, []);\n\n return (\n <HumaContext.Provider value={{ ...state, ready }}>\n {children}\n </HumaContext.Provider>\n );\n}\n\n/**\n * Access the shared HUMA state inside a HumaProvider.\n */\nexport function useHumaContext(): HumaContextValue {\n const ctx = useContext(HumaContext);\n if (!ctx) throw new Error(\"useHumaContext must be used inside <HumaProvider>\");\n return ctx;\n}\n\n/* ─────────────────────────────────────────\n HumaGate — conditional render component\n ───────────────────────────────────────── */\n\ntype HumaGateProps = {\n apiKey: string;\n userId: string;\n endpoint?: string;\n /** Content to show while verifying */\n fallback?: ReactNode;\n /** Content to show if verification fails (bot detected) */\n blocked?: ReactNode;\n /** Auto-verify on mount (default: true) */\n autoVerify?: boolean;\n children: ReactNode;\n};\n\n/**\n * Only renders children when the user is verified as human.\n * Shows fallback while loading, blocked if bot detected.\n *\n * @example\n * <HumaGate apiKey=\"huma_live_...\" userId={userId} fallback={<Spinner />}>\n * <SensitiveContent />\n * </HumaGate>\n */\nexport function HumaGate({\n apiKey, userId, endpoint,\n fallback = null,\n blocked = null,\n autoVerify = true,\n children,\n}: HumaGateProps) {\n const { isHuman, loading, verify } = useHuma({ apiKey, userId, endpoint });\n\n useEffect(() => {\n if (autoVerify) verify();\n }, []);\n\n if (loading) return <>{fallback}</>;\n if (isHuman === false) return <>{blocked}</>;\n if (isHuman === null) return <>{fallback}</>;\n return <>{children}</>;\n}\n\n/* ─────────────────────────────────────────\n useHumaSession — continuous monitoring\n ───────────────────────────────────────── */\n\ntype SessionResult = {\n score: number;\n confidence: number;\n baseline: number;\n delta: number;\n anomaly: boolean;\n action: \"allow\" | \"flag\" | \"block\";\n notes: string[];\n};\n\ntype UseHumaSessionOptions = {\n apiKey: string;\n userId: string;\n /** The token returned by verify() */\n token: string;\n /** Heartbeat interval in ms (default: 30000) */\n intervalMs?: number;\n /** Called when anomaly detected (score dropped or absolute bot) */\n onAnomaly?: (result: SessionResult) => void;\n endpoint?: string;\n};\n\n/**\n * Continuously monitors an active session for bot behavior / account takeover.\n * Start after a successful verify(). Sends heartbeats every 30s.\n *\n * @example\n * const { lastResult, anomaly, stop } = useHumaSession({\n * apiKey: 'huma_live_...',\n * userId: 'user_123',\n * token: verifyResult.token,\n * onAnomaly: (r) => router.push('/logout'),\n * });\n */\nexport function useHumaSession(opts: UseHumaSessionOptions) {\n const collectorRef = useRef<HumaCollector | null>(null);\n const windowRef = useRef<HumaCollector | null>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const [lastResult, setLastResult] = useState<SessionResult | null>(null);\n const [anomaly, setAnomaly] = useState(false);\n\n const stop = useCallback(() => {\n if (intervalRef.current) clearInterval(intervalRef.current);\n windowRef.current?.stop();\n }, []);\n\n const sendHeartbeat = useCallback(async () => {\n if (!windowRef.current) return;\n const sessionData = windowRef.current.extract();\n\n // Reset rolling window\n windowRef.current.stop();\n const fresh = new HumaCollector();\n fresh.start();\n windowRef.current = fresh;\n\n try {\n const endpoint = opts.endpoint ?? \"https://humaverify.com/api/v1/session\";\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${opts.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n userId: opts.userId,\n sessionToken: opts.token,\n sessionData,\n }),\n });\n if (!res.ok) return;\n const result: SessionResult = await res.json();\n setLastResult(result);\n if (result.anomaly) {\n setAnomaly(true);\n opts.onAnomaly?.(result);\n }\n } catch { /* silent */ }\n }, [opts.apiKey, opts.userId, opts.token, opts.endpoint]);\n\n useEffect(() => {\n // Start rolling window collector\n const w = new HumaCollector();\n w.start();\n windowRef.current = w;\n\n const ms = opts.intervalMs ?? 30_000;\n intervalRef.current = setInterval(sendHeartbeat, ms);\n\n return () => {\n stop();\n };\n }, [opts.intervalMs]);\n\n return { lastResult, anomaly, stop };\n}\n\n/* ─────────────────────────────────────────\n HumaVerifyButton — one-click verify\n ───────────────────────────────────────── */\n\ntype HumaVerifyButtonProps = {\n apiKey: string;\n userId: string;\n endpoint?: string;\n onVerified?: (result: HumaVerifyResult) => void;\n onBlocked?: () => void;\n children?: ReactNode;\n className?: string;\n style?: React.CSSProperties;\n};\n\n/**\n * A button that triggers behavioral verification on click.\n * Useful for form submissions, checkout flows, sensitive actions.\n *\n * @example\n * <HumaVerifyButton\n * apiKey=\"huma_live_...\"\n * userId={userId}\n * onVerified={(r) => console.log('Human!', r.confidence)}\n * onBlocked={() => console.log('Bot detected')}\n * >\n * Submit\n * </HumaVerifyButton>\n */\nexport function HumaVerifyButton({\n apiKey, userId, endpoint,\n onVerified, onBlocked,\n children = \"Verify\",\n className, style,\n}: HumaVerifyButtonProps) {\n const { loading, verify } = useHuma({ apiKey, userId, endpoint });\n\n const handleClick = async () => {\n const res = await verify();\n if (!res) return;\n if (res.human) onVerified?.(res);\n else onBlocked?.();\n };\n\n return (\n <button onClick={handleClick} disabled={loading} className={className} style={style}>\n {loading ? \"Verifying…\" : children}\n </button>\n );\n}\n","/**\n * useHUMA — Core Signal Collector\n * Invisible behavioral biometrics — no PII collected.\n */\n\nimport type { SessionData, HumaVerifyResult, HumaError, HumaOptions } from \"./types\";\n\ntype MousePoint = { x: number; y: number; t: number };\ntype KeyEntry = { interval: number };\ntype ScrollEntry = { interval: number };\ntype ClickEntry = { t: number };\ntype FocusEvent = { type: \"focus\" | \"blur\"; t: number };\n\ninterface Signals {\n mouse: MousePoint[];\n keys: KeyEntry[];\n scrolls: ScrollEntry[];\n clicks: ClickEntry[];\n focusEvents: FocusEvent[];\n startTime: number;\n lastKeyTime: number | null;\n lastScrollTime: number | null;\n}\n\nfunction cv(arr: number[]): number {\n if (arr.length < 2) return 0;\n const mean = arr.reduce((a, b) => a + b, 0) / arr.length;\n if (mean === 0) return 0;\n const variance = arr.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / arr.length;\n return Math.sqrt(variance) / mean;\n}\n\nfunction mouseFeatures(pts: MousePoint[]) {\n if (pts.length < 5) return { speed_cv: 0, direction_changes: 0, sample_count: 0 };\n const speeds: number[] = [];\n const directions: number[] = [];\n for (let i = 1; i < pts.length; i++) {\n const dx = pts[i].x - pts[i - 1].x;\n const dy = pts[i].y - pts[i - 1].y;\n const dt = Math.max(pts[i].t - pts[i - 1].t, 1);\n speeds.push(Math.sqrt(dx * dx + dy * dy) / dt);\n directions.push(Math.atan2(dy, dx));\n }\n let dirChanges = 0;\n for (let j = 1; j < directions.length; j++) {\n if (Math.abs(directions[j] - directions[j - 1]) > 0.3) dirChanges++;\n }\n return { speed_cv: cv(speeds), direction_changes: dirChanges, sample_count: pts.length };\n}\n\nexport class HumaCollector {\n private signals: Signals = {\n mouse: [], keys: [], scrolls: [], clicks: [], focusEvents: [],\n startTime: Date.now(), lastKeyTime: null, lastScrollTime: null,\n };\n private listening = false;\n\n private onMouseMove = (e: MouseEvent) => {\n if (this.signals.mouse.length < 200)\n this.signals.mouse.push({ x: e.clientX, y: e.clientY, t: Date.now() });\n };\n private onKeyDown = () => {\n const now = Date.now();\n if (this.signals.lastKeyTime !== null && this.signals.keys.length < 100)\n this.signals.keys.push({ interval: now - this.signals.lastKeyTime });\n this.signals.lastKeyTime = now;\n };\n private onScroll = () => {\n const now = Date.now();\n if (this.signals.lastScrollTime !== null && this.signals.scrolls.length < 50)\n this.signals.scrolls.push({ interval: now - this.signals.lastScrollTime });\n this.signals.lastScrollTime = now;\n };\n private onClick = () => {\n if (this.signals.clicks.length < 50)\n this.signals.clicks.push({ t: Date.now() });\n };\n private onFocus = () => this.signals.focusEvents.push({ type: \"focus\", t: Date.now() });\n private onBlur = () => this.signals.focusEvents.push({ type: \"blur\", t: Date.now() });\n\n start() {\n if (this.listening || typeof window === \"undefined\") return;\n this.listening = true;\n document.addEventListener(\"mousemove\", this.onMouseMove, { passive: true });\n document.addEventListener(\"keydown\", this.onKeyDown, { passive: true });\n document.addEventListener(\"scroll\", this.onScroll, { passive: true });\n document.addEventListener(\"click\", this.onClick, { passive: true });\n window.addEventListener(\"focus\", this.onFocus, { passive: true });\n window.addEventListener(\"blur\", this.onBlur, { passive: true });\n }\n\n stop() {\n if (!this.listening) return;\n this.listening = false;\n document.removeEventListener(\"mousemove\", this.onMouseMove);\n document.removeEventListener(\"keydown\", this.onKeyDown);\n document.removeEventListener(\"scroll\", this.onScroll);\n document.removeEventListener(\"click\", this.onClick);\n window.removeEventListener(\"focus\", this.onFocus);\n window.removeEventListener(\"blur\", this.onBlur);\n }\n\n extract(): SessionData {\n const { keys, scrolls, clicks, focusEvents, startTime, mouse } = this.signals;\n const m = mouseFeatures(mouse);\n const clickIntervals: number[] = [];\n for (let i = 1; i < clicks.length; i++)\n clickIntervals.push(clicks[i].t - clicks[i - 1].t);\n return {\n time_on_page_ms: Date.now() - startTime,\n key_interval_cv: cv(keys.map(k => k.interval)),\n key_count: keys.length,\n scroll_interval_cv: cv(scrolls.map(s => s.interval)),\n scroll_count: scrolls.length,\n mouse_speed_cv: m.speed_cv,\n mouse_direction_changes: m.direction_changes,\n mouse_sample_count: m.sample_count,\n click_interval_cv: cv(clickIntervals),\n click_count: clicks.length,\n tab_switches: focusEvents.length,\n };\n }\n\n debug(): Record<string, unknown> {\n return { signals: this.signals as unknown, features: this.extract() };\n }\n}\n\n/** Send extracted signals to the HUMA API and return a result. */\nexport async function callHumaApi(\n opts: HumaOptions,\n sessionData: SessionData\n): Promise<HumaVerifyResult> {\n const endpoint = opts.endpoint ?? \"https://humaverify.com/api/v1/verify\";\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${opts.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ userId: opts.userId, sessionData }),\n });\n if (!res.ok) {\n const err: HumaError = await res.json().catch(() => ({ error: \"Unknown error\" }));\n throw err;\n }\n return res.json() as Promise<HumaVerifyResult>;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "usehuma",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Privacy-first human verification SDK — behavioral biometrics, no CAPTCHA, no Cloudflare dependency.",
|
|
5
|
+
"author": "UseHUMA <team@humaverify.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://humaverify.com",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/usehuma/usehuma-js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"human-verification",
|
|
14
|
+
"bot-detection",
|
|
15
|
+
"behavioral-biometrics",
|
|
16
|
+
"captcha-alternative",
|
|
17
|
+
"fraud-prevention",
|
|
18
|
+
"privacy-first",
|
|
19
|
+
"no-captcha",
|
|
20
|
+
"turnstile-alternative",
|
|
21
|
+
"hcaptcha-alternative"
|
|
22
|
+
],
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"module": "./dist/index.mjs",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"import": "./dist/index.mjs",
|
|
29
|
+
"require": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./react": {
|
|
33
|
+
"import": "./dist/react.mjs",
|
|
34
|
+
"require": "./dist/react.js",
|
|
35
|
+
"types": "./dist/react.d.ts"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup",
|
|
44
|
+
"dev": "tsup --watch",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"prepublishOnly": "npm run build"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"tsup": "^8.0.0",
|
|
50
|
+
"typescript": "^5.4.0",
|
|
51
|
+
"@types/react": "^18.0.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"react": ">=17.0.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"react": {
|
|
58
|
+
"optional": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"sideEffects": false
|
|
62
|
+
}
|