@prosopo/procaptcha-common 2.10.28 → 2.11.1

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/procaptcha-common@2.10.28 build:cjs
2
+ > @prosopo/procaptcha-common@2.11.1 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -47,12 +47,12 @@ rendering chunks...
47
47
  dist/cjs/elements/window.cjs 0.59 kB
48
48
  dist/cjs/elements/form.cjs 0.72 kB
49
49
  dist/cjs/providers.cjs 0.98 kB
50
- dist/cjs/index.cjs 1.45 kB
51
50
  dist/cjs/extensionLoader.cjs 1.48 kB
51
+ dist/cjs/index.cjs 1.49 kB
52
52
  dist/cjs/reactComponents/TestModeBanner.cjs 1.61 kB
53
53
  dist/cjs/reactComponents/Honeypot.cjs 2.19 kB
54
54
  dist/cjs/reactComponents/Reload.cjs 3.19 kB
55
55
  dist/cjs/state/builder.cjs 3.26 kB
56
56
  dist/cjs/callbacks/defaultCallbacks.cjs 4.07 kB
57
57
  dist/cjs/reactComponents/Checkbox.cjs 4.45 kB
58
- ✓ built in 147ms
58
+ ✓ built in 195ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/procaptcha-common@2.10.28 build:tsc
2
+ > @prosopo/procaptcha-common@2.11.1 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 1:01:48 PM - Projects in this build:
5
+ 3:24:58 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -18,35 +18,35 @@
18
18
  * ../account/tsconfig.json
19
19
  * tsconfig.json
20
20
 
21
- 1:01:48 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
21
+ 3:24:58 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
22
22
 
23
- 1:01:48 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
23
+ 3:24:58 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
24
24
 
25
- 1:01:48 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
25
+ 3:24:58 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
26
26
 
27
- 1:01:48 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
27
+ 3:24:58 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
28
28
 
29
- 1:01:48 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
29
+ 3:24:58 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
30
30
 
31
- 1:01:48 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
31
+ 3:24:58 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
32
32
 
33
- 1:01:48 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/objectUtils.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
33
+ 3:24:58 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
34
34
 
35
- 1:01:48 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
35
+ 3:24:58 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
36
36
 
37
- 1:01:48 PM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/index.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
37
+ 3:24:58 PM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/constants.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
38
38
 
39
- 1:01:48 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/sources/webgl.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
39
+ 3:24:58 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
40
40
 
41
- 1:01:48 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
41
+ 3:24:58 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
42
42
 
43
- 1:01:48 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
43
+ 3:24:58 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
44
44
 
45
- 1:01:48 PM - Project '../account/tsconfig.json' is out of date because output file '../account/tsconfig.tsbuildinfo' does not exist
45
+ 3:24:58 PM - Project '../account/tsconfig.json' is out of date because output file '../account/tsconfig.tsbuildinfo' does not exist
46
46
 
47
- 1:01:48 PM - Building project '/home/runner/work/captcha/captcha/packages/account/tsconfig.json'...
47
+ 3:24:58 PM - Building project '/home/runner/work/captcha/captcha/packages/account/tsconfig.json'...
48
48
 
49
- 1:01:52 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
49
+ 3:25:02 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
50
50
 
51
- 1:01:52 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-common/tsconfig.json'...
51
+ 3:25:02 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-common/tsconfig.json'...
52
52
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/procaptcha-common@2.10.28 build
2
+ > @prosopo/procaptcha-common@2.11.1 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/procaptcha-common@2.10.28 build:cross-env
6
+ > @prosopo/procaptcha-common@2.11.1 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -49,12 +49,12 @@ rendering chunks...
49
49
  dist/extensionLoader.js 0.21 kB
50
50
  dist/elements/window.js 0.46 kB
51
51
  dist/elements/form.js 0.58 kB
52
- dist/providers.js 0.83 kB
53
- dist/index.js 0.98 kB
52
+ dist/providers.js 0.82 kB
53
+ dist/index.js 1.01 kB
54
54
  dist/reactComponents/TestModeBanner.js 1.46 kB
55
55
  dist/reactComponents/Honeypot.js 2.06 kB
56
56
  dist/reactComponents/Reload.js 3.01 kB
57
57
  dist/state/builder.js 3.14 kB
58
58
  dist/callbacks/defaultCallbacks.js 3.91 kB
