@prosopo/api 3.5.20 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,524 @@
1
+ import { AdminApiPaths, ApiParams, CaptchaType, ClientApiPaths, DecisionMachineKind, DecisionMachineLanguage, DecisionMachineRuntime, DecisionMachineScope, ModeEnum, PublicApiPaths, Tier, } from "@prosopo/types";
2
+ import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
3
+ import { HttpError } from "../api/HttpError.js";
4
+ import ProviderApi, { VERIFY_FORWARDED_HEADER } from "../api/ProviderApi.js";
5
+ import { BASE_URL, CHALLENGE, SITE_KEY, USER, stubFetch, } from "./apiHarness.js";
6
+ let fetchStub;
7
+ const api = () => new ProviderApi(BASE_URL, SITE_KEY);
8
+ const randomProvider = {
9
+ providerAccount: "5provider",
10
+ provider: {
11
+ url: BASE_URL,
12
+ datasetId: "0xdataset",
13
+ datasetIdContent: "0xcontent",
14
+ },
15
+ };
16
+ const powChallenge = {
17
+ status: "ok",
18
+ [ApiParams.challenge]: CHALLENGE,
19
+ [ApiParams.difficulty]: 4,
20
+ [ApiParams.timestamp]: "1753900000000",
21
+ [ApiParams.signature]: {
22
+ [ApiParams.provider]: { [ApiParams.challenge]: "0xproviderchallengesig" },
23
+ },
24
+ };
25
+ const puzzleChallenge = {
26
+ status: "ok",
27
+ [ApiParams.challenge]: CHALLENGE,
28
+ [ApiParams.targetX]: 10,
29
+ [ApiParams.targetY]: 20,
30
+ [ApiParams.originX]: 1,
31
+ [ApiParams.originY]: 2,
32
+ [ApiParams.tolerance]: 5,
33
+ [ApiParams.timestamp]: "1753900000000",
34
+ [ApiParams.signature]: {
35
+ [ApiParams.provider]: { [ApiParams.challenge]: "0xproviderchallengesig" },
36
+ },
37
+ };
38
+ const clientMetaData = {
39
+ widgetHeight: 1,
40
+ widgetWidth: 2,
41
+ };
42
+ const body = () => fetchStub.last().body;
43
+ beforeEach(() => {
44
+ fetchStub = stubFetch();
45
+ vi.spyOn(console, "error").mockImplementation(() => undefined);
46
+ });
47
+ afterEach(() => {
48
+ fetchStub.restore();
49
+ vi.restoreAllMocks();
50
+ });
51
+ describe("identifying headers", () => {
52
+ test("every client call names the site key, so the provider can scope it", async () => {
53
+ await api().getCaptchaChallenge(USER, randomProvider);
54
+ expect(fetchStub.last().headers["Prosopo-Site-Key"]).toBe(SITE_KEY);
55
+ expect(fetchStub.last().headers["Prosopo-User"]).toBe(USER);
56
+ });
57
+ test("calls with no user still carry the site key", async () => {
58
+ await api().submitUserEvents({ events: [] }, "s");
59
+ expect(fetchStub.last().headers["Prosopo-Site-Key"]).toBe(SITE_KEY);
60
+ expect(fetchStub.last().headers["Prosopo-User"]).toBeUndefined();
61
+ });
62
+ });
63
+ describe("getCaptchaChallenge", () => {
64
+ test("posts the site key and user to the image challenge path", async () => {
65
+ await api().getCaptchaChallenge(USER, randomProvider);
66
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.GetImageCaptchaChallenge}`);
67
+ expect(body()).toEqual({
68
+ [ApiParams.dapp]: SITE_KEY,
69
+ [ApiParams.user]: USER,
70
+ });
71
+ });
72
+ test("omits the optional fields when they are absent", async () => {
73
+ await api().getCaptchaChallenge(USER, randomProvider, undefined, undefined);
74
+ expect(body()[ApiParams.sessionId]).toBeUndefined();
75
+ expect(body()[ApiParams.simdReadings]).toBeUndefined();
76
+ });
77
+ test("includes the session id and simd readings when given", async () => {
78
+ await api().getCaptchaChallenge(USER, randomProvider, "session", "readings");
79
+ expect(body()[ApiParams.sessionId]).toBe("session");
80
+ expect(body()[ApiParams.simdReadings]).toBe("readings");
81
+ });
82
+ test("an empty session id is treated as absent", async () => {
83
+ await api().getCaptchaChallenge(USER, randomProvider, "", "");
84
+ expect(body()[ApiParams.sessionId]).toBeUndefined();
85
+ expect(body()[ApiParams.simdReadings]).toBeUndefined();
86
+ });
87
+ test("returns the provider's body", async () => {
88
+ fetchStub.respond({ captchas: [] });
89
+ await expect(api().getCaptchaChallenge(USER, randomProvider)).resolves.toEqual({ captchas: [] });
90
+ });
91
+ test("propagates a transport failure", async () => {
92
+ fetchStub.fail(new Error("offline"));
93
+ await expect(api().getCaptchaChallenge(USER, randomProvider)).rejects.toThrow("offline");
94
+ });
95
+ });
96
+ describe("in-flight de-duplication of challenge fetches", () => {
97
+ test("a second call with the same session id joins the first request", async () => {
98
+ const deferred = fetchStub.defer();
99
+ const client = api();
100
+ const first = client.getPowCaptchaChallenge(USER, SITE_KEY, "session");
101
+ const second = client.getPowCaptchaChallenge(USER, SITE_KEY, "session");
102
+ expect(fetchStub.requests).toHaveLength(1);
103
+ deferred.resolve(powChallenge);
104
+ expect(await first).toEqual(await second);
105
+ });
106
+ test("different session ids are separate requests", async () => {
107
+ const client = api();
108
+ await Promise.all([
109
+ client.getPowCaptchaChallenge(USER, SITE_KEY, "a"),
110
+ client.getPowCaptchaChallenge(USER, SITE_KEY, "b"),
111
+ ]);
112
+ expect(fetchStub.requests).toHaveLength(2);
113
+ });
114
+ test("the same session id on a different path is a separate request", async () => {
115
+ const client = api();
116
+ await Promise.all([
117
+ client.getPowCaptchaChallenge(USER, SITE_KEY, "session"),
118
+ client.getPuzzleCaptchaChallenge(USER, SITE_KEY, "session"),
119
+ ]);
120
+ expect(fetchStub.requests).toHaveLength(2);
121
+ });
122
+ test("calls without a session id are never deduped", async () => {
123
+ const client = api();
124
+ await Promise.all([
125
+ client.getPowCaptchaChallenge(USER, SITE_KEY),
126
+ client.getPowCaptchaChallenge(USER, SITE_KEY),
127
+ ]);
128
+ expect(fetchStub.requests).toHaveLength(2);
129
+ });
130
+ test("a retry after the first call settles starts a fresh request", async () => {
131
+ const client = api();
132
+ await client.getPowCaptchaChallenge(USER, SITE_KEY, "session");
133
+ await client.getPowCaptchaChallenge(USER, SITE_KEY, "session");
134
+ expect(fetchStub.requests).toHaveLength(2);
135
+ });
136
+ test("a failed call is dropped from the in-flight map, so a retry can proceed", async () => {
137
+ const client = api();
138
+ fetchStub.fail(new Error("offline"));
139
+ await expect(client.getPowCaptchaChallenge(USER, SITE_KEY, "session")).rejects.toThrow("offline");
140
+ fetchStub.respond(powChallenge);
141
+ await expect(client.getPowCaptchaChallenge(USER, SITE_KEY, "session")).resolves.toEqual(powChallenge);
142
+ expect(fetchStub.requests).toHaveLength(2);
143
+ });
144
+ test("both joined callers see the same failure", async () => {
145
+ const deferred = fetchStub.defer();
146
+ const client = api();
147
+ const first = client.getPowCaptchaChallenge(USER, SITE_KEY, "session");
148
+ const second = client.getPowCaptchaChallenge(USER, SITE_KEY, "session");
149
+ deferred.reject(new Error("offline"));
150
+ await expect(first).rejects.toThrow("offline");
151
+ await expect(second).rejects.toThrow("offline");
152
+ });
153
+ test("two clients do not share an in-flight map", async () => {
154
+ const first = api().getPowCaptchaChallenge(USER, SITE_KEY, "session");
155
+ const second = api().getPowCaptchaChallenge(USER, SITE_KEY, "session");
156
+ expect(fetchStub.requests).toHaveLength(2);
157
+ await Promise.all([first, second]);
158
+ });
159
+ test("image challenges dedupe on their own path too", async () => {
160
+ fetchStub.defer();
161
+ const client = api();
162
+ void client.getCaptchaChallenge(USER, randomProvider, "session");
163
+ void client.getCaptchaChallenge(USER, randomProvider, "session");
164
+ expect(fetchStub.requests).toHaveLength(1);
165
+ });
166
+ });
167
+ describe("submitCaptchaSolution", () => {
168
+ const submit = (behavioralData, simdReadings, meta) => api().submitCaptchaSolution([], "0xrequesthash", USER, "1753900000000", "0xproviderhashsig", "0xusertimestampsig", behavioralData, simdReadings, meta);
169
+ test("posts the solution with both signatures", async () => {
170
+ await submit();
171
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.SubmitImageCaptchaSolution}`);
172
+ expect(body()).toEqual({
173
+ [ApiParams.user]: USER,
174
+ [ApiParams.dapp]: SITE_KEY,
175
+ [ApiParams.captchas]: [],
176
+ [ApiParams.requestHash]: "0xrequesthash",
177
+ [ApiParams.timestamp]: "1753900000000",
178
+ [ApiParams.signature]: {
179
+ [ApiParams.user]: { [ApiParams.timestamp]: "0xusertimestampsig" },
180
+ [ApiParams.provider]: { [ApiParams.requestHash]: "0xproviderhashsig" },
181
+ },
182
+ });
183
+ });
184
+ test("an empty solution list is still submitted, not short-circuited", async () => {
185
+ await submit();
186
+ expect(body()[ApiParams.captchas]).toEqual([]);
187
+ });
188
+ test("attaches the optional telemetry when present", async () => {
189
+ await submit("behaviour", "readings", clientMetaData);
190
+ expect(body()[ApiParams.behavioralData]).toBe("behaviour");
191
+ expect(body()[ApiParams.simdReadings]).toBe("readings");
192
+ expect(body()[ApiParams.clientMetaData]).toEqual(clientMetaData);
193
+ });
194
+ test("empty telemetry strings are omitted rather than sent blank", async () => {
195
+ await submit("", "");
196
+ expect(ApiParams.behavioralData in body()).toBe(false);
197
+ expect(ApiParams.simdReadings in body()).toBe(false);
198
+ });
199
+ });
200
+ describe("verifyDappUser", () => {
201
+ test("posts the token, signature and ip", async () => {
202
+ await api().verifyDappUser("token", "0xsig", USER, undefined, "1.2.3.4");
203
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.VerifyImageCaptchaSolutionDapp}`);
204
+ expect(body()).toEqual({
205
+ [ApiParams.token]: "token",
206
+ [ApiParams.dappSignature]: "0xsig",
207
+ [ApiParams.ip]: "1.2.3.4",
208
+ });
209
+ });
210
+ test("includes maxVerifiedTime and email when given", async () => {
211
+ await api().verifyDappUser("token", "0xsig", USER, 60_000, "1.2.3.4", "user@example.com");
212
+ expect(body()[ApiParams.maxVerifiedTime]).toBe(60_000);
213
+ expect(body()[ApiParams.email]).toBe("user@example.com");
214
+ });
215
+ test("a zero maxVerifiedTime is dropped, so the provider applies its default", async () => {
216
+ await api().verifyDappUser("token", "0xsig", USER, 0);
217
+ expect(ApiParams.maxVerifiedTime in body()).toBe(false);
218
+ });
219
+ test("an omitted ip is sent as undefined rather than a placeholder", async () => {
220
+ await api().verifyDappUser("token", "0xsig", USER);
221
+ expect(ApiParams.ip in body()).toBe(false);
222
+ });
223
+ });
224
+ describe("pow challenge and solution", () => {
225
+ test("requests a challenge for the user and site key", async () => {
226
+ await api().getPowCaptchaChallenge(USER, SITE_KEY);
227
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.GetPowCaptchaChallenge}`);
228
+ expect(body()).toEqual({
229
+ [ApiParams.user]: USER,
230
+ [ApiParams.dapp]: SITE_KEY,
231
+ });
232
+ });
233
+ test("submits the nonce with the provider's challenge signature", async () => {
234
+ await api().submitPowCaptchaSolution(powChallenge, USER, SITE_KEY, 42, "0xusertimestampsig");
235
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.SubmitPowCaptchaSolution}`);
236
+ expect(body()).toMatchObject({
237
+ [ApiParams.challenge]: CHALLENGE,
238
+ [ApiParams.difficulty]: 4,
239
+ [ApiParams.nonce]: 42,
240
+ [ApiParams.user]: USER,
241
+ [ApiParams.dapp]: SITE_KEY,
242
+ [ApiParams.signature]: {
243
+ [ApiParams.provider]: {
244
+ [ApiParams.challenge]: "0xproviderchallengesig",
245
+ },
246
+ [ApiParams.user]: { [ApiParams.timestamp]: "0xusertimestampsig" },
247
+ },
248
+ });
249
+ });
250
+ test("passes simd readings on the challenge request when present", async () => {
251
+ await api().getPowCaptchaChallenge(USER, SITE_KEY, undefined, "readings");
252
+ expect(body()[ApiParams.simdReadings]).toBe("readings");
253
+ });
254
+ test("a nonce of zero is submitted, not treated as missing", async () => {
255
+ await api().submitPowCaptchaSolution(powChallenge, USER, SITE_KEY, 0, "s");
256
+ expect(body()[ApiParams.nonce]).toBe(0);
257
+ });
258
+ test("attaches the optional proof fields when present", async () => {
259
+ await api().submitPowCaptchaSolution(powChallenge, USER, SITE_KEY, 1, "s", "behaviour", "salt", "readings", clientMetaData, "proof");
260
+ expect(body()).toMatchObject({
261
+ [ApiParams.behavioralData]: "behaviour",
262
+ [ApiParams.salt]: "salt",
263
+ [ApiParams.simdReadings]: "readings",
264
+ [ApiParams.fingerprintProof]: "proof",
265
+ });
266
+ });
267
+ test("the schema strips anything it does not declare", async () => {
268
+ await api().submitPowCaptchaSolution(powChallenge, USER, SITE_KEY, 1, "s");
269
+ expect(ApiParams.timestamp in body()).toBe(false);
270
+ });
271
+ test("a malformed challenge is rejected before any request is made", async () => {
272
+ const bad = {
273
+ ...powChallenge,
274
+ [ApiParams.challenge]: "not-a-challenge",
275
+ };
276
+ expect(() => api().submitPowCaptchaSolution(bad, USER, SITE_KEY, 1, "s")).toThrow();
277
+ expect(fetchStub.requests).toHaveLength(0);
278
+ });
279
+ });
280
+ describe("puzzle challenge and solution", () => {
281
+ test("requests a puzzle challenge", async () => {
282
+ await api().getPuzzleCaptchaChallenge(USER, SITE_KEY, "session", "readings");
283
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.GetPuzzleCaptchaChallenge}`);
284
+ expect(body()).toEqual({
285
+ [ApiParams.user]: USER,
286
+ [ApiParams.dapp]: SITE_KEY,
287
+ [ApiParams.sessionId]: "session",
288
+ [ApiParams.simdReadings]: "readings",
289
+ });
290
+ });
291
+ test("submits the final position and the drag trail", async () => {
292
+ await api().submitPuzzleCaptchaSolution(puzzleChallenge, USER, SITE_KEY, 11, 22, [{ x: 1, y: 2, t: 3 }], "0xusertimestampsig");
293
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.SubmitPuzzleCaptchaSolution}`);
294
+ expect(body()).toMatchObject({
295
+ [ApiParams.finalX]: 11,
296
+ [ApiParams.finalY]: 22,
297
+ [ApiParams.puzzleEvents]: [{ x: 1, y: 2, t: 3 }],
298
+ });
299
+ });
300
+ test("an empty event trail is submitted, and the provider decides", async () => {
301
+ await api().submitPuzzleCaptchaSolution(puzzleChallenge, USER, SITE_KEY, 0, 0, [], "s");
302
+ expect(body()[ApiParams.puzzleEvents]).toEqual([]);
303
+ });
304
+ test("attaches the optional puzzle telemetry when present", async () => {
305
+ await api().submitPuzzleCaptchaSolution(puzzleChallenge, USER, SITE_KEY, 1, 2, [], "s", "behaviour", "salt", "readings", clientMetaData);
306
+ expect(body()).toMatchObject({
307
+ [ApiParams.behavioralData]: "behaviour",
308
+ [ApiParams.salt]: "salt",
309
+ [ApiParams.simdReadings]: "readings",
310
+ });
311
+ expect(body()[ApiParams.clientMetaData]).toBeDefined();
312
+ });
313
+ test("verifies a puzzle token, with the email only when supplied", async () => {
314
+ await api().submitPuzzleCaptchaVerify("token", "0xsig", USER, "1.2.3.4");
315
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.VerifyPuzzleCaptchaSolution}`);
316
+ expect(ApiParams.email in body()).toBe(false);
317
+ await api().submitPuzzleCaptchaVerify("token", "0xsig", USER, "1.2.3.4", "user@example.com");
318
+ expect(body()[ApiParams.email]).toBe("user@example.com");
319
+ });
320
+ });
321
+ describe("getFrictionlessCaptcha", () => {
322
+ const frictionlessBody = { status: "ok", [ApiParams.captchaType]: "pow" };
323
+ test("posts the token and head hash", async () => {
324
+ fetchStub.respond(frictionlessBody);
325
+ await api().getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER);
326
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.GetFrictionlessCaptchaChallenge}`);
327
+ expect(body()).toEqual({
328
+ [ApiParams.token]: "token",
329
+ [ApiParams.headHash]: "0xhead",
330
+ [ApiParams.dapp]: SITE_KEY,
331
+ [ApiParams.user]: USER,
332
+ });
333
+ });
334
+ test("includes the optional context when supplied", async () => {
335
+ fetchStub.respond(frictionlessBody);
336
+ await api().getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER, ModeEnum.invisible, "readings", undefined, undefined, "https://site.example/page", "https://iframe.example");
337
+ expect(body()).toMatchObject({
338
+ [ApiParams.mode]: ModeEnum.invisible,
339
+ [ApiParams.simdReadings]: "readings",
340
+ [ApiParams.currentUrl]: "https://site.example/page",
341
+ [ApiParams.iframeUrl]: "https://iframe.example",
342
+ });
343
+ });
344
+ test("moves the honeypot from the meta header onto the response", async () => {
345
+ fetchStub.respond(frictionlessBody, {
346
+ status: 200,
347
+ headers: {
348
+ "content-type": "application/json",
349
+ "x-prosopo-meta": "encoded-honeypot",
350
+ },
351
+ });
352
+ const response = await api().getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER);
353
+ expect(response[ApiParams.hp]).toBe("encoded-honeypot");
354
+ });
355
+ test("leaves the body untouched when there is no meta header", async () => {
356
+ fetchStub.respond(frictionlessBody);
357
+ const response = await api().getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER);
358
+ expect(ApiParams.hp in response).toBe(false);
359
+ });
360
+ test("an empty meta header is treated as absent", async () => {
361
+ fetchStub.respond(frictionlessBody, {
362
+ status: 200,
363
+ headers: { "content-type": "application/json", "x-prosopo-meta": "" },
364
+ });
365
+ const response = await api().getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER);
366
+ expect(response[ApiParams.hp]).toBeUndefined();
367
+ });
368
+ test("is not deduped: a frictionless call always reaches the provider", async () => {
369
+ const client = api();
370
+ fetchStub.respond(frictionlessBody);
371
+ await Promise.all([
372
+ client.getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER),
373
+ client.getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER),
374
+ ]);
375
+ expect(fetchStub.requests).toHaveLength(2);
376
+ });
377
+ test("propagates a transport failure", async () => {
378
+ fetchStub.respond("nope", { status: 500, headers: {} });
379
+ await expect(api().getFrictionlessCaptcha("token", "0xhead", SITE_KEY, USER)).rejects.toBeInstanceOf(HttpError);
380
+ });
381
+ });
382
+ describe("status and details", () => {
383
+ test("reads the provider status", async () => {
384
+ fetchStub.respond({ status: "ok" });
385
+ await api().getProviderStatus();
386
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.GetProviderStatus}`);
387
+ expect(fetchStub.last().init?.method).toBeUndefined();
388
+ });
389
+ test("reads the public provider details", async () => {
390
+ await api().getProviderDetails();
391
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${PublicApiPaths.GetProviderDetails}`);
392
+ });
393
+ test("submits user events", async () => {
394
+ const events = { events: [] };
395
+ await api().submitUserEvents(events, "0xstring");
396
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.SubmitUserEvents}`);
397
+ expect(body()).toEqual({ events, string: "0xstring" });
398
+ });
399
+ });
400
+ describe("forwardVerify", () => {
401
+ test("marks the request as forwarded so the receiver does not forward again", async () => {
402
+ await api().forwardVerify(ClientApiPaths.VerifyPowCaptchaSolution, { [ApiParams.token]: "token" }, USER);
403
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.VerifyPowCaptchaSolution}`);
404
+ expect(fetchStub.last().headers[VERIFY_FORWARDED_HEADER]).toBe("true");
405
+ });
406
+ test("the marker header is lowercase, to match express's normalised keys", () => {
407
+ expect(VERIFY_FORWARDED_HEADER).toBe(VERIFY_FORWARDED_HEADER.toLowerCase());
408
+ });
409
+ test("forwards the body verbatim", async () => {
410
+ const forwarded = { [ApiParams.token]: "token", extra: "kept" };
411
+ await api().forwardVerify(ClientApiPaths.VerifyImageCaptchaSolutionDapp, forwarded, USER);
412
+ expect(body()).toEqual(forwarded);
413
+ });
414
+ });
415
+ describe("submitPowCaptchaVerify", () => {
416
+ test("posts the token and signature", async () => {
417
+ await api().submitPowCaptchaVerify("token", "0xsig", USER, "1.2.3.4");
418
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${ClientApiPaths.VerifyPowCaptchaSolution}`);
419
+ expect(body()).toEqual({
420
+ [ApiParams.token]: "token",
421
+ [ApiParams.dappSignature]: "0xsig",
422
+ [ApiParams.ip]: "1.2.3.4",
423
+ });
424
+ });
425
+ test("adds the email only when one is supplied", async () => {
426
+ await api().submitPowCaptchaVerify("token", "0xsig", USER);
427
+ expect(ApiParams.email in body()).toBe(false);
428
+ await api().submitPowCaptchaVerify("token", "0xsig", USER, undefined, "user@example.com");
429
+ expect(body()[ApiParams.email]).toBe("user@example.com");
430
+ });
431
+ });
432
+ describe("the admin endpoints", () => {
433
+ const JWT = "jwt-token";
434
+ const settings = {
435
+ captchaType: CaptchaType.pow,
436
+ domains: ["example.com"],
437
+ frictionlessThreshold: 0.5,
438
+ powDifficulty: 4,
439
+ };
440
+ const auth = () => fetchStub.last().headers;
441
+ test("every admin call is bearer-authorised and site-key scoped", async () => {
442
+ await api().registerSiteKey(SITE_KEY, Tier.Free, settings, JWT);
443
+ expect(auth().Authorization).toBe(`Bearer ${JWT}`);
444
+ expect(auth()["Prosopo-Site-Key"]).toBe(SITE_KEY);
445
+ });
446
+ test("registers one site key", async () => {
447
+ await api().registerSiteKey(SITE_KEY, Tier.Free, settings, JWT);
448
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.SiteKeyRegister}`);
449
+ expect(body()).toEqual({ siteKey: SITE_KEY, tier: Tier.Free, settings });
450
+ });
451
+ test("registers a batch of site keys verbatim", async () => {
452
+ const batch = [{ siteKey: SITE_KEY, tier: Tier.Free, settings }];
453
+ await api().registerSiteKeys(batch, JWT);
454
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.SiteKeysRegister}`);
455
+ expect(body()).toEqual(batch);
456
+ });
457
+ test("removes one site key", async () => {
458
+ await api().removeSiteKey(SITE_KEY, JWT);
459
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.SiteKeyRemove}`);
460
+ expect(body()).toEqual({ siteKey: SITE_KEY });
461
+ });
462
+ test("removes a batch of site keys", async () => {
463
+ await api().removeSiteKeys([{ siteKey: SITE_KEY }], JWT);
464
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.SiteKeysRemove}`);
465
+ expect(body()).toEqual([{ siteKey: SITE_KEY }]);
466
+ });
467
+ test("an invalid removal batch never leaves the client", async () => {
468
+ expect(() => api().removeSiteKeys([{ siteKey: 1 }], JWT)).toThrow();
469
+ expect(fetchStub.requests).toHaveLength(0);
470
+ });
471
+ test("updates a decision machine with its full descriptor", async () => {
472
+ await api().updateDecisionMachine(DecisionMachineScope.Dapp, DecisionMachineRuntime.Node, "export default () => true", JWT, SITE_KEY, DecisionMachineLanguage.JavaScript, "machine", "1.0.0", CaptchaType.pow, DecisionMachineKind.Decision);
473
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.UpdateDecisionMachine}`);
474
+ expect(body()).toMatchObject({
475
+ [ApiParams.decisionMachineScope]: DecisionMachineScope.Dapp,
476
+ [ApiParams.decisionMachineRuntime]: DecisionMachineRuntime.Node,
477
+ [ApiParams.decisionMachineSource]: "export default () => true",
478
+ [ApiParams.dapp]: SITE_KEY,
479
+ });
480
+ });
481
+ test("reads all decision machines with an empty body", async () => {
482
+ await api().getAllDecisionMachines(JWT);
483
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.GetAllDecisionMachines}`);
484
+ expect(body()).toEqual({});
485
+ });
486
+ test("reads one decision machine by id", async () => {
487
+ await api().getDecisionMachine("machine-id", JWT);
488
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.GetDecisionMachine}`);
489
+ expect(body()).toEqual({ id: "machine-id" });
490
+ });
491
+ test("removes one decision machine by id", async () => {
492
+ await api().removeDecisionMachine("machine-id", JWT);
493
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.RemoveDecisionMachine}`);
494
+ expect(body()).toEqual({ id: "machine-id" });
495
+ });
496
+ test("removes all decision machines", async () => {
497
+ await api().removeAllDecisionMachines(JWT);
498
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.RemoveAllDecisionMachines}`);
499
+ expect(body()).toEqual({});
500
+ });
501
+ test("clears counters, optionally for a single site key", async () => {
502
+ await api().clearAllCounters(JWT);
503
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.ClearAllCounters}`);
504
+ await api().clearAllCounters(JWT, SITE_KEY);
505
+ expect(body()).toMatchObject({ [ApiParams.dapp]: SITE_KEY });
506
+ });
507
+ test("toggles maintenance mode with a signed timestamp instead of a JWT", async () => {
508
+ await api().toggleMaintenanceMode(true, "1753900000000", "0xsig");
509
+ expect(fetchStub.last().url).toBe(`${BASE_URL}${AdminApiPaths.ToggleMaintenanceMode}`);
510
+ expect(body()).toEqual({ enabled: true });
511
+ expect(fetchStub.last().headers.timestamp).toBe("1753900000000");
512
+ expect(fetchStub.last().headers.signature).toBe("0xsig");
513
+ expect(fetchStub.last().headers.Authorization).toBeUndefined();
514
+ });
515
+ test("disabling maintenance mode is sent as false, not omitted", async () => {
516
+ await api().toggleMaintenanceMode(false, "1753900000000", "0xsig");
517
+ expect(body()).toEqual({ enabled: false });
518
+ });
519
+ test("an admin failure surfaces as an HttpError", async () => {
520
+ fetchStub.respond("forbidden", { status: 403, headers: {} });
521
+ await expect(api().getAllDecisionMachines(JWT)).rejects.toBeInstanceOf(HttpError);
522
+ });
523
+ });
524
+ //# sourceMappingURL=providerApi.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerApi.unit.test.js","sourceRoot":"","sources":["../../src/tests/providerApi.unit.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/api",
3
- "version": "3.5.20",
3
+ "version": "4.0.0",
4
4
  "description": "Wrapper for the provider API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,7 +22,10 @@
