@prosopo/procaptcha-puzzle 2.10.40 → 2.10.42
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/.turbo/turbo-build$colon$cjs.log +4 -4
- package/.turbo/turbo-build$colon$tsc.log +19 -19
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +12 -0
- package/dist/cjs/components/ProcaptchaWidget.cjs +10 -5
- package/dist/cjs/services/Manager.cjs +3 -3
- package/dist/components/ProcaptchaWidget.d.ts.map +1 -1
- package/dist/components/ProcaptchaWidget.js +10 -5
- package/dist/components/ProcaptchaWidget.js.map +1 -1
- package/dist/services/Manager.d.ts.map +1 -1
- package/dist/services/Manager.js +3 -3
- package/dist/services/Manager.js.map +1 -1
- package/dist/tests/manager.unit.test.d.ts +2 -0
- package/dist/tests/manager.unit.test.d.ts.map +1 -0
- package/dist/tests/manager.unit.test.js +506 -0
- package/dist/tests/manager.unit.test.js.map +1 -0
- package/dist/tests/managerHarness.d.ts +20 -0
- package/dist/tests/managerHarness.d.ts.map +1 -0
- package/dist/tests/managerHarness.js +86 -0
- package/dist/tests/managerHarness.js.map +1 -0
- package/dist/tests/procaptchaPuzzle.test-d.d.ts +2 -0
- package/dist/tests/procaptchaPuzzle.test-d.d.ts.map +1 -0
- package/dist/tests/procaptchaPuzzle.test-d.js +97 -0
- package/dist/tests/procaptchaPuzzle.test-d.js.map +1 -0
- package/dist/tests/procaptchaPuzzle.unit.test.d.ts +2 -0
- package/dist/tests/procaptchaPuzzle.unit.test.d.ts.map +1 -0
- package/dist/tests/procaptchaPuzzle.unit.test.js +81 -0
- package/dist/tests/procaptchaPuzzle.unit.test.js.map +1 -0
- package/dist/tests/procaptchaWidget.unit.test.d.ts +2 -0
- package/dist/tests/procaptchaWidget.unit.test.d.ts.map +1 -0
- package/dist/tests/procaptchaWidget.unit.test.js +547 -0
- package/dist/tests/procaptchaWidget.unit.test.js.map +1 -0
- package/dist/tests/puzzleCanvas.unit.test.d.ts +2 -0
- package/dist/tests/puzzleCanvas.unit.test.d.ts.map +1 -0
- package/dist/tests/puzzleCanvas.unit.test.js +312 -0
- package/dist/tests/puzzleCanvas.unit.test.js.map +1 -0
- package/dist/tests/setup.d.ts +5 -0
- package/dist/tests/setup.d.ts.map +1 -0
- package/dist/tests/setup.js +3 -0
- package/dist/tests/setup.js.map +1 -0
- package/package.json +10 -5
- package/src/components/ProcaptchaWidget.tsx +17 -6
- package/src/services/Manager.ts +10 -6
- package/src/tests/manager.unit.test.ts +763 -0
- package/src/tests/managerHarness.ts +169 -0
- package/src/tests/procaptchaPuzzle.test-d.ts +191 -0
- package/src/tests/procaptchaPuzzle.unit.test.ts +123 -0
- package/src/tests/procaptchaWidget.unit.test.ts +789 -0
- package/src/tests/puzzleCanvas.unit.test.ts +418 -0
- package/src/tests/setup.ts +26 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.test.config.ts +27 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { act, createElement } from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, test, vi, } from "vitest";
|
|
4
|
+
import { PuzzleCanvas } from "../components/PuzzleCanvas.js";
|
|
5
|
+
const CONTAINER_WIDTH = 300;
|
|
6
|
+
const CONTAINER_HEIGHT = 200;
|
|
7
|
+
const PIECE_SIZE = 24;
|
|
8
|
+
let container;
|
|
9
|
+
let root;
|
|
10
|
+
let onComplete;
|
|
11
|
+
const props = (overrides = {}) => ({
|
|
12
|
+
originX: 20,
|
|
13
|
+
originY: 100,
|
|
14
|
+
targetX: 200,
|
|
15
|
+
targetY: 80,
|
|
16
|
+
onComplete,
|
|
17
|
+
showRetry: false,
|
|
18
|
+
submitting: false,
|
|
19
|
+
...overrides,
|
|
20
|
+
});
|
|
21
|
+
const render = (canvasProps) => {
|
|
22
|
+
act(() => {
|
|
23
|
+
root.render(createElement(PuzzleCanvas, canvasProps));
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
const piece = () => {
|
|
27
|
+
const element = container.querySelector('[data-cy="prosopo-puzzle-piece"]');
|
|
28
|
+
if (!element)
|
|
29
|
+
throw new Error("expected the puzzle piece to be rendered");
|
|
30
|
+
return element;
|
|
31
|
+
};
|
|
32
|
+
const piecePosition = () => ({
|
|
33
|
+
x: Number.parseFloat(piece().style.left) + PIECE_SIZE / 2,
|
|
34
|
+
y: Number.parseFloat(piece().style.top) + PIECE_SIZE / 2,
|
|
35
|
+
});
|
|
36
|
+
const mouseDown = (clientX, clientY) => {
|
|
37
|
+
act(() => {
|
|
38
|
+
piece().dispatchEvent(new MouseEvent("mousedown", { bubbles: true, clientX, clientY }));
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const mouseMove = (clientX, clientY) => {
|
|
42
|
+
act(() => {
|
|
43
|
+
document.dispatchEvent(new MouseEvent("mousemove", { bubbles: true, clientX, clientY }));
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const mouseUp = () => {
|
|
47
|
+
act(() => {
|
|
48
|
+
document.dispatchEvent(new MouseEvent("mouseup", { bubbles: true }));
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const touchEvent = (type, touches) => {
|
|
52
|
+
const event = new Event(type, { bubbles: true });
|
|
53
|
+
Object.defineProperty(event, "touches", { value: touches });
|
|
54
|
+
return event;
|
|
55
|
+
};
|
|
56
|
+
const touchStart = (touches) => {
|
|
57
|
+
act(() => {
|
|
58
|
+
piece().dispatchEvent(touchEvent("touchstart", touches));
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const touchMove = (touches) => {
|
|
62
|
+
act(() => {
|
|
63
|
+
document.dispatchEvent(touchEvent("touchmove", touches));
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const touchEnd = () => {
|
|
67
|
+
act(() => {
|
|
68
|
+
document.dispatchEvent(touchEvent("touchend", []));
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
beforeEach(() => {
|
|
72
|
+
onComplete =
|
|
73
|
+
vi.fn();
|
|
74
|
+
container = document.createElement("div");
|
|
75
|
+
document.body.appendChild(container);
|
|
76
|
+
act(() => {
|
|
77
|
+
root = createRoot(container);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
afterEach(() => {
|
|
81
|
+
act(() => {
|
|
82
|
+
root.unmount();
|
|
83
|
+
});
|
|
84
|
+
container.remove();
|
|
85
|
+
vi.useRealTimers();
|
|
86
|
+
vi.restoreAllMocks();
|
|
87
|
+
});
|
|
88
|
+
describe("what it puts on screen", () => {
|
|
89
|
+
test("the piece starts at the origin the challenge named", () => {
|
|
90
|
+
render(props());
|
|
91
|
+
expect(piecePosition()).toEqual({ x: 20, y: 100 });
|
|
92
|
+
});
|
|
93
|
+
test("a new challenge moves the piece back to its new origin", () => {
|
|
94
|
+
render(props());
|
|
95
|
+
mouseDown(20, 100);
|
|
96
|
+
mouseMove(120, 120);
|
|
97
|
+
render(props({ originX: 50, originY: 60 }));
|
|
98
|
+
expect(piecePosition()).toEqual({ x: 50, y: 60 });
|
|
99
|
+
});
|
|
100
|
+
test("re-rendering with the same origin leaves a dragged piece alone", () => {
|
|
101
|
+
render(props());
|
|
102
|
+
mouseDown(20, 100);
|
|
103
|
+
mouseMove(120, 120);
|
|
104
|
+
render(props());
|
|
105
|
+
expect(piecePosition()).toEqual({ x: 120, y: 120 });
|
|
106
|
+
});
|
|
107
|
+
test("the first go asks the user to drag the piece", () => {
|
|
108
|
+
render(props());
|
|
109
|
+
expect(container.textContent).toContain("Drag the piece to the target");
|
|
110
|
+
});
|
|
111
|
+
test("a retry says so instead", () => {
|
|
112
|
+
render(props({ showRetry: true }));
|
|
113
|
+
expect(container.textContent).toContain("Not quite");
|
|
114
|
+
});
|
|
115
|
+
test("the piece cannot be grabbed while a solution is in flight", () => {
|
|
116
|
+
render(props({ submitting: true }));
|
|
117
|
+
mouseDown(20, 100);
|
|
118
|
+
mouseMove(120, 120);
|
|
119
|
+
mouseUp();
|
|
120
|
+
expect(piecePosition()).toEqual({ x: 20, y: 100 });
|
|
121
|
+
expect(onComplete).not.toHaveBeenCalled();
|
|
122
|
+
});
|
|
123
|
+
test("a tap cannot be started while a solution is in flight either", () => {
|
|
124
|
+
render(props({ submitting: true }));
|
|
125
|
+
touchStart([{ clientX: 20, clientY: 100 }]);
|
|
126
|
+
touchMove([{ clientX: 120, clientY: 120 }]);
|
|
127
|
+
touchEnd();
|
|
128
|
+
expect(onComplete).not.toHaveBeenCalled();
|
|
129
|
+
});
|
|
130
|
+
test("the shake on a retry stops on its own", () => {
|
|
131
|
+
vi.useFakeTimers();
|
|
132
|
+
render(props({ showRetry: true }));
|
|
133
|
+
act(() => {
|
|
134
|
+
vi.advanceTimersByTime(600);
|
|
135
|
+
});
|
|
136
|
+
expect(piecePosition()).toEqual({ x: 20, y: 100 });
|
|
137
|
+
});
|
|
138
|
+
test("unmounting mid-shake cancels the timer", () => {
|
|
139
|
+
vi.useFakeTimers();
|
|
140
|
+
render(props({ showRetry: true }));
|
|
141
|
+
act(() => {
|
|
142
|
+
root.unmount();
|
|
143
|
+
});
|
|
144
|
+
act(() => {
|
|
145
|
+
vi.advanceTimersByTime(600);
|
|
146
|
+
});
|
|
147
|
+
act(() => {
|
|
148
|
+
root = createRoot(container);
|
|
149
|
+
});
|
|
150
|
+
expect(container.querySelector('[data-cy="prosopo-puzzle-piece"]')).toBeNull();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
describe("dragging with a mouse", () => {
|
|
154
|
+
test("the piece follows the pointer", () => {
|
|
155
|
+
render(props());
|
|
156
|
+
mouseDown(20, 100);
|
|
157
|
+
mouseMove(150, 90);
|
|
158
|
+
expect(piecePosition()).toEqual({ x: 150, y: 90 });
|
|
159
|
+
});
|
|
160
|
+
test("grabbing the piece off-centre keeps the offset", () => {
|
|
161
|
+
render(props());
|
|
162
|
+
mouseDown(25, 100);
|
|
163
|
+
mouseMove(150, 100);
|
|
164
|
+
expect(piecePosition()).toEqual({ x: 145, y: 100 });
|
|
165
|
+
});
|
|
166
|
+
test("a pointer moving before the piece is grabbed is ignored", () => {
|
|
167
|
+
render(props());
|
|
168
|
+
mouseMove(150, 90);
|
|
169
|
+
expect(piecePosition()).toEqual({ x: 20, y: 100 });
|
|
170
|
+
});
|
|
171
|
+
test("the piece cannot be dragged off the left or top of the board", () => {
|
|
172
|
+
render(props());
|
|
173
|
+
mouseDown(20, 100);
|
|
174
|
+
mouseMove(-500, -500);
|
|
175
|
+
expect(piecePosition()).toEqual({ x: 0, y: 0 });
|
|
176
|
+
});
|
|
177
|
+
test("nor off the right or bottom", () => {
|
|
178
|
+
render(props());
|
|
179
|
+
mouseDown(20, 100);
|
|
180
|
+
mouseMove(5000, 5000);
|
|
181
|
+
expect(piecePosition()).toEqual({
|
|
182
|
+
x: CONTAINER_WIDTH,
|
|
183
|
+
y: CONTAINER_HEIGHT,
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
test("letting go reports where the piece landed, with the trail", () => {
|
|
187
|
+
render(props());
|
|
188
|
+
mouseDown(20, 100);
|
|
189
|
+
mouseMove(100, 95);
|
|
190
|
+
mouseMove(200, 80);
|
|
191
|
+
mouseUp();
|
|
192
|
+
expect(onComplete).toHaveBeenCalledTimes(1);
|
|
193
|
+
const [finalX, finalY, events] = onComplete.mock.calls[0] ?? [];
|
|
194
|
+
expect(finalX).toBe(200);
|
|
195
|
+
expect(finalY).toBe(80);
|
|
196
|
+
expect(events?.map((event) => [event.x, event.y])).toEqual([
|
|
197
|
+
[100, 95],
|
|
198
|
+
[200, 80],
|
|
199
|
+
]);
|
|
200
|
+
});
|
|
201
|
+
test("a grab released without moving reports the origin and no trail", () => {
|
|
202
|
+
render(props());
|
|
203
|
+
mouseDown(20, 100);
|
|
204
|
+
mouseUp();
|
|
205
|
+
expect(onComplete).toHaveBeenCalledWith(20, 100, []);
|
|
206
|
+
});
|
|
207
|
+
test("letting go without having grabbed anything reports nothing", () => {
|
|
208
|
+
render(props());
|
|
209
|
+
mouseUp();
|
|
210
|
+
expect(onComplete).not.toHaveBeenCalled();
|
|
211
|
+
});
|
|
212
|
+
test("a second release after the drop is ignored", () => {
|
|
213
|
+
render(props());
|
|
214
|
+
mouseDown(20, 100);
|
|
215
|
+
mouseMove(200, 80);
|
|
216
|
+
mouseUp();
|
|
217
|
+
mouseUp();
|
|
218
|
+
expect(onComplete).toHaveBeenCalledTimes(1);
|
|
219
|
+
});
|
|
220
|
+
test("moving after the drop no longer moves the piece", () => {
|
|
221
|
+
render(props());
|
|
222
|
+
mouseDown(20, 100);
|
|
223
|
+
mouseMove(200, 80);
|
|
224
|
+
mouseUp();
|
|
225
|
+
mouseMove(50, 50);
|
|
226
|
+
expect(piecePosition()).toEqual({ x: 200, y: 80 });
|
|
227
|
+
});
|
|
228
|
+
test("a second drag starts from a clean trail", () => {
|
|
229
|
+
render(props());
|
|
230
|
+
mouseDown(20, 100);
|
|
231
|
+
mouseMove(100, 95);
|
|
232
|
+
mouseUp();
|
|
233
|
+
mouseDown(100, 95);
|
|
234
|
+
mouseMove(200, 80);
|
|
235
|
+
mouseUp();
|
|
236
|
+
const events = onComplete.mock.calls[1]?.[2];
|
|
237
|
+
expect(events?.map((event) => [event.x, event.y])).toEqual([[200, 80]]);
|
|
238
|
+
});
|
|
239
|
+
test("the trail is timestamped in order", () => {
|
|
240
|
+
render(props());
|
|
241
|
+
mouseDown(20, 100);
|
|
242
|
+
mouseMove(100, 95);
|
|
243
|
+
mouseMove(200, 80);
|
|
244
|
+
mouseUp();
|
|
245
|
+
const events = onComplete.mock.calls[0]?.[2] ?? [];
|
|
246
|
+
expect(events).toHaveLength(2);
|
|
247
|
+
expect(events[1]?.t).toBeGreaterThanOrEqual(events[0]?.t ?? 0);
|
|
248
|
+
});
|
|
249
|
+
test("the trail handed over is a copy, safe from the next drag", () => {
|
|
250
|
+
render(props());
|
|
251
|
+
mouseDown(20, 100);
|
|
252
|
+
mouseMove(200, 80);
|
|
253
|
+
mouseUp();
|
|
254
|
+
const events = onComplete.mock.calls[0]?.[2] ?? [];
|
|
255
|
+
mouseDown(200, 80);
|
|
256
|
+
mouseMove(10, 10);
|
|
257
|
+
expect(events).toHaveLength(1);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe("dragging with a finger", () => {
|
|
261
|
+
test("the piece follows the touch", () => {
|
|
262
|
+
render(props());
|
|
263
|
+
touchStart([{ clientX: 20, clientY: 100 }]);
|
|
264
|
+
touchMove([{ clientX: 150, clientY: 90 }]);
|
|
265
|
+
expect(piecePosition()).toEqual({ x: 150, y: 90 });
|
|
266
|
+
});
|
|
267
|
+
test("lifting the finger reports the drop", () => {
|
|
268
|
+
render(props());
|
|
269
|
+
touchStart([{ clientX: 20, clientY: 100 }]);
|
|
270
|
+
touchMove([{ clientX: 200, clientY: 80 }]);
|
|
271
|
+
touchEnd();
|
|
272
|
+
expect(onComplete).toHaveBeenCalledWith(200, 80, [
|
|
273
|
+
expect.objectContaining({ x: 200, y: 80 }),
|
|
274
|
+
]);
|
|
275
|
+
});
|
|
276
|
+
test("a touchstart carrying no touches does not start a drag", () => {
|
|
277
|
+
render(props());
|
|
278
|
+
touchStart([]);
|
|
279
|
+
touchMove([{ clientX: 150, clientY: 90 }]);
|
|
280
|
+
touchEnd();
|
|
281
|
+
expect(piecePosition()).toEqual({ x: 20, y: 100 });
|
|
282
|
+
expect(onComplete).not.toHaveBeenCalled();
|
|
283
|
+
});
|
|
284
|
+
test("a touchmove carrying no touches is ignored mid-drag", () => {
|
|
285
|
+
render(props());
|
|
286
|
+
touchStart([{ clientX: 20, clientY: 100 }]);
|
|
287
|
+
touchMove([]);
|
|
288
|
+
expect(piecePosition()).toEqual({ x: 20, y: 100 });
|
|
289
|
+
});
|
|
290
|
+
test("a finger drag is clamped to the board like a mouse drag", () => {
|
|
291
|
+
render(props());
|
|
292
|
+
touchStart([{ clientX: 20, clientY: 100 }]);
|
|
293
|
+
touchMove([{ clientX: 9999, clientY: -9999 }]);
|
|
294
|
+
expect(piecePosition()).toEqual({ x: CONTAINER_WIDTH, y: 0 });
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
describe("after it goes away", () => {
|
|
298
|
+
test("its document listeners go with it", () => {
|
|
299
|
+
render(props());
|
|
300
|
+
mouseDown(20, 100);
|
|
301
|
+
act(() => {
|
|
302
|
+
root.unmount();
|
|
303
|
+
});
|
|
304
|
+
mouseMove(150, 90);
|
|
305
|
+
mouseUp();
|
|
306
|
+
expect(onComplete).not.toHaveBeenCalled();
|
|
307
|
+
act(() => {
|
|
308
|
+
root = createRoot(container);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
//# sourceMappingURL=puzzleCanvas.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleCanvas.unit.test.js","sourceRoot":"","sources":["../../src/tests/puzzleCanvas.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/tests/setup.ts"],"names":[],"mappings":"AAmBA,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,wBAAwB,EAAE,OAAO,CAAC;CACtC;AAID,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/tests/setup.ts"],"names":[],"mappings":"AAuBA,UAAU,CAAC,wBAAwB,GAAG,IAAI,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/procaptcha-puzzle",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.42",
|
|
4
4
|
"author": "PROSOPO LIMITED <info@prosopo.io>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,15 +25,18 @@
|
|
|
25
25
|
"build:cross-env": "vite build --config vite.esm.config.ts",
|
|
26
26
|
"build:tsc": "tsc --build --verbose",
|
|
27
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"
|
|
28
|
+
"typecheck": "tsc --project tsconfig.types.json",
|
|
29
|
+
"test": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --config ./vite.test.config.ts",
|
|
30
|
+
"test:watch": "NODE_ENV=${NODE_ENV:-test}; npx vitest --config ./vite.test.config.ts",
|
|
31
|
+
"test:coverage": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --coverage --config ./vite.test.config.ts"
|
|
29
32
|
},
|
|
30
33
|
"browserslist": ["> 0.5%, last 2 versions, not dead"],
|
|
31
34
|
"dependencies": {
|
|
32
35
|
"@polkadot/util": "13.5.7",
|
|
33
|
-
"@prosopo/api": "3.5.
|
|
36
|
+
"@prosopo/api": "3.5.21",
|
|
34
37
|
"@prosopo/common": "3.1.48",
|
|
35
38
|
"@prosopo/locale": "3.2.8",
|
|
36
|
-
"@prosopo/procaptcha-common": "2.11.
|
|
39
|
+
"@prosopo/procaptcha-common": "2.11.19",
|
|
37
40
|
"@prosopo/types": "4.10.0",
|
|
38
41
|
"@prosopo/util": "3.3.5",
|
|
39
42
|
"@prosopo/util-crypto": "13.5.30",
|
|
@@ -41,14 +44,16 @@
|
|
|
41
44
|
"react": "18.3.1"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
44
|
-
"@prosopo/config": "3.3.5",
|
|
45
47
|
"@emotion/react": "11.11.1",
|
|
46
48
|
"@emotion/styled": "11.11.0",
|
|
49
|
+
"@prosopo/config": "3.3.5",
|
|
47
50
|
"@types/node": "22.5.5",
|
|
48
51
|
"@vitest/coverage-v8": "4.1.10",
|
|
49
52
|
"concurrently": "9.0.1",
|
|
50
53
|
"del-cli": "6.0.0",
|
|
54
|
+
"jsdom": "26.1.0",
|
|
51
55
|
"npm-run-all": "4.1.5",
|
|
56
|
+
"react-dom": "18.3.1",
|
|
52
57
|
"tslib": "2.7.0",
|
|
53
58
|
"tsx": "4.20.3",
|
|
54
59
|
"typescript": "5.6.2",
|
|
@@ -269,14 +269,25 @@ const Procaptcha = (props: ProcaptchaProps) => {
|
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
lastCoordsRef.current = { x, y };
|
|
272
|
-
|
|
272
|
+
try {
|
|
273
|
+
const challenge = await manager.current.start(x, y);
|
|
273
274
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
if (challenge) {
|
|
276
|
+
setChallengeData(challenge);
|
|
277
|
+
setPuzzlePhase("dragging");
|
|
278
|
+
}
|
|
279
|
+
} catch (error) {
|
|
280
|
+
// The manager reports failures through state.error;
|
|
281
|
+
// rethrowing here only produces an unhandled rejection,
|
|
282
|
+
// since nothing awaits this handler.
|
|
283
|
+
callbacks.onError?.(
|
|
284
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
285
|
+
);
|
|
286
|
+
} finally {
|
|
287
|
+
// A rejected start would otherwise leave the spinner up for
|
|
288
|
+
// good, with no way back to the checkbox for the user.
|
|
289
|
+
setLoading(false);
|
|
277
290
|
}
|
|
278
|
-
|
|
279
|
-
setLoading(false);
|
|
280
291
|
}}
|
|
281
292
|
labelText={isTranslationReady ? t("WIDGET.I_AM_HUMAN") : ""}
|
|
282
293
|
error={state.error?.message}
|
package/src/services/Manager.ts
CHANGED
|
@@ -193,11 +193,6 @@ export const Manager = (
|
|
|
193
193
|
x = 0,
|
|
194
194
|
y = 0,
|
|
195
195
|
): Promise<GetPuzzleCaptchaResponse | undefined> => {
|
|
196
|
-
// Persist click coords on every entry so retries inherit the
|
|
197
|
-
// trusted coordinates captured by the widget on initial click.
|
|
198
|
-
storedClickX = x;
|
|
199
|
-
storedClickY = y;
|
|
200
|
-
|
|
201
196
|
await providerRetry(
|
|
202
197
|
async () => {
|
|
203
198
|
if (state.loading) {
|
|
@@ -210,6 +205,13 @@ export const Manager = (
|
|
|
210
205
|
// reset the state to defaults - do not reset the frictionless state
|
|
211
206
|
resetState();
|
|
212
207
|
|
|
208
|
+
// Persist click coords on every entry so retries inherit the
|
|
209
|
+
// trusted coordinates captured by the widget on initial click.
|
|
210
|
+
// Set after the reset, which clears the closure state: setting
|
|
211
|
+
// them before it meant the salt never carried the coordinates.
|
|
212
|
+
storedClickX = x;
|
|
213
|
+
storedClickY = y;
|
|
214
|
+
|
|
213
215
|
// set the loading flag to true (allow UI to show some sort of loading / pending indicator while we get the captcha process going)
|
|
214
216
|
updateState({
|
|
215
217
|
loading: true,
|
|
@@ -304,7 +306,9 @@ export const Manager = (
|
|
|
304
306
|
});
|
|
305
307
|
},
|
|
306
308
|
async () => {
|
|
307
|
-
|
|
309
|
+
// Carry the original coords into the retry: re-entering with the
|
|
310
|
+
// defaults would replace the user's real click with (0, 0).
|
|
311
|
+
await start(x, y);
|
|
308
312
|
},
|
|
309
313
|
() => {
|
|
310
314
|
resetState();
|