59
59
  dist/reactComponents/Checkbox.js 4.23 kB
60
- ✓ built in 296ms
60
+ ✓ built in 266ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,91 @@
1
1
  # @prosopo/procaptcha-common
2
2
 
3
+ ## 2.11.1
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [6ecc576]
7
+ - Updated dependencies [619dc9f]
8
+ - Updated dependencies [b166037]
9
+ - Updated dependencies [1111ff2]
10
+ - Updated dependencies [6a7b122]
11
+ - @prosopo/widget-skeleton@2.8.4
12
+ - @prosopo/types@4.9.0
13
+ - @prosopo/load-balancer@2.10.1
14
+ - @prosopo/account@2.8.48
15
+
16
+ ## 2.11.0
17
+ ### Minor Changes
18
+
19
+ - 12cd0a6: Replace client-side weighted-random provider selection with static DNS endpoints.
20
+
21
+ - Removed the `providerSelectEntropy` field from `DetectorResult`, `Session`, the
22
+ Mongoose `SessionRecordSchema` (including its standalone index), and every
23
+ call-site that threaded it through frictionless / image / pow / puzzle flows.
24
+ - Removed `FrictionlessManager.hostVerified` and its decision-machine call site
25
+ — there's nothing to verify when the DNS layer picks the host.
26
+ - `getRandomActiveProvider(env)` now returns the per-environment static DNS
27
+ endpoint (`pronode.prosopo.io` family) instead of fetching the provider list
28
+ and weighted-selecting. The entropy parameter is gone.
29
+ - `getProcaptchaRandomActiveProvider` is now a thin re-export so widget packages
30
+ keep importing from `procaptcha-common`.
31
+ - `FrontendProvider.datasetId` is dropped; `CaptchaRequestBody.datasetId` is
32
+ optional. The server falls back to its own most-recently-uploaded dataset
33
+ (`env.datasetId`, populated from `db.getMostRecentDatasetId()` at startup) —
34
+ clients can't pin a dataset under DNS routing because they don't know which
35
+ pronode they'll hit.
36
+ - Removed dead `setProviderLoader` / `prefetchProviders` / `selectWeightedProvider`
37
+ plumbing from `@prosopo/load-balancer`. The server's cacheFile-based loader
38
+ setup in `startProviderApi` goes with them.
39
+ - `getRandomActiveProvider` now hits `/healthz` on the global hostname once per
40
+ page load, reads the responding pronode's identity from the JSON body, and
41
+ pins subsequent captcha calls to that pronode (`https://pronodeN.prosopo.io`)
42
+ so session creation and submission land on the same backend. Falls back to
43
+ the dual-stack global hostname when `/healthz` is unreachable.
44
+ - `/healthz` now returns `{ ok: true, host: <pronode-identity> }` instead of
45
+ `"OK"` to support the above pinning.
46
+ - CORS preflight is now cached for 24h (`maxAge: 86400`) — previously the
47
+ browser refired an OPTIONS preflight before every captcha call because
48
+ the custom `Prosopo-Site-Key` / `Prosopo-User` headers make the request
49
+ non-simple and the default `maxAge` is 5s.
50
+ - 12cd0a6: Add ipv4-only / ipv6-only provider DNS routing via `data-ipv4` / `data-ipv6`.
51
+
52
+ Dapps that need to pin captcha traffic to a single IP stack can now do so:
53
+
54
+ ```html
55
+ <div class="procaptcha" data-sitekey="..." data-ipv4="true"></div>
56
+ ```
57
+
58
+ What happens under the hood:
59
+
60
+ - The widget reads `data-ipv4` / `data-ipv6` (or the matching `ipv4` / `ipv6`
61
+ booleans on `ProcaptchaRenderOptions` / explicit `render(...)`) and threads
62
+ them through `ProcaptchaConfigSchema`.
63
+ - `pickIpMode(config)` resolves them into an `IpMode` (`"ipv4"` / `"ipv6"` /
64
+ `undefined`); `ipv4` wins if both are set.
65
+ - The frictionless / image / pow / puzzle managers pass the `IpMode` into
66
+ `getProcaptchaRandomActiveProvider`, which calls `/healthz` on the matching
67
+ single-stack global hostname (`ipv4.pronode.prosopo.io` or
68
+ `ipv6.pronode.prosopo.io`) and pins subsequent captcha calls to
69
+ `ipv4.pronodeN.prosopo.io` / `ipv6.pronodeN.prosopo.io`. The dual-stack
70
+ cache and the single-stack caches are kept separate.
71
+ - `convertHostedProvider` now accepts an optional `IpMode` and, when set,
72
+ selects the matching `ipv4` / `ipv6` sub-object from the provider-list JSON.
73
+ Top-level `ipv4` / `ipv6` keys are skipped by default so existing dual-stack
74
+ callers keep working.
75
+ - New helpers in `@prosopo/load-balancer`: `IpMode`, `stripIpModeLabel`,
76
+ `getProviderHostname`.
77
+
78
+ Coordinated with the matching `captcha-private` change that publishes the
79
+ `ipv4` / `ipv6` sub-objects to S3.
80
+
81
+ ### Patch Changes
82
+
83
+ - Updated dependencies [12cd0a6]
84
+ - Updated dependencies [12cd0a6]
85
+ - @prosopo/load-balancer@2.10.0
86
+ - @prosopo/types@4.8.0
87
+ - @prosopo/account@2.8.47
88
+
3
89
  ## 2.10.28
