@prosopo/procaptcha-puzzle 2.10.40 → 2.10.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +4 -4
  2. package/.turbo/turbo-build$colon$tsc.log +19 -19
  3. package/.turbo/turbo-build.log +6 -6
  4. package/CHANGELOG.md +7 -0
  5. package/dist/cjs/components/ProcaptchaWidget.cjs +10 -5
  6. package/dist/cjs/services/Manager.cjs +3 -3
  7. package/dist/components/ProcaptchaWidget.d.ts.map +1 -1
  8. package/dist/components/ProcaptchaWidget.js +10 -5
  9. package/dist/components/ProcaptchaWidget.js.map +1 -1
  10. package/dist/services/Manager.d.ts.map +1 -1
  11. package/dist/services/Manager.js +3 -3
  12. package/dist/services/Manager.js.map +1 -1
  13. package/dist/tests/manager.unit.test.d.ts +2 -0
  14. package/dist/tests/manager.unit.test.d.ts.map +1 -0
  15. package/dist/tests/manager.unit.test.js +506 -0
  16. package/dist/tests/manager.unit.test.js.map +1 -0
  17. package/dist/tests/managerHarness.d.ts +20 -0
  18. package/dist/tests/managerHarness.d.ts.map +1 -0
  19. package/dist/tests/managerHarness.js +86 -0
  20. package/dist/tests/managerHarness.js.map +1 -0
  21. package/dist/tests/procaptchaPuzzle.test-d.d.ts +2 -0
  22. package/dist/tests/procaptchaPuzzle.test-d.d.ts.map +1 -0
  23. package/dist/tests/procaptchaPuzzle.test-d.js +97 -0
  24. package/dist/tests/procaptchaPuzzle.test-d.js.map +1 -0
  25. package/dist/tests/procaptchaPuzzle.unit.test.d.ts +2 -0
  26. package/dist/tests/procaptchaPuzzle.unit.test.d.ts.map +1 -0
  27. package/dist/tests/procaptchaPuzzle.unit.test.js +81 -0
  28. package/dist/tests/procaptchaPuzzle.unit.test.js.map +1 -0
  29. package/dist/tests/procaptchaWidget.unit.test.d.ts +2 -0
  30. package/dist/tests/procaptchaWidget.unit.test.d.ts.map +1 -0
  31. package/dist/tests/procaptchaWidget.unit.test.js +547 -0
  32. package/dist/tests/procaptchaWidget.unit.test.js.map +1 -0
  33. package/dist/tests/puzzleCanvas.unit.test.d.ts +2 -0
  34. package/dist/tests/puzzleCanvas.unit.test.d.ts.map +1 -0
  35. package/dist/tests/puzzleCanvas.unit.test.js +312 -0
  36. package/dist/tests/puzzleCanvas.unit.test.js.map +1 -0
  37. package/dist/tests/setup.d.ts +5 -0
  38. package/dist/tests/setup.d.ts.map +1 -0
  39. package/dist/tests/setup.js +3 -0
  40. package/dist/tests/setup.js.map +1 -0
  41. package/package.json +9 -4
  42. package/src/components/ProcaptchaWidget.tsx +17 -6
  43. package/src/services/Manager.ts +10 -6
  44. package/src/tests/manager.unit.test.ts +763 -0
  45. package/src/tests/managerHarness.ts +169 -0
  46. package/src/tests/procaptchaPuzzle.test-d.ts +191 -0
  47. package/src/tests/procaptchaPuzzle.unit.test.ts +123 -0
  48. package/src/tests/procaptchaWidget.unit.test.ts +789 -0
  49. package/src/tests/puzzleCanvas.unit.test.ts +418 -0
  50. package/src/tests/setup.ts +26 -0
  51. package/tsconfig.tsbuildinfo +1 -1
  52. package/vite.test.config.ts +27 -0