22
22
  "build:cross-env": "vite build --config vite.esm.config.ts",
23
23
  "build:tsc": "tsc --build --verbose",
24
24
  "build:cjs": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV",
25
- "typecheck": "tsc --project tsconfig.types.json"
25
+ "typecheck": "tsc --project tsconfig.types.json",
26
+ "test": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --config ./vite.test.config.ts",
27
+ "test:watch": "NODE_ENV=${NODE_ENV:-test}; npx vitest watch --config ./vite.test.config.ts",
28
+ "test:coverage": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --coverage --config ./vite.test.config.ts"
26
29
  },
27
30
  "repository": {
28
31
  "type": "git",
@@ -36,10 +39,10 @@
36
39
  },
37
40
  "homepage": "https://github.com/prosopo/captcha#readme",
38
41
  "dependencies": {
39
- "@prosopo/types": "4.10.0"
42
+ "@prosopo/types": "5.0.0"
40
43
  },
41
44
  "devDependencies": {
42
- "@prosopo/config": "3.3.5",
45
+ "@prosopo/config": "3.3.6",
43
46
  "@types/node": "22.10.2",
44
47
  "@vitest/coverage-v8": "4.1.10",
45
48
  "concurrently": "9.0.1",
@@ -0,0 +1,19 @@
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 { ViteTestConfig } from "@prosopo/config";
16
+
17
+ process.env.NODE_ENV = "test";
18
+
19
+ export default ViteTestConfig();