4
90
  ### Patch Changes
5
91
 
@@ -11,6 +11,7 @@ const Checkbox = require("./reactComponents/Checkbox.cjs");
11
11
  const Honeypot = require("./reactComponents/Honeypot.cjs");
12
12
  const TestModeBanner = require("./reactComponents/TestModeBanner.cjs");
13
13
  exports.getProcaptchaRandomActiveProvider = providers.getProcaptchaRandomActiveProvider;
14
+ exports.pickIpMode = providers.pickIpMode;
14
15
  exports.providerRetry = providers.providerRetry;
15
16
  exports.buildUpdateState = builder.buildUpdateState;
16
17
  exports.useProcaptcha = builder.useProcaptcha;
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const loadBalancer = require("@prosopo/load-balancer");
4
- const getProcaptchaRandomActiveProvider = async (defaultEnvironment) => {
5
- const randomNumberU8a = window.crypto.getRandomValues(new Uint8Array(10));
6
- const randomNumber = randomNumberU8a.reduce((a, b) => a + b, 0);
7
- return await loadBalancer.getRandomActiveProvider(defaultEnvironment, randomNumber);
4
+ const pickIpMode = (flags) => {
5
+ if (flags?.ipv4) return "ipv4";
6
+ if (flags?.ipv6) return "ipv6";
7
+ return void 0;
8
+ };
9
+ const getProcaptchaRandomActiveProvider = async (defaultEnvironment, ipMode) => {
10
+ return loadBalancer.getRandomActiveProvider(defaultEnvironment, ipMode);
8
11
  };
9
12
  const providerRetry = async (currentFn, retryFn, stateReset, attemptCount, retryMax) => {
10
13
  try {
@@ -23,4 +26,5 @@ const providerRetry = async (currentFn, retryFn, stateReset, attemptCount, retry
23
26
  }
24
27
  };
25
28
  exports.getProcaptchaRandomActiveProvider = getProcaptchaRandomActiveProvider;
29
+ exports.pickIpMode = pickIpMode;
26
30
  exports.providerRetry = providerRetry;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getProcaptchaRandomActiveProvider, providerRetry } from "./providers.js";
1
+ import { getProcaptchaRandomActiveProvider, pickIpMode, providerRetry } from "./providers.js";
2
2
  import { buildUpdateState, useProcaptcha } from "./state/builder.js";
3
3
  import { getDefaultCallbacks, setUserCallbacks } from "./callbacks/defaultCallbacks.js";
4
4
  import { getDefaultEvents } from "./callbacks/defaultEvents.js";
@@ -20,6 +20,7 @@ export {
20
20
  getProcaptchaRandomActiveProvider,
21
21
  getWindowCallback,
22
22
  isSecureBrowserContext,
23
+ pickIpMode,
23
24
  providerRetry,
24
25
  setUserCallbacks,
25
26
  useProcaptcha
@@ -1,4 +1,9 @@
1
- import type { EnvironmentTypes } from "@prosopo/types";
2
- export declare const getProcaptchaRandomActiveProvider: (defaultEnvironment: EnvironmentTypes) => Promise<import("@prosopo/types").RandomProvider>;
1
+ import { type IpMode } from "@prosopo/load-balancer";
2
+ import type { EnvironmentTypes, RandomProvider } from "@prosopo/types";
3
+ export declare const pickIpMode: (flags: {
4
+ ipv4?: boolean;
5
+ ipv6?: boolean;
6
+ } | undefined) => IpMode | undefined;
7
+ export declare const getProcaptchaRandomActiveProvider: (defaultEnvironment: EnvironmentTypes, ipMode?: IpMode) => Promise<RandomProvider>;
3
8
  export declare const providerRetry: (currentFn: () => Promise<void>, retryFn: () => Promise<void>, stateReset: () => void, attemptCount: number, retryMax: number) => Promise<void>;
4
9
  //# sourceMappingURL=providers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,eAAO,MAAM,iCAAiC,uBACzB,gBAAgB,qDAKpC,CAAC;AAEF,eAAO,MAAM,aAAa,cACd,MAAM,OAAO,CAAC,IAAI,CAAC,WACrB,MAAM,OAAO,CAAC,IAAI,CAAC,cAChB,MAAM,IAAI,gBACR,MAAM,YACV,MAAM,kBAkBhB,CAAC"}
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,MAAM,EAA2B,MAAM,wBAAwB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKvE,eAAO,MAAM,UAAU,UACf;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,KACnD,MAAM,GAAG,SAIX,CAAC;AAKF,eAAO,MAAM,iCAAiC,uBACzB,gBAAgB,WAC3B,MAAM,KACb,OAAO,CAAC,cAAc,CAExB,CAAC;AAEF,eAAO,MAAM,aAAa,cACd,MAAM,OAAO,CAAC,IAAI,CAAC,WACrB,MAAM,OAAO,CAAC,IAAI,CAAC,cAChB,MAAM,IAAI,gBACR,MAAM,YACV,MAAM,kBAkBhB,CAAC"}
package/dist/providers.js CHANGED
@@ -1,8 +1,11 @@
1
1
  import { getRandomActiveProvider } from "@prosopo/load-balancer";
2
- const getProcaptchaRandomActiveProvider = async (defaultEnvironment) => {
3
- const randomNumberU8a = window.crypto.getRandomValues(new Uint8Array(10));
4
- const randomNumber = randomNumberU8a.reduce((a, b) => a + b, 0);
5
- return await getRandomActiveProvider(defaultEnvironment, randomNumber);
2
+ const pickIpMode = (flags) => {
3
+ if (flags?.ipv4) return "ipv4";
4
+ if (flags?.ipv6) return "ipv6";
5
+ return void 0;
6
+ };
7
+ const getProcaptchaRandomActiveProvider = async (defaultEnvironment, ipMode) => {
8
+ return getRandomActiveProvider(defaultEnvironment, ipMode);
6
9
  };
7
10
  const providerRetry = async (currentFn, retryFn, stateReset, attemptCount, retryMax) => {
8
11
  try {
@@ -22,5 +25,6 @@ const providerRetry = async (currentFn, retryFn, stateReset, attemptCount, retry
22
25
  };
23
26
  export {
24
27
  getProcaptchaRandomActiveProvider,
28
+ pickIpMode,
25
29
  providerRetry
26
30
  };
@@ -1 +1 @@
1
- {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,MAAM,CAAC,MAAM,iCAAiC,GAAG,KAAK,EACrD,kBAAoC,EACnC,EAAE;IACH,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAChE,OAAO,MAAM,uBAAuB,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EACjC,SAA8B,EAC9B,OAA4B,EAC5B,UAAsB,EACtB,YAAoB,EACpB,QAAgB,EACf,EAAE;IACH,IAAI,CAAC;QACJ,MAAM,SAAS,EAAE,CAAC;IACnB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,KAAK,CACZ,gBAAgB,YAAY,OAAO,QAAQ,qBAAqB,CAChE,CAAC;YACF,OAAO,UAAU,EAAE,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEnB,UAAU,EAAE,CAAC;QAEb,MAAM,OAAO,EAAE,CAAC;IACjB,CAAC;AACF,CAAC,CAAC"}
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAcA,OAAO,EAAe,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAM9E,MAAM,CAAC,MAAM,UAAU,GAAG,CACzB,KAAqD,EAChC,EAAE;IACvB,IAAI,KAAK,EAAE,IAAI;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,KAAK,EAAE,IAAI;QAAE,OAAO,MAAM,CAAC;IAC/B,OAAO,SAAS,CAAC;AAClB,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,iCAAiC,GAAG,KAAK,EACrD,kBAAoC,EACpC,MAAe,EACW,EAAE;IAC5B,OAAO,uBAAuB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EACjC,SAA8B,EAC9B,OAA4B,EAC5B,UAAsB,EACtB,YAAoB,EACpB,QAAgB,EACf,EAAE;IACH,IAAI,CAAC;QACJ,MAAM,SAAS,EAAE,CAAC;IACnB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,KAAK,CACZ,gBAAgB,YAAY,OAAO,QAAQ,qBAAqB,CAChE,CAAC;YACF,OAAO,UAAU,EAAE,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEnB,UAAU,EAAE,CAAC;QAEb,MAAM,OAAO,EAAE,CAAC;IACjB,CAAC;AACF,CAAC,CAAC"}
@@ -1,45 +1,39 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { getProcaptchaRandomActiveProvider, providerRetry, } from "../providers.js";
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { getProcaptchaRandomActiveProvider, pickIpMode, providerRetry, } from "../providers.js";
3
3
  vi.mock("@prosopo/load-balancer", () => ({
4
- getRandomActiveProvider: vi.fn(),
4
+ getRandomActiveProvider: vi.fn(async (env) => ({
5
+ providerAccount: "dns-routed",
6
+ provider: {
7
+ url: env === "production"
8
+ ? "https://pronode.prosopo.io"
9
+ : "http://localhost:9229",
10
+ },
11
+ })),
5
12
  }));
6
13
  describe("providers", () => {
7
14
  describe("getProcaptchaRandomActiveProvider", () => {
8
- let originalGetRandomValues;
9
- beforeEach(() => {
10
- originalGetRandomValues = global.window.crypto.getRandomValues.bind(global.window.crypto);
11
- });
12
- afterEach(() => {
13
- global.window.crypto.getRandomValues = originalGetRandomValues;
14
- });
15
- it("should generate random values and call getRandomActiveProvider", async () => {
16
- const mockRandomValues = new Uint8Array([
17
- 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
18
- ]);
19
- const mockGetRandomValues = vi.fn(() => mockRandomValues);
20
- global.window.crypto.getRandomValues = mockGetRandomValues;
15
+ it("delegates to the load-balancer static-DNS resolver", async () => {
21
16
  const { getRandomActiveProvider } = await import("@prosopo/load-balancer");
22
- vi.mocked(getRandomActiveProvider).mockResolvedValue({
23
- providerUrl: "https://test-provider.com",
24
- });
25
- const result = await getProcaptchaRandomActiveProvider("development");
26
- expect(mockGetRandomValues).toHaveBeenCalledWith(expect.any(Uint8Array));
27
- expect(getRandomActiveProvider).toHaveBeenCalledWith("development", 550);
28
- expect(result).toEqual({ providerUrl: "https://test-provider.com" });
17
+ const result = await getProcaptchaRandomActiveProvider("production");
18
+ expect(getRandomActiveProvider).toHaveBeenCalledWith("production", undefined);
19
+ expect(result.provider.url).toBe("https://pronode.prosopo.io");
29
20
  });
30
- it("should use different random values on each call", async () => {
31
- let callCount = 0;
32
- const mockGetRandomValues = vi.fn((arr) => {
33
- callCount++;
34
- arr.fill(callCount);
35
- return arr;
36
- });
37
- global.window.crypto.getRandomValues = mockGetRandomValues;
21
+ it("forwards the ipMode parameter to the load-balancer resolver", async () => {
38
22
  const { getRandomActiveProvider } = await import("@prosopo/load-balancer");
39
- vi.mocked(getRandomActiveProvider).mockResolvedValue({});
40
- await getProcaptchaRandomActiveProvider("development");
41
- await getProcaptchaRandomActiveProvider("development");
42
- expect(mockGetRandomValues).toHaveBeenCalledTimes(2);
23
+ await getProcaptchaRandomActiveProvider("production", "ipv4");
24
+ expect(getRandomActiveProvider).toHaveBeenCalledWith("production", "ipv4");
25
+ });
26
+ });
27
+ describe("pickIpMode", () => {
28
+ it("picks ipv4 when both flags are set", () => {
29
+ expect(pickIpMode({ ipv4: true, ipv6: true })).toBe("ipv4");
30
+ });
31
+ it("returns undefined when neither flag is set", () => {
32
+ expect(pickIpMode({})).toBeUndefined();
33
+ expect(pickIpMode(undefined)).toBeUndefined();
34
+ });
35
+ it("returns ipv6 when only ipv6 is set", () => {
36
+ expect(pickIpMode({ ipv6: true })).toBe("ipv6");
43
37
  });
44
38
  });
45
39
  describe("providerRetry", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"providers.test.js","sourceRoot":"","sources":["../../src/tests/providers.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"providers.test.js","sourceRoot":"","sources":["../../src/tests/providers.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/procaptcha-common",
3
- "version": "2.10.28",
3
+ "version": "2.11.1",
4
4
  "author": "PROSOPO LIMITED <info@prosopo.io>",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -34,15 +34,15 @@
34
34
  "dependencies": {
35
35
  "@emotion/react": "11.11.1",
36
36
  "@emotion/styled": "11.11.0",
37
- "@prosopo/account": "2.8.46",
38
- "@prosopo/load-balancer": "2.9.21",
39
- "@prosopo/types": "4.7.4",
40
- "@prosopo/widget-skeleton": "2.8.3",
37
+ "@prosopo/account": "2.8.48",
38
+ "@prosopo/load-balancer": "2.10.1",
39
+ "@prosopo/types": "4.9.0",
40
+ "@prosopo/widget-skeleton": "2.8.4",
41
41
  "react": "18.3.1",
42
42
  "react-dom": "18.3.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@prosopo/config": "3.3.2",
45
+ "@prosopo/config": "3.3.4",
46
46
  "@types/jsdom": "21.1.7",
47
47
  "@types/node": "22.10.2",
48
48
  "@types/react": "18.3.1",
package/src/providers.ts CHANGED
@@ -12,15 +12,28 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- import { getRandomActiveProvider } from "@prosopo/load-balancer";
16
- import type { EnvironmentTypes } from "@prosopo/types";
15
+ import { type IpMode, getRandomActiveProvider } from "@prosopo/load-balancer";
16
+ import type { EnvironmentTypes, RandomProvider } from "@prosopo/types";
17
17
 
18
+ // Translate the user-facing ipv4/ipv6 booleans (set via ProcaptchaRenderOptions
19
+ // or data-ipv4/data-ipv6) into the load-balancer's IpMode selector. ipv4 wins
20
+ // if both are set; neither set leaves DNS in dual-stack mode (undefined).
21
+ export const pickIpMode = (
22
+ flags: { ipv4?: boolean; ipv6?: boolean } | undefined,
23
+ ): IpMode | undefined => {
24
+ if (flags?.ipv4) return "ipv4";
25
+ if (flags?.ipv6) return "ipv6";
26
+ return undefined;
27
+ };
28
+
29
+ // Thin wrapper over the load-balancer's static-DNS endpoint resolver. Kept as
30
+ // a separate export so widget packages (procaptcha, procaptcha-pow, …) import
31
+ // from procaptcha-common rather than reaching into load-balancer directly.
18
32
  export const getProcaptchaRandomActiveProvider = async (
19
33
  defaultEnvironment: EnvironmentTypes,
20
- ) => {
21
- const randomNumberU8a = window.crypto.getRandomValues(new Uint8Array(10));
22
- const randomNumber = randomNumberU8a.reduce((a, b) => a + b, 0);
23
- return await getRandomActiveProvider(defaultEnvironment, randomNumber);
34
+ ipMode?: IpMode,
35
+ ): Promise<RandomProvider> => {
36
+ return getRandomActiveProvider(defaultEnvironment, ipMode);
24
37
  };
25
38
 
26
39
  export const providerRetry = async (
@@ -12,77 +12,67 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
15
+ import { describe, expect, it, vi } from "vitest";
16
16
  import {
17
17
  getProcaptchaRandomActiveProvider,
18
+ pickIpMode,
18
19
  providerRetry,
19
20
  } from "../providers.js";
20
21
 
21
- // Mock the load-balancer module
22
22
  vi.mock("@prosopo/load-balancer", () => ({
23
- getRandomActiveProvider: vi.fn(),
23
+ getRandomActiveProvider: vi.fn(async (env: string) => ({
24
+ providerAccount: "dns-routed",
25
+ provider: {
26
+ url:
27
+ env === "production"
28
+ ? "https://pronode.prosopo.io"
29
+ : "http://localhost:9229",
30
+ },
31
+ })),
24
32
  }));
25
33
 
26
34
  describe("providers", () => {
27
35
  describe("getProcaptchaRandomActiveProvider", () => {
28
- // biome-ignore lint/suspicious/noExplicitAny: Store original crypto function
29
- let originalGetRandomValues: any;
30
-
31
- beforeEach(() => {
32
- originalGetRandomValues = global.window.crypto.getRandomValues.bind(
33
- global.window.crypto,
36
+ it("delegates to the load-balancer static-DNS resolver", async () => {
37
+ const { getRandomActiveProvider } = await import(
38
+ "@prosopo/load-balancer"
34
39
  );
35
- });
36
40
 
37
- afterEach(() => {
38
- global.window.crypto.getRandomValues = originalGetRandomValues;
39
- });
41
+ const result = await getProcaptchaRandomActiveProvider("production");
40
42
 
41
- it("should generate random values and call getRandomActiveProvider", async () => {
42
- // Mock window.crypto.getRandomValues
43
- const mockRandomValues = new Uint8Array([
44
- 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
45
- ]);
46
- const mockGetRandomValues = vi.fn(() => mockRandomValues);
47
- // biome-ignore lint/suspicious/noExplicitAny: Mock crypto API
48
- global.window.crypto.getRandomValues = mockGetRandomValues as any;
43
+ expect(getRandomActiveProvider).toHaveBeenCalledWith(
44
+ "production",
45
+ undefined,
46
+ );
47
+ expect(result.provider.url).toBe("https://pronode.prosopo.io");
48
+ });
49
49
 
50
- // Mock the getRandomActiveProvider import
50
+ it("forwards the ipMode parameter to the load-balancer resolver", async () => {
51
51
  const { getRandomActiveProvider } = await import(
52
52
  "@prosopo/load-balancer"
53
53
  );
54
- vi.mocked(getRandomActiveProvider).mockResolvedValue({
55
- providerUrl: "https://test-provider.com",
56
- // biome-ignore lint/suspicious/noExplicitAny: Mock return type
57
- } as any);
58
54
 
59
- const result = await getProcaptchaRandomActiveProvider("development");
55
+ await getProcaptchaRandomActiveProvider("production", "ipv4");
60
56
 
61
- expect(mockGetRandomValues).toHaveBeenCalledWith(expect.any(Uint8Array));
62
- expect(getRandomActiveProvider).toHaveBeenCalledWith("development", 550); // sum of mockRandomValues
63
- expect(result).toEqual({ providerUrl: "https://test-provider.com" });
57
+ expect(getRandomActiveProvider).toHaveBeenCalledWith(
58
+ "production",
59
+ "ipv4",
60
+ );
64
61
  });
62
+ });
65
63
 
66
- it("should use different random values on each call", async () => {
67
- let callCount = 0;
68
- const mockGetRandomValues = vi.fn((arr: Uint8Array) => {
69
- callCount++;
70
- arr.fill(callCount);
71
- return arr;
72
- });
73
- // biome-ignore lint/suspicious/noExplicitAny: Mock crypto API
74
- global.window.crypto.getRandomValues = mockGetRandomValues as any;
75
-
76
- const { getRandomActiveProvider } = await import(
77
- "@prosopo/load-balancer"
78
- );
79
- // biome-ignore lint/suspicious/noExplicitAny: Mock return type
80
- vi.mocked(getRandomActiveProvider).mockResolvedValue({} as any);
64
+ describe("pickIpMode", () => {
65
+ it("picks ipv4 when both flags are set", () => {
66
+ expect(pickIpMode({ ipv4: true, ipv6: true })).toBe("ipv4");
67
+ });
81
68
 
82
- await getProcaptchaRandomActiveProvider("development");
83
- await getProcaptchaRandomActiveProvider("development");
69
+ it("returns undefined when neither flag is set", () => {
70
+ expect(pickIpMode({})).toBeUndefined();
71
+ expect(pickIpMode(undefined)).toBeUndefined();
72
+ });
84
73
 
85
- expect(mockGetRandomValues).toHaveBeenCalledTimes(2);
74
+ it("returns ipv6 when only ipv6 is set", () => {
75
+ expect(pickIpMode({ ipv6: true })).toBe("ipv6");
86
76
  });
87
77
  });
88
78