@@ -0,0 +1,506 @@
1
+ import { ApiParams, CaptchaType, decodeProcaptchaOutput, } from "@prosopo/types";
2
+ import { extractData } from "@prosopo/util";
3
+ import { afterEach, beforeEach, describe, expect, test, vi, } from "vitest";
4
+ import { Manager } from "../services/Manager.js";
5
+ import { OTHER_PROVIDER_URL, PROVIDER_URL, SITE_KEY, USER_ADDRESS, account, accountWithoutExtension, callbacks, challengeResponse, collector, config, frictionless, puzzleEvents, randomProvider, signRawMock, solutionResponse, state, timerHandle, } from "./managerHarness.js";
6
+ const mocks = vi.hoisted(() => {
7
+ const providerApiConstructions = [];
8
+ const getPuzzleCaptchaChallenge = vi.fn();
9
+ const submitPuzzleCaptchaSolution = vi.fn();
10
+ class ProviderApiMock {
11
+ constructor(url, siteKey) {
12
+ this.getPuzzleCaptchaChallenge = getPuzzleCaptchaChallenge;
13
+ this.submitPuzzleCaptchaSolution = submitPuzzleCaptchaSolution;
14
+ providerApiConstructions.push({ url, siteKey });
15
+ }
16
+ }
17
+ const getAccount = vi.fn();
18
+ class ExtensionMock {
19
+ constructor() {
20
+ this.getAccount = getAccount;
21
+ }
22
+ }
23
+ const extensionLoader = vi.fn();
24
+ const getProcaptchaRandomActiveProvider = vi.fn();
25
+ const getSimdReadingsForSubmit = vi.fn();
26
+ const sleep = vi.fn();
27
+ return {
28
+ providerApiConstructions,
29
+ getPuzzleCaptchaChallenge,
30
+ submitPuzzleCaptchaSolution,
31
+ ProviderApiMock,
32
+ getAccount,
33
+ ExtensionMock,
34
+ extensionLoader,
35
+ getProcaptchaRandomActiveProvider,
36
+ getSimdReadingsForSubmit,
37
+ sleep,
38
+ };
39
+ });
40
+ vi.mock("@prosopo/api", async (importOriginal) => {
41
+ const actual = await importOriginal();
42
+ return { ...actual, ProviderApi: mocks.ProviderApiMock };
43
+ });
44
+ vi.mock("@prosopo/procaptcha-common", async (importOriginal) => {
45
+ const actual = await importOriginal();
46
+ return {
47
+ ...actual,
48
+ ExtensionLoader: mocks.extensionLoader,
49
+ getProcaptchaRandomActiveProvider: mocks.getProcaptchaRandomActiveProvider,
50
+ getSimdReadingsForSubmit: mocks.getSimdReadingsForSubmit,
51
+ providerRetry: (currentFn, retryFn, stateReset, attemptCount, retryMax) => actual.providerRetry(currentFn, retryFn, stateReset, attemptCount, retryMax, 0),
52
+ };
53
+ });
54
+ vi.mock("@prosopo/util", async (importOriginal) => {
55
+ const actual = await importOriginal();
56
+ return { ...actual, sleep: mocks.sleep };
57
+ });
58
+ const build = (options = {}) => {
59
+ const currentState = state(options.initialState);
60
+ const updates = [];
61
+ const events = {
62
+ onHuman: vi.fn(),
63
+ onFailed: vi.fn(),
64
+ onExpired: vi.fn(),
65
+ onReset: vi.fn(),
66
+ };
67
+ const restart = vi.fn();
68
+ const callbackInput = callbacks(events);
69
+ const frictionlessState = options.frictionlessState ??
70
+ (options.withFrictionless === false
71
+ ? undefined
72
+ : frictionless({ restart }));
73
+ const manager = Manager(options.configInput ?? config(), currentState, (next) => {
74
+ updates.push({ ...next });
75
+ }, callbackInput, frictionlessState, options.honeypot);
76
+ return { manager, state: currentState, updates, events, restart };
77
+ };
78
+ const lastUpdate = (harness, key) => {
79
+ const withKey = harness.updates.filter((update) => key in update);
80
+ return withKey.length === 0 ? undefined : withKey[withKey.length - 1]?.[key];
81
+ };
82
+ const submitArgs = (callIndex = 0) => {
83
+ const call = mocks.submitPuzzleCaptchaSolution.mock.calls[callIndex];
84
+ if (!call)
85
+ throw new Error("expected a solution to have been submitted");
86
+ return call;
87
+ };
88
+ const solve = async (harness) => {
89
+ await harness.manager.start(11, 22);
90
+ return harness.manager.submitSolution(200, 80, puzzleEvents());
91
+ };
92
+ const signRaw = signRawMock;
93
+ beforeEach(() => {
94
+ vi.clearAllMocks();
95
+ mocks.providerApiConstructions.length = 0;
96
+ signRaw.mockResolvedValue({ id: 1, signature: "0xuser-signature" });
97
+ mocks.getAccount.mockResolvedValue(account(signRaw));
98
+ mocks.extensionLoader.mockResolvedValue(mocks.ExtensionMock);
99
+ mocks.getProcaptchaRandomActiveProvider.mockResolvedValue(randomProvider());
100
+ mocks.getPuzzleCaptchaChallenge.mockResolvedValue(challengeResponse());
101
+ mocks.submitPuzzleCaptchaSolution.mockResolvedValue(solutionResponse());
102
+ mocks.getSimdReadingsForSubmit.mockResolvedValue("simd-readings");
103
+ mocks.sleep.mockResolvedValue(undefined);
104
+ vi.spyOn(console, "error").mockImplementation(() => undefined);
105
+ vi.spyOn(console, "log").mockImplementation(() => undefined);
106
+ });
107
+ afterEach(() => {
108
+ vi.useRealTimers();
109
+ vi.restoreAllMocks();
110
+ });
111
+ describe("start: the cases it refuses to run", () => {
112
+ test("a solve already in flight is left alone", async () => {
113
+ const harness = build({ initialState: { loading: true } });
114
+ await harness.manager.start();
115
+ expect(mocks.getPuzzleCaptchaChallenge).not.toHaveBeenCalled();
116
+ expect(harness.updates).toHaveLength(0);
117
+ });
118
+ test("a user already proven human is not asked again", async () => {
119
+ const harness = build({ initialState: { isHuman: true } });
120
+ await harness.manager.start();
121
+ expect(mocks.getPuzzleCaptchaChallenge).not.toHaveBeenCalled();
122
+ expect(harness.events.onHuman).not.toHaveBeenCalled();
123
+ });
124
+ test("a refused start still resolves, with no challenge to hand back", async () => {
125
+ const harness = build({ initialState: { isHuman: true } });
126
+ await expect(harness.manager.start()).resolves.toBeUndefined();
127
+ });
128
+ });
129
+ describe("start: getting to a challenge", () => {
130
+ test("resets the widget first, so a stale challenge cannot linger", async () => {
131
+ const harness = build({ initialState: { index: 3, showModal: true } });
132
+ await harness.manager.start();
133
+ const resetAt = harness.updates.findIndex((update) => "showModal" in update);
134
+ expect(harness.updates[resetAt]).toMatchObject({
135
+ showModal: false,
136
+ loading: false,
137
+ index: 0,
138
+ isHuman: false,
139
+ });
140
+ expect(harness.events.onReset).toHaveBeenCalled();
141
+ });
142
+ test("counts the attempt, so provider selection can rotate on a retry", async () => {
143
+ const harness = build({ initialState: { attemptCount: 2 } });
144
+ await harness.manager.start();
145
+ expect(lastUpdate(harness, "attemptCount")).toBe(3);
146
+ });
147
+ test("asks the provider named by the frictionless state, when there is one", async () => {
148
+ const harness = build();
149
+ await harness.manager.start();
150
+ expect(mocks.getProcaptchaRandomActiveProvider).not.toHaveBeenCalled();
151
+ expect(mocks.providerApiConstructions).toEqual([
152
+ { url: PROVIDER_URL, siteKey: SITE_KEY },
153
+ ]);
154
+ });
155
+ test("picks a provider itself when the frictionless state has none", async () => {
156
+ const harness = build({
157
+ frictionlessState: frictionless({ provider: undefined }),
158
+ });
159
+ await harness.manager.start();
160
+ expect(mocks.getProcaptchaRandomActiveProvider).toHaveBeenCalledWith("production", undefined, { attempt: 1, excludeUrl: undefined });
161
+ });
162
+ test("excludes the provider that just failed from the next pick", async () => {
163
+ const harness = build({
164
+ frictionlessState: frictionless({ provider: undefined }),
165
+ });
166
+ await harness.manager.start();
167
+ await harness.manager.start();
168
+ expect(mocks.getProcaptchaRandomActiveProvider).toHaveBeenLastCalledWith("production", undefined, expect.objectContaining({ excludeUrl: PROVIDER_URL }));
169
+ });
170
+ test("loads an extension account when there is no frictionless state", async () => {
171
+ const harness = build({ withFrictionless: false });
172
+ await harness.manager.start();
173
+ expect(mocks.extensionLoader).toHaveBeenCalled();
174
+ expect(lastUpdate(harness, "account")).toEqual({
175
+ account: { address: USER_ADDRESS },
176
+ });
177
+ });
178
+ test("records the site key it was configured with as the dapp account", async () => {
179
+ const harness = build();
180
+ await harness.manager.start();
181
+ expect(lastUpdate(harness, "dappAccount")).toBe(SITE_KEY);
182
+ });
183
+ test("passes the session id and prefetched SIMD readings to the challenge call", async () => {
184
+ const getSimdReadings = vi.fn();
185
+ getSimdReadings.mockResolvedValue("prefetched");
186
+ const harness = build({
187
+ frictionlessState: frictionless({
188
+ sessionId: "session-1",
189
+ getSimdReadings,
190
+ }),
191
+ });
192
+ await harness.manager.start();
193
+ expect(mocks.getPuzzleCaptchaChallenge).toHaveBeenCalledWith(USER_ADDRESS, SITE_KEY, "session-1", "prefetched");
194
+ expect(getSimdReadings).toHaveBeenCalledWith(0);
195
+ });
196
+ test("omits SIMD readings when the frictionless state cannot supply them", async () => {
197
+ const harness = build();
198
+ await harness.manager.start();
199
+ expect(mocks.getPuzzleCaptchaChallenge).toHaveBeenCalledWith(USER_ADDRESS, SITE_KEY, undefined, undefined);
200
+ });
201
+ test("hands the challenge back and drops the loading flag", async () => {
202
+ const harness = build();
203
+ await expect(harness.manager.start()).resolves.toEqual(challengeResponse());
204
+ expect(lastUpdate(harness, "loading")).toBe(false);
205
+ });
206
+ });
207
+ describe("start: when the provider will not issue a challenge", () => {
208
+ test("surfaces the provider's error to the widget", async () => {
209
+ mocks.getPuzzleCaptchaChallenge.mockResolvedValue(challengeResponse({
210
+ error: {
211
+ message: "no session",
212
+ key: "CAPTCHA.NO_SESSION_FOUND",
213
+ code: 400,
214
+ },
215
+ }));
216
+ const harness = build();
217
+ await harness.manager.start();
218
+ expect(lastUpdate(harness, "error")).toEqual({
219
+ message: "no session",
220
+ key: "CAPTCHA.NO_SESSION_FOUND",
221
+ });
222
+ expect(lastUpdate(harness, "loading")).toBe(false);
223
+ });
224
+ test("labels an error the provider left unkeyed", async () => {
225
+ mocks.getPuzzleCaptchaChallenge.mockResolvedValue(challengeResponse({ error: { message: "something broke", code: 500 } }));
226
+ const harness = build();
227
+ await harness.manager.start();
228
+ expect(lastUpdate(harness, "error")).toEqual({
229
+ message: "something broke",
230
+ key: "API.UNKNOWN_ERROR",
231
+ });
232
+ });
233
+ test("keeps no challenge, so a submit afterwards cannot pretend one exists", async () => {
234
+ mocks.getPuzzleCaptchaChallenge.mockResolvedValue(challengeResponse({ error: { message: "no session", code: 400 } }));
235
+ const harness = build();
236
+ await expect(harness.manager.start()).resolves.toBeUndefined();
237
+ await expect(harness.manager.submitSolution(1, 2, [])).rejects.toThrow();
238
+ });
239
+ test("web3 mode without a configured account address refuses to continue", async () => {
240
+ const harness = build({
241
+ configInput: config({ web2: false, userAccountAddress: "" }),
242
+ frictionlessState: frictionless({ provider: undefined }),
243
+ });
244
+ await harness.manager.start();
245
+ expect(mocks.getPuzzleCaptchaChallenge).not.toHaveBeenCalled();
246
+ });
247
+ test("retries against a fresh provider when the challenge call throws", async () => {
248
+ mocks.getPuzzleCaptchaChallenge
249
+ .mockRejectedValueOnce(new Error("provider down"))
250
+ .mockResolvedValue(challengeResponse());
251
+ mocks.getProcaptchaRandomActiveProvider
252
+ .mockResolvedValueOnce(randomProvider())
253
+ .mockResolvedValue(randomProvider(OTHER_PROVIDER_URL));
254
+ const harness = build({
255
+ frictionlessState: frictionless({ provider: undefined }),
256
+ });
257
+ await harness.manager.start();
258
+ expect(mocks.getPuzzleCaptchaChallenge).toHaveBeenCalledTimes(2);
259
+ expect(mocks.providerApiConstructions.map((c) => c.url)).toEqual([
260
+ PROVIDER_URL,
261
+ OTHER_PROVIDER_URL,
262
+ ]);
263
+ });
264
+ test("gives up once the retry budget is spent", async () => {
265
+ mocks.getPuzzleCaptchaChallenge.mockRejectedValue(new Error("down"));
266
+ const harness = build({
267
+ frictionlessState: frictionless({ provider: undefined }),
268
+ });
269
+ await harness.manager.start();
270
+ expect(mocks.getPuzzleCaptchaChallenge.mock.calls.length).toBeLessThan(5);
271
+ expect(harness.events.onReset).toHaveBeenCalled();
272
+ });
273
+ });
274
+ describe("submitSolution: refusing to submit without a challenge", () => {
275
+ test("throws when start was never called", async () => {
276
+ const harness = build();
277
+ await expect(harness.manager.submitSolution(1, 2, puzzleEvents())).rejects.toThrow();
278
+ });
279
+ test("throws again after a reset has cleared the stored challenge", async () => {
280
+ const harness = build();
281
+ await harness.manager.start();
282
+ harness.manager.resetState();
283
+ await expect(harness.manager.submitSolution(1, 2, puzzleEvents())).rejects.toThrow();
284
+ });
285
+ test("refuses when the account carries no signer", async () => {
286
+ const harness = build({
287
+ frictionlessState: frictionless({ userAccount: account() }),
288
+ });
289
+ await harness.manager.start();
290
+ await expect(harness.manager.submitSolution(1, 2, puzzleEvents())).rejects.toThrow();
291
+ expect(lastUpdate(harness, "loading")).toBe(false);
292
+ });
293
+ test("refuses when the account has no extension at all", async () => {
294
+ const harness = build({
295
+ frictionlessState: frictionless({
296
+ userAccount: accountWithoutExtension(),
297
+ }),
298
+ });
299
+ await harness.manager.start();
300
+ await expect(harness.manager.submitSolution(1, 2, puzzleEvents())).rejects.toThrow();
301
+ });
302
+ test("clears loading and rethrows when the provider call fails", async () => {
303
+ mocks.submitPuzzleCaptchaSolution.mockRejectedValue(new Error("boom"));
304
+ const harness = build();
305
+ await harness.manager.start();
306
+ await expect(harness.manager.submitSolution(1, 2, puzzleEvents())).rejects.toThrow("boom");
307
+ expect(lastUpdate(harness, "loading")).toBe(false);
308
+ });
309
+ });
310
+ describe("submitSolution: what it sends", () => {
311
+ test("sends the drop position and the event trail as given", async () => {
312
+ const harness = build();
313
+ const events = puzzleEvents();
314
+ await harness.manager.start();
315
+ await harness.manager.submitSolution(201, 79, events);
316
+ const args = submitArgs();
317
+ expect(args[3]).toBe(201);
318
+ expect(args[4]).toBe(79);
319
+ expect(args[5]).toEqual(events);
320
+ });
321
+ test("an empty event trail is submitted rather than rejected", async () => {
322
+ const harness = build();
323
+ await harness.manager.start();
324
+ await harness.manager.submitSolution(200, 80, []);
325
+ expect(submitArgs()[5]).toEqual([]);
326
+ });
327
+ test("signs the challenge timestamp with the user's key", async () => {
328
+ const harness = build();
329
+ await harness.manager.start();
330
+ await harness.manager.submitSolution(200, 80, puzzleEvents());
331
+ expect(signRaw).toHaveBeenCalledWith(expect.objectContaining({ address: USER_ADDRESS, type: "bytes" }));
332
+ expect(submitArgs()[6]).toBe("0xuser-signature");
333
+ });
334
+ test("embeds the checkbox coordinates in the salt", async () => {
335
+ const harness = build();
336
+ await solve(harness);
337
+ const salt = submitArgs()[8];
338
+ if (!salt)
339
+ throw new Error("expected a salt");
340
+ expect(extractData(salt)).toEqual([11, 22]);
341
+ });
342
+ test("attaches the SIMD readings gathered at submit time", async () => {
343
+ const harness = build();
344
+ await solve(harness);
345
+ expect(submitArgs()[9]).toBe("simd-readings");
346
+ });
347
+ test("sends the honeypot value when the input was filled", async () => {
348
+ const harness = build({ honeypot: () => "trap" });
349
+ await solve(harness);
350
+ expect(submitArgs()[10]).toEqual({ hp: "trap" });
351
+ });
352
+ test("sends no client metadata when the honeypot is empty", async () => {
353
+ const harness = build({ honeypot: () => undefined });
354
+ await solve(harness);
355
+ expect(submitArgs()[10]).toBeUndefined();
356
+ });
357
+ test("sends no client metadata when there is no honeypot at all", async () => {
358
+ const harness = build();
359
+ await solve(harness);
360
+ expect(submitArgs()[10]).toBeUndefined();
361
+ });
362
+ });
363
+ describe("submitSolution: behavioural data", () => {
364
+ const withCollectors = (encryptBehavioralData) => frictionless({
365
+ encryptBehavioralData,
366
+ behaviorCollector1: collector([{ x: 1, y: 2, timestamp: 3 }]),
367
+ deviceCapability: "high",
368
+ });
369
+ test("encrypts and attaches what the collectors gathered", async () => {
370
+ const encrypt = vi.fn();
371
+ encrypt.mockResolvedValue("encrypted");
372
+ const harness = build({ frictionlessState: withCollectors(encrypt) });
373
+ await solve(harness);
374
+ expect(submitArgs()[7]).toBe("encrypted");
375
+ const payload = JSON.parse(encrypt.mock.calls[0]?.[0] ?? "null");
376
+ expect(payload).toMatchObject({
377
+ collector1: [{ x: 1, y: 2, timestamp: 3 }],
378
+ collector2: [],
379
+ collector3: [],
380
+ deviceCapability: "high",
381
+ });
382
+ });
383
+ test("submits without behavioural data when encryption fails", async () => {
384
+ const encrypt = vi.fn();
385
+ encrypt.mockRejectedValue(new Error("no key"));
386
+ const harness = build({ frictionlessState: withCollectors(encrypt) });
387
+ await expect(solve(harness)).resolves.toBe(true);
388
+ expect(submitArgs()[7]).toBeUndefined();
389
+ });
390
+ test("packs the data first when a packer is provided", async () => {
391
+ const packed = {
392
+ c1: [],
393
+ c2: [],
394
+ c3: [],
395
+ d: "high",
396
+ };
397
+ const encrypt = vi.fn();
398
+ encrypt.mockResolvedValue("encrypted");
399
+ const base = withCollectors(encrypt);
400
+ const harness = build({
401
+ frictionlessState: {
402
+ ...base,
403
+ packBehavioralData: () => packed,
404
+ },
405
+ });
406
+ await solve(harness);
407
+ expect(encrypt).toHaveBeenCalledWith(JSON.stringify(packed));
408
+ });
409
+ test("skips the whole step when no collector is attached", async () => {
410
+ const encrypt = vi.fn();
411
+ const harness = build({
412
+ frictionlessState: frictionless({ encryptBehavioralData: encrypt }),
413
+ });
414
+ await solve(harness);
415
+ expect(encrypt).not.toHaveBeenCalled();
416
+ expect(submitArgs()[7]).toBeUndefined();
417
+ });
418
+ test("skips the whole step when nothing can encrypt", async () => {
419
+ const harness = build({
420
+ frictionlessState: frictionless({
421
+ behaviorCollector1: collector([]),
422
+ }),
423
+ });
424
+ await solve(harness);
425
+ expect(submitArgs()[7]).toBeUndefined();
426
+ });
427
+ });
428
+ describe("submitSolution: the verdict", () => {
429
+ test("marks the user human and emits a token the provider can verify", async () => {
430
+ const harness = build();
431
+ await expect(solve(harness)).resolves.toBe(true);
432
+ expect(lastUpdate(harness, "isHuman")).toBe(true);
433
+ const token = harness.events.onHuman.mock.calls[0]?.[0];
434
+ if (!token)
435
+ throw new Error("expected a token");
436
+ expect(decodeProcaptchaOutput(token)).toMatchObject({
437
+ [ApiParams.providerUrl]: PROVIDER_URL,
438
+ [ApiParams.user]: USER_ADDRESS,
439
+ [ApiParams.dapp]: SITE_KEY,
440
+ [ApiParams.captchaType]: CaptchaType.puzzle,
441
+ });
442
+ });
443
+ test("expires the human state once the solution timeout elapses", async () => {
444
+ vi.useFakeTimers();
445
+ const harness = build();
446
+ await solve(harness);
447
+ expect(lastUpdate(harness, "successfullChallengeTimeout")).toBeDefined();
448
+ await vi.runOnlyPendingTimersAsync();
449
+ expect(harness.events.onExpired).toHaveBeenCalled();
450
+ expect(lastUpdate(harness, "isHuman")).toBe(false);
451
+ });
452
+ test("a rejected solution fails the widget and restarts frictionless", async () => {
453
+ mocks.submitPuzzleCaptchaSolution.mockResolvedValue(solutionResponse({ verified: false }));
454
+ const harness = build();
455
+ await expect(solve(harness)).resolves.toBe(false);
456
+ expect(harness.events.onFailed).toHaveBeenCalled();
457
+ expect(harness.events.onHuman).not.toHaveBeenCalled();
458
+ expect(harness.restart).toHaveBeenCalled();
459
+ expect(lastUpdate(harness, "isHuman")).toBe(false);
460
+ });
461
+ test("a rejected solution without a frictionless state still resets", async () => {
462
+ mocks.submitPuzzleCaptchaSolution.mockResolvedValue(solutionResponse({ verified: false }));
463
+ const harness = build({ withFrictionless: false });
464
+ await expect(solve(harness)).resolves.toBe(false);
465
+ expect(harness.events.onReset).toHaveBeenCalled();
466
+ });
467
+ });
468
+ describe("resetState", () => {
469
+ test("clears the widget back to its defaults and announces the reset", () => {
470
+ const harness = build();
471
+ harness.manager.resetState();
472
+ expect(harness.updates).toContainEqual(expect.objectContaining({
473
+ showModal: false,
474
+ loading: false,
475
+ index: 0,
476
+ isHuman: false,
477
+ }));
478
+ expect(harness.events.onReset).toHaveBeenCalledTimes(1);
479
+ });
480
+ test("clears both timers so a stale expiry cannot fire later", () => {
481
+ const clear = vi.spyOn(window, "clearTimeout");
482
+ const harness = build({
483
+ initialState: {
484
+ timeout: timerHandle(11),
485
+ successfullChallengeTimeout: timerHandle(22),
486
+ },
487
+ });
488
+ harness.manager.resetState();
489
+ expect(clear).toHaveBeenCalledWith(timerHandle(11));
490
+ expect(clear).toHaveBeenCalledWith(timerHandle(22));
491
+ });
492
+ test("runs the frictionless restart it is handed", () => {
493
+ const restart = vi.fn();
494
+ const harness = build();
495
+ harness.manager.resetState(restart);
496
+ expect(restart).toHaveBeenCalledTimes(1);
497
+ });
498
+ test("a start after a reset re-fetches rather than reusing the old challenge", async () => {
499
+ const harness = build();
500
+ await harness.manager.start();
501
+ harness.manager.resetState();
502
+ await harness.manager.start();
503
+ expect(mocks.getPuzzleCaptchaChallenge).toHaveBeenCalledTimes(2);
504
+ });
505
+ });
506
+ //# sourceMappingURL=manager.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.unit.test.js","sourceRoot":"","sources":["../../src/tests/manager.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Account, FrictionlessState, GetPuzzleCaptchaResponse, MouseMovementPoint, ProcaptchaCallbacks, ProcaptchaClientConfigInput, ProcaptchaState, PuzzleCaptchaSolutionResponse, PuzzleEvent, RandomProvider } from "@prosopo/types";
2
+ export declare const PROVIDER_URL = "https://provider.one";
3
+ export declare const OTHER_PROVIDER_URL = "https://provider.two";
4
+ export declare const USER_ADDRESS = "user-address";
5
+ export declare const SITE_KEY = "site-key";
6
+ export declare const config: (overrides?: Partial<ProcaptchaClientConfigInput>) => ProcaptchaClientConfigInput;
7
+ export declare const state: (overrides?: Partial<ProcaptchaState>) => ProcaptchaState;
8
+ export type SignRaw = NonNullable<NonNullable<Account["extension"]>["signer"]["signRaw"]>;
9
+ export declare const account: (signRaw?: SignRaw) => Account;
10
+ export declare const accountWithoutExtension: () => Account;
11
+ export declare const randomProvider: (url?: string) => RandomProvider;
12
+ export declare const challengeResponse: (overrides?: Partial<GetPuzzleCaptchaResponse>) => GetPuzzleCaptchaResponse;
13
+ export declare const solutionResponse: (overrides?: Partial<PuzzleCaptchaSolutionResponse>) => PuzzleCaptchaSolutionResponse;
14
+ export declare const puzzleEvents: () => PuzzleEvent[];
15
+ export declare const callbacks: (overrides?: Partial<ProcaptchaCallbacks>) => ProcaptchaCallbacks;
16
+ export declare const signRawMock: import("vitest").Mock<(raw: import("@polkadot/types/types").SignerPayloadRaw) => Promise<import("@polkadot/types/types").SignerResult>>;
17
+ export declare const frictionless: (overrides?: Partial<FrictionlessState>) => FrictionlessState;
18
+ export declare const collector: (points: MouseMovementPoint[]) => NonNullable<FrictionlessState["behaviorCollector1"]>;
19
+ export declare const timerHandle: (id: number) => ReturnType<typeof setTimeout>;
20
+ //# sourceMappingURL=managerHarness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managerHarness.d.ts","sourceRoot":"","sources":["../../src/tests/managerHarness.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACX,OAAO,EACP,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,EAC3B,eAAe,EACf,6BAA6B,EAC7B,WAAW,EACX,cAAc,EACd,MAAM,gBAAgB,CAAC;AASxB,eAAO,MAAM,YAAY,yBAAyB,CAAC;AACnD,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AACzD,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAC3C,eAAO,MAAM,QAAQ,aAAa,CAAC;AAEnC,eAAO,MAAM,MAAM,eACP,OAAO,CAAC,2BAA2B,CAAC,KAC7C,2BAID,CAAC;AAEH,eAAO,MAAM,KAAK,eACN,OAAO,CAAC,eAAe,CAAC,KACjC,eAkBD,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,WAAW,CAChC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CACtD,CAAC;AAMF,eAAO,MAAM,OAAO,aAAc,OAAO,KAAG,OAW1C,CAAC;AAEH,eAAO,MAAM,uBAAuB,QAAO,OAEzC,CAAC;AAEH,eAAO,MAAM,cAAc,SAAS,MAAM,KAAkB,cAG1D,CAAC;AAEH,eAAO,MAAM,iBAAiB,eAClB,OAAO,CAAC,wBAAwB,CAAC,KAC1C,wBAWD,CAAC;AAEH,eAAO,MAAM,gBAAgB,eACjB,OAAO,CAAC,6BAA6B,CAAC,KAC/C,6BAID,CAAC;AAEH,eAAO,MAAM,YAAY,QAAO,WAAW,EAI1C,CAAC;AAEF,eAAO,MAAM,SAAS,eACV,OAAO,CAAC,mBAAmB,CAAC,KACrC,mBAAyC,CAAC;AAO7C,eAAO,MAAM,WAAW,yIAAmB,CAAC;AAE5C,eAAO,MAAM,YAAY,eACb,OAAO,CAAC,iBAAiB,CAAC,KACnC,iBAKD,CAAC;AAOH,eAAO,MAAM,SAAS,WACb,kBAAkB,EAAE,KAC1B,WAAW,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,CAKpD,CAAC;AAOH,eAAO,MAAM,WAAW,OAAQ,MAAM,KAAG,UAAU,CAAC,OAAO,UAAU,CACtB,CAAC"}
@@ -0,0 +1,86 @@
1
+ import { vi } from "vitest";
2
+ export const PROVIDER_URL = "https://provider.one";
3
+ export const OTHER_PROVIDER_URL = "https://provider.two";
4
+ export const USER_ADDRESS = "user-address";
5
+ export const SITE_KEY = "site-key";
6
+ export const config = (overrides = {}) => ({
7
+ account: { address: SITE_KEY },
8
+ defaultEnvironment: "production",
9
+ ...overrides,
10
+ });
11
+ export const state = (overrides = {}) => ({
12
+ isHuman: false,
13
+ index: 0,
14
+ solutions: [],
15
+ captchaApi: undefined,
16
+ challenge: undefined,
17
+ showModal: false,
18
+ loading: false,
19
+ account: undefined,
20
+ dappAccount: undefined,
21
+ submission: undefined,
22
+ timeout: undefined,
23
+ successfullChallengeTimeout: undefined,
24
+ sendData: false,
25
+ attemptCount: 0,
26
+ error: undefined,
27
+ sessionId: undefined,
28
+ ...overrides,
29
+ });
30
+ export const account = (signRaw) => ({
31
+ account: { address: USER_ADDRESS },
32
+ extension: {
33
+ name: "test-extension",
34
+ version: "0.0.0",
35
+ accounts: {
36
+ get: async () => [{ address: USER_ADDRESS }],
37
+ subscribe: () => () => undefined,
38
+ },
39
+ signer: signRaw ? { signRaw } : {},
40
+ },
41
+ });
42
+ export const accountWithoutExtension = () => ({
43
+ account: { address: USER_ADDRESS },
44
+ });
45
+ export const randomProvider = (url = PROVIDER_URL) => ({
46
+ providerAccount: "provider-account",
47
+ provider: { url },
48
+ });
49
+ export const challengeResponse = (overrides = {}) => ({
50
+ challenge: "0x1___0xdeadbeef___1700000000000",
51
+ targetX: 200,
52
+ targetY: 80,
53
+ originX: 20,
54
+ originY: 100,
55
+ tolerance: 10,
56
+ timestamp: "1700000000000",
57
+ signature: { provider: { challenge: "0xprovider-challenge" } },
58
+ status: "ok",
59
+ ...overrides,
60
+ });
61
+ export const solutionResponse = (overrides = {}) => ({
62
+ verified: true,
63
+ status: "ok",
64
+ ...overrides,
65
+ });
66
+ export const puzzleEvents = () => [
67
+ { x: 20, y: 100, t: 0 },
68
+ { x: 120, y: 90, t: 120 },
69
+ { x: 200, y: 80, t: 260 },
70
+ ];
71
+ export const callbacks = (overrides = {}) => ({ ...overrides });
72
+ export const signRawMock = vi.fn();
73
+ export const frictionless = (overrides = {}) => ({
74
+ provider: randomProvider(),
75
+ userAccount: account(signRawMock),
76
+ restart: () => undefined,
77
+ ...overrides,
78
+ });
79
+ export const collector = (points) => ({
80
+ start: () => undefined,
81
+ stop: () => undefined,
82
+ getData: () => points,
83
+ clear: () => undefined,
84
+ });
85
+ export const timerHandle = (id) => id;
86
+ //# sourceMappingURL=managerHarness.js.map