@prosopo/procaptcha-puzzle 2.10.8

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.
@@ -0,0 +1,57 @@
1
+
2
+
3
+ > @prosopo/procaptcha-puzzle@2.10.4 build
4
+ > npm run build:cross-env -- --mode ${NODE_ENV:-development}
5
+
6
+
7
+ > @prosopo/procaptcha-puzzle@2.10.4 build:cross-env
8
+ > vite build --config vite.esm.config.ts --mode production
9
+
10
+ ViteEsmConfig: .
11
+ {
12
+ tsConfigPaths: [
13
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/api/tsconfig.json',
14
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/types/tsconfig.json',
15
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/locale/tsconfig.json',
16
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/util/tsconfig.json',
17
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/util-crypto/tsconfig.json',
18
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/common/tsconfig.json',
19
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/logger/tsconfig.json',
20
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/procaptcha-common/tsconfig.json',
21
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/load-balancer/tsconfig.json',
22
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/widget-skeleton/tsconfig.json',
23
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/account/tsconfig.json',
24
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/fingerprint/tsconfig.json',
25
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/fingerprintjs/tsconfig.json',
26
+ '/home/chris/dev/prosopo/captcha-private2/captcha/packages/keyring/tsconfig.json'
27
+ ]
28
+ }
29
+ {
30
+ externals: [
31
+ '@prosopo/api',
32
+ '@prosopo/types',
33
+ '@prosopo/locale',
34
+ '@prosopo/util',
35
+ '@prosopo/util-crypto',
36
+ '@prosopo/common',
37
+ '@prosopo/logger',
38
+ '@prosopo/procaptcha-common',
39
+ '@prosopo/load-balancer',
40
+ '@prosopo/widget-skeleton',
41
+ '@prosopo/account',
42
+ '@prosopo/fingerprint',
43
+ '@prosopo/fingerprintjs',
44
+ '@prosopo/keyring'
45
+ ]
46
+ }
47
+ vite v6.4.1 building SSR bundle for production...
48
+ Bundle build started
49
+ transforming (1) src/index.tsBuild end
50
+ ✓ 5 modules transformed.
51
+ rendering chunks (1)...rendering chunks (2)...rendering chunks (3)...rendering chunks (4)...rendering chunks (5)...dist/index.js 0.14 kB
52
+ dist/components/ProcaptchaPuzzle.js 0.46 kB
53
+ dist/components/ProcaptchaWidget.js 6.11 kB
54
+ dist/services/Manager.js 9.80 kB
55
+ dist/components/PuzzleCanvas.js 9.81 kB
56
+ ✓ built in 69ms
57
+ ⠙⠙
@@ -0,0 +1,4 @@
1
+
2
+ > @prosopo/procaptcha-puzzle@2.8.45 typecheck
3
+ > tsc --project tsconfig.types.json
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,224 @@
1
+ # @prosopo/procaptcha-puzzle
2
+
3
+ ## 2.10.8
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [a1d60db]
7
+ - Updated dependencies [2392aaf]
8
+ - Updated dependencies [6ca1125]
9
+ - @prosopo/types@4.3.0
10
+ - @prosopo/util@3.2.15
11
+ - @prosopo/api@3.4.8
12
+ - @prosopo/common@3.1.38
13
+ - @prosopo/procaptcha-common@2.10.17
14
+
15
+ ## 2.10.7
16
+ ### Patch Changes
17
+
18
+ - d3db08d: feat(widget): bait AI responses with empty input + decoded label, portaled into the dapp's form
19
+
20
+ Redesigns the honeypot so it can actually catch AI agents instead of being inert:
21
+
22
+ - Empty input + decoded label: the encoded morse/semaphore question moves from `input.value` to an offscreen `<label>` (base64-decoded at render). Naive form-fillers and humans leave the empty input alone; agents that read the DOM as a prompt write into the empty field, captured as `clientMetaData.hp` on submit.
23
+ - Portaled to light DOM, inside the dapp's `<form>`: widget stays in shadow DOM, but the honeypot portals via `react-dom/createPortal` into the enclosing form (`document.body` fallback). Bots no longer have to traverse `.shadowRoot` to reach it (which was tripping `@prosopo/catcher`'s shadow-DOM guard and wiping the bot's value), and the bait sits where bots actually look — `form.querySelectorAll('input')`.
24
+ - `form="<useId>-d"`: opaque per-instance non-existent form id disassociates the input from native form submission while keeping it DOM-discoverable. Dapp backends don't receive a stray `email_confirm=` field.
25
+ - Shared `<Honeypot />` extracted to `@prosopo/procaptcha-common`.
26
+ - `procaptcha-bundle` Vite config now routes the Honeypot module into a per-build opaque chunk (`c<random8hex>-<hash>.js`) so the URL doesn't identify the component or stay stable across builds for static blocklisting.
27
+ - Updated dependencies [d3db08d]
28
+ - @prosopo/procaptcha-common@2.10.16
29
+
30
+ ## 2.10.6
31
+ ### Patch Changes
32
+
33
+ - 6c26669: Add per-site honeypot trap. When enabled, the provider attaches an encoded question (morse or semaphore, base64-wrapped) in the `x-prosopo-meta` response header on frictionless responses. The widget renders the value into an off-screen hidden input with `name="email_confirm"`; bots that auto-fill text inputs populate it and the value rides back on the solution submit as `clientMetaData.hp`, which is persisted on the `StoredCaptcha` record. Falls back to a random phrase from `PROSOPO_HONEYPOT_PHRASE_BANK_PATH` when no custom question is configured.
34
+ - Updated dependencies [6c26669]
35
+ - Updated dependencies [f7f9ec5]
36
+ - @prosopo/types@4.2.1
37
+ - @prosopo/api@3.4.7
38
+ - @prosopo/procaptcha-common@2.10.15
39
+
40
+ ## 2.10.5
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies [0fd81af]
44
+ - @prosopo/common@3.1.37
45
+ - @prosopo/procaptcha-common@2.10.14
46
+
47
+ ## 2.10.4
48
+ ### Patch Changes
49
+
50
+ - Updated dependencies [20cae63]
51
+ - Updated dependencies [4d9923e]
52
+ - @prosopo/types@4.2.0
53
+ - @prosopo/api@3.4.6
54
+ - @prosopo/procaptcha-common@2.10.13
55
+
56
+ ## 2.10.3
57
+ ### Patch Changes
58
+
59
+ - Updated dependencies [d351362]
60
+ - @prosopo/types@4.1.4
61
+ - @prosopo/api@3.4.5
62
+ - @prosopo/procaptcha-common@2.10.12
63
+
64
+ ## 2.10.2
65
+ ### Patch Changes
66
+
67
+ - Updated dependencies [6567ce0]
68
+ - Updated dependencies [e2711ae]
69
+ - Updated dependencies [5786629]
70
+ - @prosopo/util@3.2.14
71
+ - @prosopo/types@4.1.3
72
+ - @prosopo/locale@3.2.4
73
+ - @prosopo/api@3.4.4
74
+ - @prosopo/common@3.1.36
75
+ - @prosopo/procaptcha-common@2.10.11
76
+
77
+ ## 2.10.1
78
+ ### Patch Changes
79
+
80
+ - Updated dependencies [72a1218]
81
+ - Updated dependencies [566c1f6]
82
+ - @prosopo/util@3.2.13
83
+ - @prosopo/widget-skeleton@2.8.3
84
+ - @prosopo/types@4.1.2
85
+ - @prosopo/procaptcha-common@2.10.10
86
+ - @prosopo/api@3.4.3
87
+
88
+ ## 2.10.0
89
+ ### Minor Changes
90
+
91
+ - 91958da: Puzzle captcha + maintenance mode hardening, plus a refactor of the
92
+ frictionless handler into focused modules.
93
+
94
+ - **Puzzle captcha now records checkbox-click coordinates like POW.** Adds an
95
+ optional `salt` field to `SubmitPuzzleCaptchaSolutionBody`; the puzzle
96
+ widget hashes the click coords into the salt and the server decodes them
97
+ into the puzzle record's `coords` field on submit. New `start(x, y)`
98
+ parameters on `procaptcha-puzzle` Manager + widget.
99
+ - **Fix puzzle "No session found" caused by stale Redis dedup.** The
100
+ `/frictionless` dedup path is now Mongo-authoritative — Redis is no
101
+ longer consulted as a session source. A concurrent `/captcha/{type}`
102
+ invalidation could previously race a fire-and-forget Redis repopulation
103
+ in the `/frictionless` dedup branch, leaving Redis pointing at a
104
+ Mongo-deleted session for the full 1-hour TTL. Stale pointers are now
105
+ evicted lazily.
106
+ - **Maintenance mode operates without MongoDB.** `/frictionless` and
107
+ `/captcha/{pow,puzzle}` short-circuit to dummy responses before any DB
108
+ call, and `Environment.isReady()` tolerates a Mongo connect failure when
109
+ `MAINTENANCE_MODE=true` so the provider can start with Mongo down.
110
+ - **Refactor `getFrictionlessCaptchaChallenge.ts` into focused modules** under
111
+ `getFrictionlessCaptchaChallenge/` (handler, sessionDedup, shortCircuit,
112
+ accessPolicy, decisionMachine, decryptSimdReadings, constants). Original
113
+ import path preserved via a re-export shim.
114
+ - **Move `RedisWriteQueue` from `@prosopo/provider` to `@prosopo/database`**
115
+ (where the Redis connection itself lives), and clear residual Redis
116
+ session keys at provider startup via `Environment.cleanup()` so a
117
+ previously-crashed run can't leak stale dedup pointers.
118
+ - Adds puzzle-type branch to access-policy handling in `/frictionless`.
119
+
120
+ ### Patch Changes
121
+
122
+ - Updated dependencies [53bfd45]
123
+ - Updated dependencies [91958da]
124
+ - @prosopo/procaptcha-common@2.10.9
125
+ - @prosopo/locale@3.2.3
126
+ - @prosopo/api@3.4.2
127
+ - @prosopo/types@4.1.1
128
+ - @prosopo/common@3.1.35
129
+
130
+ ## 2.9.2
131
+ ### Patch Changes
132
+
133
+ - Updated dependencies [6a741ce]
134
+ - @prosopo/types@4.1.0
135
+ - @prosopo/api@3.4.1
136
+ - @prosopo/procaptcha-common@2.10.8
137
+
138
+ ## 2.9.1
139
+ ### Patch Changes
140
+
141
+ - @prosopo/procaptcha-common@2.10.7
142
+
143
+ ## 2.9.0
144
+ ### Minor Changes
145
+
146
+ - d865319: Add puzzle captcha (drag-to-target challenge) as a new captcha type:
147
+ provider endpoints, manager + widget package, types, demo pages, and
148
+ a `puzzleTolerance` site setting.
149
+ - 273926d: Fix `/captcha/{type}` endpoints looping with "No session found" when the
150
+ Redis session cache and Mongo diverge: on a session lookup miss the cache
151
+ entry is now invalidated, so the next `/frictionless` falls through and
152
+ creates a fresh session instead of resurrecting the dead one.
153
+
154
+ Add invisible-mode support to the puzzle captcha widget: the
155
+ execute-event handler now drives the full phase transition
156
+ (`start` → `setChallengeData` → `dragging`), and the puzzle overlay is
157
+ rendered in invisible mode so the user can still solve the (inherently
158
+ interactive) drag challenge — only the checkbox UI is hidden.
159
+
160
+ Add `invisible-puzzle-implicit.html` / `invisible-puzzle-explicit.html`
161
+ demo pages, and surface both standard and invisible puzzle entries in
162
+ the client-bundle-example navbar.
163
+
164
+ ### Patch Changes
165
+
166
+ - 4aae4e6: Plumb the WASM SIMD CPU fingerprint readings (collected by the catcher
167
+ client per https://blog.azerpas.com/writing/wasm-simd-fingerprinting/)
168
+ through the captcha flow and onto the linked `Session` record.
169
+ Collection-only — no scoring or classification yet.
170
+
171
+ The readings are sent at the earliest moment they're available so the
172
+ signal lands on the session as soon as possible:
173
+
174
+ 1. **Captcha-challenge GET** (PoW / Puzzle / Image) — the procaptcha
175
+ Manager calls `frictionlessState.getSimdReadings(0)` (non-blocking
176
+ cache check) and attaches it to the challenge-request body. The
177
+ provider handler decodes and patches the linked session via
178
+ `updateSessionRecord`.
179
+ 2. **Solution submission** (PoW / Puzzle / Image) — same non-blocking
180
+ check on the submit body. Acts as a backup if the benchmark wasn't
181
+ ready in time for the challenge GET.
182
+
183
+ Frictionless init itself stays SIMD-free (benchmark is too slow to gate
184
+ the first hop).
185
+
186
+ Surface area:
187
+
188
+ - `SimdReadings` discriminated union + `SimdOpReadingRecord` /
189
+ `SimdOpCategory` in `@prosopo/types`, plus `simdReadingsCodec` shared
190
+ encode/decode helpers so the browser SDK and the provider use the same
191
+ pipe-safe wire format.
192
+ - Optional `simdReadings: string()` on `CaptchaRequestBody`,
193
+ `GetPowCaptchaChallengeRequestBody`, `GetPuzzleCaptchaChallengeRequestBody`,
194
+ `CaptchaSolutionBody`, `SubmitPowCaptchaSolutionBody`, and
195
+ `SubmitPuzzleCaptchaSolutionBody`.
196
+ - `FrictionlessState.getSimdReadings` + `BotDetectionFunctionResult.getSimdReadings`
197
+ so the catcher's prefetched benchmark is consumed at the request sites.
198
+ - `ProcaptchaApiInterface.{getCaptchaChallenge, submitCaptchaSolution}` and
199
+ the `ProviderApi.{getCaptchaChallenge, getPowCaptchaChallenge, getPuzzleCaptchaChallenge,
200
+ submitCaptchaSolution, submitPowCaptchaSolution, submitPuzzleCaptchaSolution}`
201
+ client methods accept the field.
202
+ - Provider challenge + solution handlers decode via `decodeSimdReadings`
203
+ and `updateSessionRecord` (Mongoose `Mixed`, Zod discriminated-union
204
+ validation at the edge). The challenge-GET patch is fire-and-forget.
205
+
206
+ Backward-compatible: older catcher clients omit the field at every layer;
207
+ the session record omits it in turn.
208
+ - Updated dependencies [3c0be68]
209
+ - Updated dependencies [f9ea09d]
210
+ - Updated dependencies [4aae4e6]
211
+ - Updated dependencies [d865319]
212
+ - Updated dependencies [753304b]
213
+ - Updated dependencies [8bb7286]
214
+ - Updated dependencies [f9ea09d]
215
+ - Updated dependencies [4aae4e6]
216
+ - Updated dependencies [4993813]
217
+ - Updated dependencies [5f1ae53]
218
+ - @prosopo/types@4.0.0
219
+ - @prosopo/api@3.4.0
220
+ - @prosopo/locale@3.2.2
221
+ - @prosopo/util@3.2.12
222
+ - @prosopo/common@3.1.34
223
+ - @prosopo/widget-skeleton@2.8.2
224
+ - @prosopo/procaptcha-common@2.10.6
@@ -0,0 +1,3 @@
1
+ import type { ProcaptchaProps } from "@prosopo/types";
2
+ export declare const ProcaptchaPuzzle: (props: ProcaptchaProps) => import("@emotion/react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=ProcaptchaPuzzle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcaptchaPuzzle.d.ts","sourceRoot":"","sources":["../../src/components/ProcaptchaPuzzle.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AActD,eAAO,MAAM,gBAAgB,UAAW,eAAe,qDAStD,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
2
+ import { Suspense, lazy } from "react";
3
+ const ProcaptchaWidget = lazy(async () => import("./ProcaptchaWidget.js"));
4
+ export const ProcaptchaPuzzle = (props) => (_jsx(Suspense, { children: _jsx(ProcaptchaWidget, { config: props.config, callbacks: props.callbacks, frictionlessState: props.frictionlessState, i18n: props.i18n }) }));
5
+ //# sourceMappingURL=ProcaptchaPuzzle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcaptchaPuzzle.js","sourceRoot":"","sources":["../../src/components/ProcaptchaPuzzle.tsx"],"names":[],"mappings":";AAeA,OAAO,EAA4B,QAAQ,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AASjE,MAAM,gBAAgB,GAAmD,IAAI,CAC5E,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAC3C,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAE,EAAE,CAAC,CAC3D,KAAC,QAAQ,cACR,KAAC,gBAAgB,IAChB,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,GACf,GACQ,CACX,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ProcaptchaProps } from "@prosopo/types";
2
+ declare const Procaptcha: (props: ProcaptchaProps) => import("@emotion/react/jsx-runtime").JSX.Element;
3
+ export default Procaptcha;
4
+ //# sourceMappingURL=ProcaptchaWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcaptchaWidget.d.ts","sourceRoot":"","sources":["../../src/components/ProcaptchaWidget.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAGN,KAAK,eAAe,EAEpB,MAAM,gBAAgB,CAAC;AAWxB,QAAA,MAAM,UAAU,UAAW,eAAe,qDAiOzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,155 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
+ import { loadI18next, useTranslation } from "@prosopo/locale";
3
+ import { buildUpdateState, useProcaptcha } from "@prosopo/procaptcha-common";
4
+ import { Checkbox, Honeypot } from "@prosopo/procaptcha-common";
5
+ import { ModeEnum, } from "@prosopo/types";
6
+ import { darkTheme, lightTheme } from "@prosopo/widget-skeleton";
7
+ import { useCallback, useEffect, useRef, useState } from "react";
8
+ import { Manager } from "../services/Manager.js";
9
+ import { PuzzleCanvas } from "./PuzzleCanvas.js";
10
+ const PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
11
+ const Procaptcha = (props) => {
12
+ const { t, ready: isTranslationReady } = useTranslation();
13
+ const config = props.config;
14
+ const i18n = props.i18n;
15
+ const theme = "light" === config.theme ? lightTheme : darkTheme;
16
+ const frictionlessState = props.frictionlessState;
17
+ const callbacks = props.callbacks || {};
18
+ const [state, _updateState] = useProcaptcha(useState, useRef);
19
+ const [loading, setLoading] = useState(false);
20
+ const [puzzlePhase, setPuzzlePhase] = useState("checkbox");
21
+ const [challengeData, setChallengeData] = useState(null);
22
+ const [showRetry, setShowRetry] = useState(false);
23
+ const updateState = buildUpdateState(state, _updateState);
24
+ const hpRef = useRef(null);
25
+ const manager = useRef(Manager(config, state, updateState, callbacks, frictionlessState, () => hpRef.current?.value || undefined));
26
+ useEffect(() => {
27
+ if (config.language) {
28
+ if (i18n) {
29
+ if (i18n.language !== config.language) {
30
+ i18n.changeLanguage(config.language).then((r) => r);
31
+ }
32
+ }
33
+ else {
34
+ loadI18next(false).then((i18n) => {
35
+ if (i18n.language !== config.language)
36
+ i18n.changeLanguage(config.language).then((r) => r);
37
+ });
38
+ }
39
+ }
40
+ }, [i18n, config.language]);
41
+ useEffect(() => {
42
+ if (!state.error)
43
+ return undefined;
44
+ setLoading(false);
45
+ setPuzzlePhase("checkbox");
46
+ setChallengeData(null);
47
+ setShowRetry(false);
48
+ if (state.error.key === "CAPTCHA.NO_SESSION_FOUND" && frictionlessState) {
49
+ const timer = setTimeout(() => {
50
+ frictionlessState.restart();
51
+ }, 100);
52
+ return () => clearTimeout(timer);
53
+ }
54
+ return undefined;
55
+ }, [state.error, frictionlessState]);
56
+ useEffect(() => {
57
+ if (config.mode === ModeEnum.invisible) {
58
+ const handleExecuteEvent = async () => {
59
+ if (loading) {
60
+ return;
61
+ }
62
+ setLoading(true);
63
+ setShowRetry(false);
64
+ try {
65
+ const challenge = await manager.current.start();
66
+ if (challenge) {
67
+ setChallengeData(challenge);
68
+ setPuzzlePhase("dragging");
69
+ }
70
+ }
71
+ catch (error) {
72
+ callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));
73
+ }
74
+ finally {
75
+ setLoading(false);
76
+ }
77
+ };
78
+ document.addEventListener(PROCAPTCHA_EXECUTE_EVENT, handleExecuteEvent);
79
+ return () => {
80
+ document.removeEventListener(PROCAPTCHA_EXECUTE_EVENT, handleExecuteEvent);
81
+ };
82
+ }
83
+ return () => { };
84
+ }, [config.mode, callbacks.onError, loading]);
85
+ const handlePuzzleComplete = useCallback(async (finalX, finalY, puzzleEvents) => {
86
+ setPuzzlePhase("submitting");
87
+ let verified = false;
88
+ try {
89
+ verified = await manager.current.submitSolution(finalX, finalY, puzzleEvents);
90
+ }
91
+ catch (error) {
92
+ callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));
93
+ }
94
+ if (verified) {
95
+ setPuzzlePhase("checkbox");
96
+ setChallengeData(null);
97
+ setShowRetry(false);
98
+ setLoading(false);
99
+ return;
100
+ }
101
+ setShowRetry(true);
102
+ setPuzzlePhase("dragging");
103
+ try {
104
+ const newChallenge = await manager.current.start();
105
+ if (newChallenge) {
106
+ setChallengeData(newChallenge);
107
+ }
108
+ else {
109
+ setPuzzlePhase("checkbox");
110
+ setChallengeData(null);
111
+ setShowRetry(false);
112
+ }
113
+ }
114
+ catch {
115
+ setPuzzlePhase("checkbox");
116
+ setChallengeData(null);
117
+ setShowRetry(false);
118
+ }
119
+ setLoading(false);
120
+ }, [callbacks.onError]);
121
+ const isInvisible = config.mode === ModeEnum.invisible;
122
+ const showPuzzleOverlay = (puzzlePhase === "dragging" || puzzlePhase === "submitting") &&
123
+ challengeData;
124
+ return (_jsxs(_Fragment, { children: [frictionlessState?.hp && (_jsx(Honeypot, { ref: hpRef, encodedQuestion: frictionlessState.hp })), showPuzzleOverlay && (_jsx(PuzzleCanvas, { originX: challengeData.originX, originY: challengeData.originY, targetX: challengeData.targetX, targetY: challengeData.targetY, onComplete: handlePuzzleComplete, showRetry: showRetry, submitting: puzzlePhase === "submitting" })), !isInvisible && (_jsx(Checkbox, { checked: state.isHuman, theme: theme, onChange: async (event) => {
125
+ if (loading) {
126
+ return;
127
+ }
128
+ setLoading(true);
129
+ setShowRetry(false);
130
+ let x = 0;
131
+ let y = 0;
132
+ const mouseOrTouchEvent = event.nativeEvent;
133
+ if (!mouseOrTouchEvent.isTrusted) {
134
+ }
135
+ else if ("touches" in mouseOrTouchEvent &&
136
+ mouseOrTouchEvent.touches.length > 0 &&
137
+ mouseOrTouchEvent.touches[0]) {
138
+ x = mouseOrTouchEvent.touches[0].clientX;
139
+ y = mouseOrTouchEvent.touches[0].clientY;
140
+ }
141
+ else if ("clientX" in mouseOrTouchEvent &&
142
+ "clientY" in mouseOrTouchEvent) {
143
+ x = mouseOrTouchEvent.clientX;
144
+ y = mouseOrTouchEvent.clientY;
145
+ }
146
+ const challenge = await manager.current.start(x, y);
147
+ if (challenge) {
148
+ setChallengeData(challenge);
149
+ setPuzzlePhase("dragging");
150
+ }
151
+ setLoading(false);
152
+ }, labelText: isTranslationReady ? t("WIDGET.I_AM_HUMAN") : "", error: state.error?.message, "aria-label": "human checkbox", loading: loading || puzzlePhase === "submitting" }))] }));
153
+ };
154
+ export default Procaptcha;
155
+ //# sourceMappingURL=ProcaptchaWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcaptchaWidget.js","sourceRoot":"","sources":["../../src/components/ProcaptchaWidget.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { PuzzleEvent } from "@prosopo/types";
2
+ interface PuzzleCanvasProps {
3
+ originX: number;
4
+ originY: number;
5
+ targetX: number;
6
+ targetY: number;
7
+ onComplete: (finalX: number, finalY: number, puzzleEvents: PuzzleEvent[]) => void;
8
+ showRetry: boolean;
9
+ submitting: boolean;
10
+ }
11
+ export declare const PuzzleCanvas: ({ originX, originY, targetX, targetY, onComplete, showRetry, submitting, }: PuzzleCanvasProps) => import("@emotion/react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=PuzzleCanvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PuzzleCanvas.d.ts","sourceRoot":"","sources":["../../src/components/PuzzleCanvas.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,UAAU,iBAAiB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,CACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,EAAE,KACvB,IAAI,CAAC;IACV,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACpB;AAeD,eAAO,MAAM,YAAY,+EAQtB,iBAAiB,qDA2RnB,CAAC"}
@@ -0,0 +1,206 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ const CONTAINER_WIDTH = 300;
4
+ const CONTAINER_HEIGHT = 200;
5
+ const TARGET_SIZE = 30;
6
+ const PIECE_SIZE = 24;
7
+ const SHAKE_KEYFRAMES = `
8
+ @keyframes prosopo-puzzle-shake {
9
+ 0%, 100% { transform: translateX(0); }
10
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
11
+ 20%, 40%, 60%, 80% { transform: translateX(4px); }
12
+ }
13
+ `;
14
+ export const PuzzleCanvas = ({ originX, originY, targetX, targetY, onComplete, showRetry, submitting, }) => {
15
+ const [posX, setPosX] = useState(originX);
16
+ const [posY, setPosY] = useState(originY);
17
+ const isDragging = useRef(false);
18
+ const puzzleEvents = useRef([]);
19
+ const containerRef = useRef(null);
20
+ const offsetRef = useRef({ x: 0, y: 0 });
21
+ const [visible, setVisible] = useState(false);
22
+ const [shaking, setShaking] = useState(false);
23
+ useEffect(() => {
24
+ setPosX(originX);
25
+ setPosY(originY);
26
+ }, [originX, originY]);
27
+ useEffect(() => {
28
+ const frame = requestAnimationFrame(() => setVisible(true));
29
+ return () => cancelAnimationFrame(frame);
30
+ }, []);
31
+ useEffect(() => {
32
+ if (showRetry) {
33
+ setShaking(true);
34
+ const timer = setTimeout(() => setShaking(false), 500);
35
+ return () => clearTimeout(timer);
36
+ }
37
+ return () => { };
38
+ }, [showRetry]);
39
+ const clamp = useCallback((value, min, max) => {
40
+ return Math.max(min, Math.min(max, value));
41
+ }, []);
42
+ const getContainerOffset = useCallback(() => {
43
+ if (containerRef.current) {
44
+ const rect = containerRef.current.getBoundingClientRect();
45
+ return { x: rect.left, y: rect.top };
46
+ }
47
+ return { x: 0, y: 0 };
48
+ }, []);
49
+ const handleMoveEvent = useCallback((clientX, clientY) => {
50
+ if (!isDragging.current) {
51
+ return;
52
+ }
53
+ const containerOffset = getContainerOffset();
54
+ const newX = clamp(clientX - containerOffset.x - offsetRef.current.x, 0, CONTAINER_WIDTH);
55
+ const newY = clamp(clientY - containerOffset.y - offsetRef.current.y, 0, CONTAINER_HEIGHT);
56
+ setPosX(newX);
57
+ setPosY(newY);
58
+ puzzleEvents.current.push({ x: newX, y: newY, t: Date.now() });
59
+ }, [clamp, getContainerOffset]);
60
+ const handleEndEvent = useCallback(() => {
61
+ if (!isDragging.current) {
62
+ return;
63
+ }
64
+ isDragging.current = false;
65
+ const currentEvents = [...puzzleEvents.current];
66
+ const lastEvent = currentEvents[currentEvents.length - 1];
67
+ const finalX = lastEvent ? lastEvent.x : originX;
68
+ const finalY = lastEvent ? lastEvent.y : originY;
69
+ onComplete(finalX, finalY, currentEvents);
70
+ }, [onComplete, originX, originY]);
71
+ const handleMouseMove = useCallback((event) => {
72
+ handleMoveEvent(event.clientX, event.clientY);
73
+ }, [handleMoveEvent]);
74
+ const handleTouchMove = useCallback((event) => {
75
+ const touch = event.touches[0];
76
+ if (touch) {
77
+ handleMoveEvent(touch.clientX, touch.clientY);
78
+ }
79
+ }, [handleMoveEvent]);
80
+ const handleMouseUp = useCallback(() => {
81
+ handleEndEvent();
82
+ }, [handleEndEvent]);
83
+ const handleTouchEnd = useCallback(() => {
84
+ handleEndEvent();
85
+ }, [handleEndEvent]);
86
+ useEffect(() => {
87
+ document.addEventListener("mousemove", handleMouseMove);
88
+ document.addEventListener("mouseup", handleMouseUp);
89
+ document.addEventListener("touchmove", handleTouchMove);
90
+ document.addEventListener("touchend", handleTouchEnd);
91
+ return () => {
92
+ document.removeEventListener("mousemove", handleMouseMove);
93
+ document.removeEventListener("mouseup", handleMouseUp);
94
+ document.removeEventListener("touchmove", handleTouchMove);
95
+ document.removeEventListener("touchend", handleTouchEnd);
96
+ };
97
+ }, [handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
98
+ const handlePieceMouseDown = useCallback((event) => {
99
+ if (submitting)
100
+ return;
101
+ isDragging.current = true;
102
+ puzzleEvents.current = [];
103
+ const containerOffset = getContainerOffset();
104
+ offsetRef.current = {
105
+ x: event.clientX - containerOffset.x - posX,
106
+ y: event.clientY - containerOffset.y - posY,
107
+ };
108
+ }, [getContainerOffset, posX, posY, submitting]);
109
+ const handlePieceTouchStart = useCallback((event) => {
110
+ if (submitting)
111
+ return;
112
+ const touch = event.touches[0];
113
+ if (touch) {
114
+ isDragging.current = true;
115
+ puzzleEvents.current = [];
116
+ const containerOffset = getContainerOffset();
117
+ offsetRef.current = {
118
+ x: touch.clientX - containerOffset.x - posX,
119
+ y: touch.clientY - containerOffset.y - posY,
120
+ };
121
+ }
122
+ }, [getContainerOffset, posX, posY, submitting]);
123
+ const instructionText = showRetry
124
+ ? "Not quite \u2014 try again"
125
+ : "Drag the piece to the target";
126
+ const headerBorderColor = showRetry
127
+ ? "rgba(220, 53, 69, 0.4)"
128
+ : "transparent";
129
+ const headerTextColor = showRetry ? "#dc3545" : "#333";
130
+ return (_jsxs("div", { style: {
131
+ position: "fixed",
132
+ inset: 0,
133
+ zIndex: 2147483646,
134
+ display: "flex",
135
+ alignItems: "center",
136
+ justifyContent: "center",
137
+ backgroundColor: visible ? "rgba(0, 0, 0, 0.4)" : "rgba(0, 0, 0, 0)",
138
+ transition: "background-color 0.3s ease",
139
+ }, children: [_jsx("style", { children: SHAKE_KEYFRAMES }), _jsxs("div", { style: {
140
+ display: "flex",
141
+ flexDirection: "column",
142
+ alignItems: "center",
143
+ gap: "0",
144
+ zIndex: 2147483647,
145
+ opacity: visible ? 1 : 0,
146
+ transform: visible ? "scale(1)" : "scale(0.9)",
147
+ transition: "opacity 0.3s ease, transform 0.3s ease",
148
+ animation: shaking ? "prosopo-puzzle-shake 0.5s ease" : "none",
149
+ }, children: [_jsx("div", { style: {
150
+ backgroundColor: "#fff",
151
+ borderRadius: "8px 8px 0 0",
152
+ padding: "12px 20px",
153
+ width: `${CONTAINER_WIDTH}px`,
154
+ boxSizing: "border-box",
155
+ textAlign: "center",
156
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
157
+ fontSize: "14px",
158
+ fontWeight: 500,
159
+ color: headerTextColor,
160
+ borderBottom: `2px solid ${headerBorderColor}`,
161
+ boxShadow: "0px 11px 15px -7px rgba(0,0,0,0.2), 0px 24px 38px 3px rgba(0,0,0,0.14), 0px 9px 46px 8px rgba(0,0,0,0.12)",
162
+ transition: "color 0.3s ease, border-color 0.3s ease",
163
+ }, children: instructionText }), _jsxs("div", { ref: containerRef, style: {
164
+ position: "relative",
165
+ width: `${CONTAINER_WIDTH}px`,
166
+ height: `${CONTAINER_HEIGHT}px`,
167
+ background: "linear-gradient(135deg, #e8eaf6 0%, #c5cae9 50%, #e8eaf6 100%)",
168
+ borderRadius: "0 0 8px 8px",
169
+ overflow: "hidden",
170
+ userSelect: "none",
171
+ boxShadow: "0px 11px 15px -7px rgba(0,0,0,0.2), 0px 24px 38px 3px rgba(0,0,0,0.14), 0px 9px 46px 8px rgba(0,0,0,0.12)",
172
+ opacity: submitting ? 0.6 : 1,
173
+ pointerEvents: submitting ? "none" : "auto",
174
+ transition: "opacity 0.2s ease",
175
+ }, children: [_jsx("div", { style: {
176
+ position: "absolute",
177
+ left: `${targetX - TARGET_SIZE / 2}px`,
178
+ top: `${targetY - TARGET_SIZE / 2}px`,
179
+ width: `${TARGET_SIZE}px`,
180
+ height: `${TARGET_SIZE}px`,
181
+ borderRadius: "50%",
182
+ border: "2px dashed rgba(74, 144, 217, 0.6)",
183
+ backgroundColor: "rgba(74, 144, 217, 0.08)",
184
+ boxSizing: "border-box",
185
+ } }), _jsx("div", { onMouseDown: handlePieceMouseDown, onTouchStart: handlePieceTouchStart, style: {
186
+ position: "absolute",
187
+ left: `${posX - PIECE_SIZE / 2}px`,
188
+ top: `${posY - PIECE_SIZE / 2}px`,
189
+ width: `${PIECE_SIZE}px`,
190
+ height: `${PIECE_SIZE}px`,
191
+ borderRadius: "50%",
192
+ background: "radial-gradient(circle at 40% 40%, #6ab0ff, #4a90d9)",
193
+ cursor: submitting
194
+ ? "default"
195
+ : isDragging.current
196
+ ? "grabbing"
197
+ : "grab",
198
+ boxShadow: isDragging.current
199
+ ? "0 4px 12px rgba(74, 144, 217, 0.5)"
200
+ : "0 2px 6px rgba(74, 144, 217, 0.3)",
201
+ transition: isDragging.current
202
+ ? "none"
203
+ : "box-shadow 0.2s ease, left 0.3s ease, top 0.3s ease",
204
+ } })] })] })] }));
205
+ };
206
+ //# sourceMappingURL=PuzzleCanvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PuzzleCanvas.js","sourceRoot":"","sources":["../../src/components/PuzzleCanvas.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from "./components/ProcaptchaWidget.js";
2
+ export * from "./components/ProcaptchaPuzzle.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./components/ProcaptchaWidget.js";
2
+ export * from "./components/ProcaptchaPuzzle.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type FrictionlessState, type GetPuzzleCaptchaResponse, type ProcaptchaCallbacks, type ProcaptchaClientConfigInput, type ProcaptchaState, type ProcaptchaStateUpdateFn, type PuzzleEvent } from "@prosopo/types";
2
+ interface PuzzleManagerHandle {
3
+ start: (x?: number, y?: number) => Promise<GetPuzzleCaptchaResponse | undefined>;
4
+ submitSolution: (finalX: number, finalY: number, puzzleEvents: PuzzleEvent[]) => Promise<boolean>;
5
+ resetState: (frictionlessRestart?: () => void) => void;
6
+ }
7
+ export declare const Manager: (configInput: ProcaptchaClientConfigInput, state: ProcaptchaState, onStateUpdate: ProcaptchaStateUpdateFn, callbacks: ProcaptchaCallbacks, frictionlessState?: FrictionlessState, getHoneypotValue?: () => string | undefined) => PuzzleManagerHandle;
8
+ export {};
9
+ //# sourceMappingURL=Manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Manager.d.ts","sourceRoot":"","sources":["../../src/services/Manager.ts"],"names":[],"mappings":"AAwBA,OAAO,EAGN,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAEhC,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAEhB,MAAM,gBAAgB,CAAC;AAIxB,UAAU,mBAAmB;IAC5B,KAAK,EAAE,CACN,CAAC,CAAC,EAAE,MAAM,EACV,CAAC,CAAC,EAAE,MAAM,KACN,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;IACnD,cAAc,EAAE,CACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,EAAE,KACvB,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,UAAU,EAAE,CAAC,mBAAmB,CAAC,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACvD;AAED,eAAO,MAAM,OAAO,gBACN,2BAA2B,SACjC,eAAe,iBACP,uBAAuB,aAC3B,mBAAmB,sBACV,iBAAiB,qBAGlB,MAAM,MAAM,GAAG,SAAS,KACzC,mBAuYF,CAAC"}
@@ -0,0 +1,269 @@
1
+ import { stringToHex } from "@polkadot/util/string";
2
+ import { ProviderApi } from "@prosopo/api";
3
+ import { ProsopoEnvError } from "@prosopo/common";
4
+ import { ExtensionLoader, buildUpdateState, getProcaptchaRandomActiveProvider, providerRetry, } from "@prosopo/procaptcha-common";
5
+ import { getDefaultEvents } from "@prosopo/procaptcha-common";
6
+ import { ApiParams, ProcaptchaConfigSchema, encodeProcaptchaOutput, } from "@prosopo/types";
7
+ import { embedData, sleep } from "@prosopo/util";
8
+ import { randomAsHex } from "@prosopo/util-crypto";
9
+ export const Manager = (configInput, state, onStateUpdate, callbacks, frictionlessState, getHoneypotValue) => {
10
+ const events = getDefaultEvents(callbacks);
11
+ let storedChallengeResponse;
12
+ let storedProviderApi;
13
+ let storedProviderUrl;
14
+ let storedUser;
15
+ let storedClickX;
16
+ let storedClickY;
17
+ const defaultState = () => {
18
+ return {
19
+ showModal: false,
20
+ loading: false,
21
+ index: 0,
22
+ challenge: undefined,
23
+ solutions: undefined,
24
+ isHuman: false,
25
+ captchaApi: undefined,
26
+ account: undefined,
27
+ };
28
+ };
29
+ const clearTimeout = () => {
30
+ window.clearTimeout(Number(state.timeout));
31
+ updateState({ timeout: undefined });
32
+ };
33
+ const onFailed = () => {
34
+ updateState({
35
+ isHuman: false,
36
+ loading: false,
37
+ });
38
+ events.onFailed();
39
+ resetState(frictionlessState?.restart);
40
+ };
41
+ const clearSuccessfulChallengeTimeout = () => {
42
+ window.clearTimeout(Number(state.successfullChallengeTimeout));
43
+ updateState({ successfullChallengeTimeout: undefined });
44
+ };
45
+ const getConfig = () => {
46
+ const config = {
47
+ userAccountAddress: configInput.userAccountAddress || "",
48
+ ...configInput,
49
+ };
50
+ if (state.account) {
51
+ config.userAccountAddress = state.account.account.address;
52
+ }
53
+ return ProcaptchaConfigSchema.parse(config);
54
+ };
55
+ const getAccount = () => {
56
+ if (!state.account) {
57
+ throw new ProsopoEnvError("GENERAL.ACCOUNT_NOT_FOUND", {
58
+ context: { error: "Account not loaded" },
59
+ });
60
+ }
61
+ const account = state.account;
62
+ return { account };
63
+ };
64
+ const getDappAccount = () => {
65
+ if (!state.dappAccount) {
66
+ throw new ProsopoEnvError("GENERAL.SITE_KEY_MISSING");
67
+ }
68
+ const dappAccount = state.dappAccount;
69
+ return dappAccount;
70
+ };
71
+ const updateState = buildUpdateState(state, onStateUpdate);
72
+ const resetState = (frictionlessRestart) => {
73
+ clearTimeout();
74
+ clearSuccessfulChallengeTimeout();
75
+ updateState(defaultState());
76
+ events.onReset();
77
+ if (frictionlessRestart) {
78
+ frictionlessRestart();
79
+ }
80
+ storedChallengeResponse = undefined;
81
+ storedProviderApi = undefined;
82
+ storedProviderUrl = undefined;
83
+ storedUser = undefined;
84
+ storedClickX = undefined;
85
+ storedClickY = undefined;
86
+ };
87
+ const setValidChallengeTimeout = () => {
88
+ const timeMillis = getConfig().captchas.puzzle.solutionTimeout;
89
+ const successfullChallengeTimeout = setTimeout(() => {
90
+ updateState({ isHuman: false });
91
+ events.onExpired();
92
+ resetState(frictionlessState?.restart);
93
+ }, timeMillis);
94
+ updateState({ successfullChallengeTimeout });
95
+ };
96
+ const start = async (x = 0, y = 0) => {
97
+ storedClickX = x;
98
+ storedClickY = y;
99
+ await providerRetry(async () => {
100
+ if (state.loading) {
101
+ return;
102
+ }
103
+ if (state.isHuman) {
104
+ return;
105
+ }
106
+ resetState();
107
+ updateState({
108
+ loading: true,
109
+ });
110
+ updateState({ attemptCount: state.attemptCount + 1 });
111
+ const config = getConfig();
112
+ const selectAccount = async () => {
113
+ if (frictionlessState) {
114
+ return frictionlessState.userAccount;
115
+ }
116
+ const ext = new (await ExtensionLoader(config.web2))();
117
+ return ext.getAccount(config);
118
+ };
119
+ const user = await selectAccount();
120
+ const userAccount = user.account.address;
121
+ updateState({
122
+ account: { account: { address: userAccount } },
123
+ });
124
+ updateState({ dappAccount: config.account.address });
125
+ await sleep(100);
126
+ if (!config.web2 && !config.userAccountAddress) {
127
+ throw new ProsopoEnvError("GENERAL.ACCOUNT_NOT_FOUND", {
128
+ context: {
129
+ error: "Account address has not been set for web3 mode",
130
+ },
131
+ });
132
+ }
133
+ let getRandomProviderResponse = undefined;
134
+ if (frictionlessState?.provider) {
135
+ getRandomProviderResponse = frictionlessState.provider;
136
+ }
137
+ else {
138
+ getRandomProviderResponse = await getProcaptchaRandomActiveProvider(getConfig().defaultEnvironment);
139
+ }
140
+ const providerUrl = getRandomProviderResponse.provider.url;
141
+ const providerApi = new ProviderApi(providerUrl, getDappAccount());
142
+ const simdReadingsOnChallenge = frictionlessState?.getSimdReadings
143
+ ? await frictionlessState.getSimdReadings(0)
144
+ : undefined;
145
+ const challenge = await providerApi.getPuzzleCaptchaChallenge(userAccount, getDappAccount(), frictionlessState?.sessionId, simdReadingsOnChallenge);
146
+ if (challenge.error) {
147
+ updateState({
148
+ loading: false,
149
+ error: {
150
+ message: challenge.error.message,
151
+ key: challenge.error.key || "API.UNKNOWN_ERROR",
152
+ },
153
+ });
154
+ return;
155
+ }
156
+ storedChallengeResponse = challenge;
157
+ storedProviderApi = providerApi;
158
+ storedProviderUrl = providerUrl;
159
+ storedUser = user;
160
+ updateState({
161
+ loading: false,
162
+ });
163
+ }, async () => {
164
+ await start();
165
+ }, () => {
166
+ resetState();
167
+ }, state.attemptCount, 3);
168
+ return storedChallengeResponse;
169
+ };
170
+ const submitSolution = async (finalX, finalY, puzzleEvents) => {
171
+ if (!storedChallengeResponse ||
172
+ !storedProviderApi ||
173
+ !storedProviderUrl ||
174
+ !storedUser) {
175
+ throw new ProsopoEnvError("GENERAL.ACCOUNT_NOT_FOUND", {
176
+ context: { error: "No challenge data available. Call start() first." },
177
+ });
178
+ }
179
+ updateState({ loading: true });
180
+ try {
181
+ const challenge = storedChallengeResponse;
182
+ const providerApi = storedProviderApi;
183
+ const providerUrl = storedProviderUrl;
184
+ const user = storedUser;
185
+ const config = getConfig();
186
+ const signer = user.extension?.signer;
187
+ if (!signer || !signer.signRaw) {
188
+ throw new ProsopoEnvError("GENERAL.CANT_FIND_KEYRINGPAIR", {
189
+ context: {
190
+ error: "Signer is not defined, cannot sign message to prove account ownership",
191
+ },
192
+ });
193
+ }
194
+ const userTimestampSignature = await signer.signRaw({
195
+ address: user.account.address,
196
+ data: stringToHex(challenge[ApiParams.timestamp].toString()),
197
+ type: "bytes",
198
+ });
199
+ let encryptedBehavioralData;
200
+ if (frictionlessState?.encryptBehavioralData &&
201
+ (frictionlessState?.behaviorCollector1 ||
202
+ frictionlessState?.behaviorCollector2 ||
203
+ frictionlessState?.behaviorCollector3)) {
204
+ try {
205
+ const behavioralData = {
206
+ collector1: frictionlessState.behaviorCollector1?.getData() || [],
207
+ collector2: frictionlessState.behaviorCollector2?.getData() || [],
208
+ collector3: frictionlessState.behaviorCollector3?.getData() || [],
209
+ deviceCapability: frictionlessState.deviceCapability || "unknown",
210
+ };
211
+ const dataToEncrypt = frictionlessState.packBehavioralData
212
+ ? frictionlessState.packBehavioralData(behavioralData)
213
+ : behavioralData;
214
+ encryptedBehavioralData =
215
+ await frictionlessState.encryptBehavioralData(JSON.stringify(dataToEncrypt));
216
+ }
217
+ catch {
218
+ }
219
+ }
220
+ let salt;
221
+ if (storedClickX !== undefined && storedClickY !== undefined) {
222
+ const coords = [storedClickX, storedClickY];
223
+ const randomSalt = randomAsHex(coords
224
+ .map((coord) => coord.toString(16).length + 4)
225
+ .reduce((acc, curr) => acc + curr, 0));
226
+ salt = embedData(randomSalt, coords);
227
+ }
228
+ const simdReadings = frictionlessState?.getSimdReadings
229
+ ? await frictionlessState.getSimdReadings()
230
+ : undefined;
231
+ const hpValue = getHoneypotValue?.();
232
+ const clientMetaData = hpValue ? { hp: hpValue } : undefined;
233
+ const verifiedSolution = await providerApi.submitPuzzleCaptchaSolution(challenge, getAccount().account.account.address, getDappAccount(), finalX, finalY, puzzleEvents, userTimestampSignature.signature.toString(), config.captchas.puzzle.verifiedTimeout, encryptedBehavioralData, salt, simdReadings, clientMetaData);
234
+ if (verifiedSolution[ApiParams.verified]) {
235
+ updateState({
236
+ isHuman: true,
237
+ loading: false,
238
+ });
239
+ events.onHuman(encodeProcaptchaOutput({
240
+ [ApiParams.providerUrl]: providerUrl,
241
+ [ApiParams.user]: getAccount().account.account.address,
242
+ [ApiParams.dapp]: getDappAccount(),
243
+ [ApiParams.challenge]: challenge.challenge,
244
+ [ApiParams.timestamp]: challenge.timestamp,
245
+ [ApiParams.signature]: {
246
+ [ApiParams.provider]: challenge.signature.provider,
247
+ [ApiParams.user]: {
248
+ [ApiParams.timestamp]: userTimestampSignature.signature.toString(),
249
+ },
250
+ },
251
+ }));
252
+ setValidChallengeTimeout();
253
+ return true;
254
+ }
255
+ onFailed();
256
+ return false;
257
+ }
258
+ catch (error) {
259
+ updateState({ loading: false });
260
+ throw error;
261
+ }
262
+ };
263
+ return {
264
+ start,
265
+ submitSolution,
266
+ resetState,
267
+ };
268
+ };
269
+ //# sourceMappingURL=Manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Manager.js","sourceRoot":"","sources":["../../src/services/Manager.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@prosopo/procaptcha-puzzle",
3
+ "version": "2.10.8",
4
+ "author": "PROSOPO LIMITED <info@prosopo.io>",
5
+ "license": "Apache-2.0",
6
+ "main": "dist/index.js",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "engines": {
10
+ "node": "^24",
11
+ "npm": "^11"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/cjs/index.cjs"
18
+ }
19
+ },
20
+ "types": "dist/index.d.ts",
21
+ "source": "./src/index.ts",
22
+ "scripts": {
23
+ "clean": "del-cli --verbose dist tsconfig.tsbuildinfo",
24
+ "build": "npm run build:cross-env -- --mode ${NODE_ENV:-development}",
25
+ "build:cross-env": "vite build --config vite.esm.config.ts",
26
+ "build:tsc": "tsc --build --verbose",
27
+ "build:cjs": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV",
28
+ "typecheck": "tsc --project tsconfig.types.json"
29
+ },
30
+ "browserslist": ["> 0.5%, last 2 versions, not dead"],
31
+ "dependencies": {
32
+ "@polkadot/util": "13.5.7",
33
+ "@prosopo/api": "3.4.8",
34
+ "@prosopo/common": "3.1.38",
35
+ "@prosopo/locale": "3.2.4",
36
+ "@prosopo/procaptcha-common": "2.10.17",
37
+ "@prosopo/types": "4.3.0",
38
+ "@prosopo/util": "3.2.15",
39
+ "@prosopo/util-crypto": "13.5.29",
40
+ "@prosopo/widget-skeleton": "2.8.3",
41
+ "react": "18.3.1"
42
+ },
43
+ "devDependencies": {
44
+ "@prosopo/config": "3.3.1",
45
+ "@emotion/react": "11.11.1",
46
+ "@emotion/styled": "11.11.0",
47
+ "@types/node": "22.5.5",
48
+ "@vitest/coverage-v8": "3.2.4",
49
+ "concurrently": "9.0.1",
50
+ "del-cli": "6.0.0",
51
+ "npm-run-all": "4.1.5",
52
+ "tslib": "2.7.0",
53
+ "tsx": "4.20.3",
54
+ "typescript": "5.6.2",
55
+ "vite": "6.4.1",
56
+ "vitest": "3.2.4"
57
+ },
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/prosopo/captcha.git",
61
+ "directory": "packages/procaptcha-puzzle"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/prosopo/captcha/issues"
65
+ },
66
+ "homepage": "https://github.com/prosopo/captcha#readme",
67
+ "description": "",
68
+ "publishConfig": {
69
+ "registry": "https://registry.npmjs.org"
70
+ }
71
+ }
@@ -0,0 +1,22 @@
1
+ import path from "node:path";
2
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ import { ViteCommonJSConfig } from "@prosopo/config";
16
+
17
+ export default function () {
18
+ return ViteCommonJSConfig(
19
+ path.basename("."),
20
+ path.resolve("./tsconfig.json"),
21
+ );
22
+ }
@@ -0,0 +1,20 @@
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import path from "node:path";
16
+ import { ViteEsmConfig } from "@prosopo/config";
17
+
18
+ export default function () {
19
+ return ViteEsmConfig(path.basename("."), path.resolve("./tsconfig.json"));
20
+ }