@prosopo/procaptcha-bundle 4.1.44 → 4.1.46
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 +3 -3
- package/.turbo/turbo-build$colon$tsc.log +26 -26
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +32 -0
- package/dist/cjs/index.cjs +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -1
- package/dist/tests/detectorPrefetch.unit.test.d.ts +2 -0
- package/dist/tests/detectorPrefetch.unit.test.d.ts.map +1 -0
- package/dist/tests/detectorPrefetch.unit.test.js +42 -0
- package/dist/tests/detectorPrefetch.unit.test.js.map +1 -0
- package/package.json +7 -7
- package/src/index.ts +42 -1
- package/src/tests/detectorPrefetch.unit.test.ts +91 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/procaptcha-bundle@4.1.
|
|
2
|
+
> @prosopo/procaptcha-bundle@4.1.46 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
@@ -69,8 +69,8 @@ dist/cjs/_virtual/_rolldown/runtime.cjs 1.00 kB │ gzip: 0.50 kB
|
|
|
69
69
|
dist/cjs/util/language.cjs 1.08 kB │ gzip: 0.45 kB
|
|
70
70
|
dist/cjs/util/captcha/captchaRenderer.cjs 2.26 kB │ gzip: 0.78 kB
|
|
71
71
|
dist/cjs/util/widgetFactory.cjs 2.73 kB │ gzip: 0.89 kB
|
|
72
|
-
dist/cjs/index.cjs
|
|
72
|
+
dist/cjs/index.cjs 6.42 kB │ gzip: 2.14 kB
|
|
73
73
|
|
|
74
74
|
[33m[33m[MIXED_EXPORTS] [0mEntry module "src/index.ts" is using named (including "default", "execute", "render", "reset") and default exports together. Consumers of your bundle will have to use `..default` to access the default export, which may not be what you want. Use `output.exports: "named"` to disable this warning.
|
|
75
75
|
[39m
|
|
76
|
-
[32m✓ built in
|
|
76
|
+
[32m✓ built in 81ms[39m
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/procaptcha-bundle@4.1.
|
|
2
|
+
> @prosopo/procaptcha-bundle@4.1.46 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
1:57:52 PM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
7
|
* ../util/tsconfig.json
|
|
8
8
|
* ../logger/tsconfig.json
|
|
@@ -27,51 +27,51 @@
|
|
|
27
27
|
* ../procaptcha-frictionless/tsconfig.json
|
|
28
28
|
* tsconfig.json
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
1:57:52 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'
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
1:57:52 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
1:57:52 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/logger.ts' is older than output '../logger/tsconfig.tsbuildinfo'
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
1:57:52 PM - Project '../dotenv/tsconfig.json' is up to date because newest input '../dotenv/src/tests/env.unit.test.ts' is older than output '../dotenv/tsconfig.tsbuildinfo'
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
1:57:52 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
1:57:52 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'
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
1:57:52 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
1:57:52 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
1:57:52 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
1:57:52 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
1:57:52 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
1:57:52 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/index.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
1:57:52 PM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/theme.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
1:57:52 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
1:57:52 PM - Project '../account/tsconfig.json' is up to date because newest input '../account/src/tests/cryptoWorker.unit.test.ts' is older than output '../account/tsconfig.tsbuildinfo'
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
1:57:52 PM - Project '../procaptcha-common/tsconfig.json' is up to date because newest input '../procaptcha-common/src/tests/defaultEvents.test.ts' is older than output '../procaptcha-common/tsconfig.tsbuildinfo'
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
1:57:52 PM - Project '../procaptcha-pow/tsconfig.json' is up to date because newest input '../procaptcha-pow/src/tests/managerHarness.ts' is older than output '../procaptcha-pow/tsconfig.tsbuildinfo'
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
1:57:52 PM - Project '../procaptcha-puzzle/tsconfig.json' is up to date because newest input '../procaptcha-puzzle/src/index.ts' is older than output '../procaptcha-puzzle/tsconfig.tsbuildinfo'
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
1:57:52 PM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/tests/mocks/data/captchas.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
1:57:52 PM - Project '../procaptcha/tsconfig.json' is up to date because newest input '../procaptcha/src/modules/Manager.ts' is older than output '../procaptcha/tsconfig.tsbuildinfo'
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
1:57:52 PM - Project '../procaptcha-react/tsconfig.json' is up to date because newest input '../procaptcha-react/src/tests/captchaComponent.unit.test.tsx' is older than output '../procaptcha-react/tsconfig.tsbuildinfo'
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
1:57:52 PM - Project '../procaptcha-frictionless/tsconfig.json' is up to date because newest input '../procaptcha-frictionless/src/tests/customDetectBotAssignTimeout.test.ts' is older than output '../procaptcha-frictionless/tsconfig.tsbuildinfo'
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
1:57:52 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
1:57:52 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-bundle/tsconfig.json'...
|
|
77
77
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/procaptcha-bundle@4.1.
|
|
2
|
+
> @prosopo/procaptcha-bundle@4.1.46 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/procaptcha-bundle@4.1.
|
|
6
|
+
> @prosopo/procaptcha-bundle@4.1.46 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -73,6 +73,6 @@ dist/util/configCreator.js 0.86 kB │ gzip: 0.45 kB
|
|
|
73
73
|
dist/util/language.js 1.01 kB │ gzip: 0.44 kB
|
|
74
74
|
dist/util/captcha/captchaRenderer.js 1.93 kB │ gzip: 0.70 kB
|
|
75
75
|
dist/util/widgetFactory.js 2.52 kB │ gzip: 0.85 kB
|
|
76
|
-
dist/index.js
|
|
76
|
+
dist/index.js 6.11 kB │ gzip: 2.06 kB
|
|
77
77
|
|
|
78
|
-
[32m✓ built in
|
|
78
|
+
[32m✓ built in 68ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @prosopo/procaptcha-bundle
|
|
2
2
|
|
|
3
|
+
## 4.1.46
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- 5d60541: Stop dropping detector bundles that arrive slowly, which made the frictionless POST go out with an empty token and no `detectorSessionId` — the provider then scored the session at 0 and served a challenge.
|
|
7
|
+
|
|
8
|
+
`ASSIGN_TIMEOUT_MS` was 2000 ms and covered two legs. The assign POST serves the detector inline (~215 KB gzipped) over a connection that is always cold, because `/healthz` pins a different hostname than the assign target: fresh DNS, TLS and a CORS preflight all had to fit in the budget alongside the download, measured at 6.7s against staging. The cap is now 10 s and applies only to that request; the blob-URL import that parses and evaluates the bundle is untimed, since a timer cannot rescue a stalled main thread and only discards a bundle already in hand.
|
|
9
|
+
|
|
10
|
+
`render()` and the invisible-button path now start the detector prefetch too. Only implicit render did, so pages using the explicit API — including any page that loads the bundle via dynamic import, where implicit render never runs — assigned a detector inline on the widget's critical path with no prefetch to fall back on.
|
|
11
|
+
- Updated dependencies [5d60541]
|
|
12
|
+
- Updated dependencies [2aabe73]
|
|
13
|
+
- Updated dependencies [bcef918]
|
|
14
|
+
- @prosopo/procaptcha-frictionless@2.13.2
|
|
15
|
+
- @prosopo/types@5.0.1
|
|
16
|
+
- @prosopo/locale@3.2.9
|
|
17
|
+
- @prosopo/dotenv@3.0.51
|
|
18
|
+
- @prosopo/procaptcha-common@2.11.21
|
|
19
|
+
|
|
20
|
+
## 4.1.45
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- fa4fedb: Start the detector-bundle assignment at page load instead of after the widget mounts.
|
|
24
|
+
|
|
25
|
+
Since the detector moved into the provider-served pool, the frictionless flow cannot begin until `/detector/assign` returns. That request was issued by `customDetectBot`, which only runs once React has mounted the widget — so it queued behind the bundle's dynamic-import chain. Measured on the staging demo, `assign` did not leave the browser until **1513 ms**, of which ~700 ms was purely waiting for chunks to arrive in sequence.
|
|
26
|
+
|
|
27
|
+
Nothing in that request depends on React, i18n or the widget config: it needs the site key (a DOM attribute), the environment (a build-time constant) and the IP-mode flags (DOM attributes). The bundle entry now kicks it off as soon as it has read those, and `customDetectBot` claims the in-flight promise instead of starting its own.
|
|
28
|
+
|
|
29
|
+
The prefetch is loaded by dynamic import so the provider selector and API client do not land in the entry chunk and delay first paint; the entry grows by ~400 bytes. It is fire-and-forget — a failed prefetch is indistinguishable from no prefetch, and the existing fallback path still resolves a provider itself.
|
|
30
|
+
|
|
31
|
+
The cache is single-use and keyed on `(environment, ipMode, siteKey)`, so a retry — which is retrying precisely because the pinned pronode failed — re-resolves rather than reusing a stale pin, and a second widget with different flags cannot claim another's assignment.
|
|
32
|
+
- Updated dependencies [fa4fedb]
|
|
33
|
+
- @prosopo/procaptcha-frictionless@2.13.1
|
|
34
|
+
|
|
3
35
|
## 4.1.44
|
|
4
36
|
### Patch Changes
|
|
5
37
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -11,6 +11,23 @@ let _prosopo_util = require("@prosopo/util");
|
|
|
11
11
|
var BUNDLE_NAMES = ["procaptcha.bundle.iife.js", "procaptcha.bundle.js"];
|
|
12
12
|
var procaptchaRoots = [];
|
|
13
13
|
var widgetFactory = new require_widgetFactory.WidgetFactory(new require_widgetThemeResolver.WidgetThemeResolver());
|
|
14
|
+
/**
|
|
15
|
+
* Kick off provider resolution + detector assignment without blocking render.
|
|
16
|
+
*
|
|
17
|
+
* Loaded via dynamic import on purpose: it pulls in the provider selector and
|
|
18
|
+
* the provider API client, and importing those statically would push them into
|
|
19
|
+
* the entry chunk and delay first paint. Firing the import here starts that
|
|
20
|
+
* download in parallel with the widget's own chunks rather than after them.
|
|
21
|
+
*
|
|
22
|
+
* Fire-and-forget by design — a failed prefetch is indistinguishable from no
|
|
23
|
+
* prefetch, and the detection path falls back to resolving a provider itself.
|
|
24
|
+
*/
|
|
25
|
+
var startDetectorPrefetch = (siteKey, flags) => {
|
|
26
|
+
if (!siteKey) return;
|
|
27
|
+
Promise.all([import("@prosopo/procaptcha-frictionless"), import("@prosopo/procaptcha-common")]).then(([frictionless, common]) => {
|
|
28
|
+
frictionless.prefetchDetector(process.env.PROSOPO_DEFAULT_ENVIRONMENT, common.pickIpMode(flags), siteKey);
|
|
29
|
+
}).catch(() => void 0);
|
|
30
|
+
};
|
|
14
31
|
var PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
|
|
15
32
|
var PROCAPTCHA_READY_EVENT = "procaptcha:ready";
|
|
16
33
|
var implicitRender = async () => {
|
|
@@ -25,6 +42,10 @@ var implicitRender = async () => {
|
|
|
25
42
|
console.error("No site key found");
|
|
26
43
|
return;
|
|
27
44
|
}
|
|
45
|
+
startDetectorPrefetch(siteKey, {
|
|
46
|
+
ipv4,
|
|
47
|
+
ipv6
|
|
48
|
+
});
|
|
28
49
|
const root = await widgetFactory.createWidgets(elements, {
|
|
29
50
|
siteKey,
|
|
30
51
|
ipv4,
|
|
@@ -38,6 +59,10 @@ var implicitRender = async () => {
|
|
|
38
59
|
const callback = button.getAttribute("data-callback") || "";
|
|
39
60
|
const ipv4 = button.getAttribute("data-ipv4") === "true";
|
|
40
61
|
const ipv6 = button.getAttribute("data-ipv6") === "true";
|
|
62
|
+
startDetectorPrefetch(siteKey, {
|
|
63
|
+
ipv4,
|
|
64
|
+
ipv6
|
|
65
|
+
});
|
|
41
66
|
const root = await widgetFactory.createWidgets([button], {
|
|
42
67
|
siteKey,
|
|
43
68
|
callback,
|
|
@@ -52,6 +77,7 @@ var implicitRender = async () => {
|
|
|
52
77
|
}
|
|
53
78
|
};
|
|
54
79
|
var render = async (element, renderOptions) => {
|
|
80
|
+
startDetectorPrefetch(renderOptions.siteKey, renderOptions);
|
|
55
81
|
const hasInvisibleSize = Object.prototype.hasOwnProperty.call(renderOptions, "size") && renderOptions.size === "invisible";
|
|
56
82
|
const isWeb2 = !renderOptions.web3;
|
|
57
83
|
if (hasInvisibleSize || element.tagName.toLowerCase() === "button") {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAoB,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AA6HhF,eAAO,MAAM,MAAM,YACT,OAAO,iBACD,uBAAuB,kBA6BtC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,QAY3C;AAED,eAAO,MAAM,OAAO,YAqBnB,CAAC;AAkCF,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,UAAU,EAAE;YACX,KAAK,EAAE,OAAO,KAAK,CAAC;YACpB,MAAM,EAAE,OAAO,MAAM,CAAC;YACtB,KAAK,EAAE,OAAO,KAAK,CAAC;YACpB,OAAO,EAAE,OAAO,OAAO,CAAC;SACxB,CAAC;KACF;CACD;AAmCD,eAAO,MAAM,KAAK,YAOjB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,23 @@ import { at } from "@prosopo/util";
|
|
|
8
8
|
var BUNDLE_NAMES = ["procaptcha.bundle.iife.js", "procaptcha.bundle.js"];
|
|
9
9
|
var procaptchaRoots = [];
|
|
10
10
|
var widgetFactory = new WidgetFactory(new WidgetThemeResolver());
|
|
11
|
+
/**
|
|
12
|
+
* Kick off provider resolution + detector assignment without blocking render.
|
|
13
|
+
*
|
|
14
|
+
* Loaded via dynamic import on purpose: it pulls in the provider selector and
|
|
15
|
+
* the provider API client, and importing those statically would push them into
|
|
16
|
+
* the entry chunk and delay first paint. Firing the import here starts that
|
|
17
|
+
* download in parallel with the widget's own chunks rather than after them.
|
|
18
|
+
*
|
|
19
|
+
* Fire-and-forget by design — a failed prefetch is indistinguishable from no
|
|
20
|
+
* prefetch, and the detection path falls back to resolving a provider itself.
|
|
21
|
+
*/
|
|
22
|
+
var startDetectorPrefetch = (siteKey, flags) => {
|
|
23
|
+
if (!siteKey) return;
|
|
24
|
+
Promise.all([import("@prosopo/procaptcha-frictionless"), import("@prosopo/procaptcha-common")]).then(([frictionless, common]) => {
|
|
25
|
+
frictionless.prefetchDetector(process.env.PROSOPO_DEFAULT_ENVIRONMENT, common.pickIpMode(flags), siteKey);
|
|
26
|
+
}).catch(() => void 0);
|
|
27
|
+
};
|
|
11
28
|
var PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
|
|
12
29
|
var PROCAPTCHA_READY_EVENT = "procaptcha:ready";
|
|
13
30
|
var implicitRender = async () => {
|
|
@@ -22,6 +39,10 @@ var implicitRender = async () => {
|
|
|
22
39
|
console.error("No site key found");
|
|
23
40
|
return;
|
|
24
41
|
}
|
|
42
|
+
startDetectorPrefetch(siteKey, {
|
|
43
|
+
ipv4,
|
|
44
|
+
ipv6
|
|
45
|
+
});
|
|
25
46
|
const root = await widgetFactory.createWidgets(elements, {
|
|
26
47
|
siteKey,
|
|
27
48
|
ipv4,
|
|
@@ -35,6 +56,10 @@ var implicitRender = async () => {
|
|
|
35
56
|
const callback = button.getAttribute("data-callback") || "";
|
|
36
57
|
const ipv4 = button.getAttribute("data-ipv4") === "true";
|
|
37
58
|
const ipv6 = button.getAttribute("data-ipv6") === "true";
|
|
59
|
+
startDetectorPrefetch(siteKey, {
|
|
60
|
+
ipv4,
|
|
61
|
+
ipv6
|
|
62
|
+
});
|
|
38
63
|
const root = await widgetFactory.createWidgets([button], {
|
|
39
64
|
siteKey,
|
|
40
65
|
callback,
|
|
@@ -49,6 +74,7 @@ var implicitRender = async () => {
|
|
|
49
74
|
}
|
|
50
75
|
};
|
|
51
76
|
var render = async (element, renderOptions) => {
|
|
77
|
+
startDetectorPrefetch(renderOptions.siteKey, renderOptions);
|
|
52
78
|
const hasInvisibleSize = Object.prototype.hasOwnProperty.call(renderOptions, "size") && renderOptions.size === "invisible";
|
|
53
79
|
const isWeb2 = !renderOptions.web3;
|
|
54
80
|
if (hasInvisibleSize || element.tagName.toLowerCase() === "button") {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,MAAM,YAAY,GAAG,CAAC,2BAA2B,EAAE,sBAAsB,CAAC,CAAC;AAC3E,IAAI,eAAe,GAAW,EAAE,CAAC;AAEjC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,IAAI,mBAAmB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectorPrefetch.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/detectorPrefetch.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const mocks = vi.hoisted(() => ({
|
|
3
|
+
prefetchDetector: vi.fn(),
|
|
4
|
+
createWidgets: vi.fn(),
|
|
5
|
+
}));
|
|
6
|
+
vi.mock("@prosopo/procaptcha-frictionless", () => ({
|
|
7
|
+
prefetchDetector: mocks.prefetchDetector,
|
|
8
|
+
}));
|
|
9
|
+
vi.mock("@prosopo/procaptcha-common", () => ({
|
|
10
|
+
getWindowCallback: vi.fn(),
|
|
11
|
+
pickIpMode: vi.fn((flags) => flags?.ipv4 ? "ipv4" : undefined),
|
|
12
|
+
}));
|
|
13
|
+
vi.mock("../util/widgetFactory.js", () => ({
|
|
14
|
+
WidgetFactory: vi.fn(function () {
|
|
15
|
+
return { createWidgets: mocks.createWidgets };
|
|
16
|
+
}),
|
|
17
|
+
}));
|
|
18
|
+
const { render } = await import("../index.js");
|
|
19
|
+
const SITE_KEY = "5CcNvLUdiXFpzKDMjThGLSK9rhWHA1H4EF3zrgkpkjAdqmuP";
|
|
20
|
+
const renderAndFlush = async (options) => {
|
|
21
|
+
await render(document.createElement("div"), options);
|
|
22
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
23
|
+
};
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
vi.clearAllMocks();
|
|
26
|
+
mocks.createWidgets.mockResolvedValue([]);
|
|
27
|
+
});
|
|
28
|
+
describe("render", () => {
|
|
29
|
+
it("starts the detector prefetch", async () => {
|
|
30
|
+
await renderAndFlush({ siteKey: SITE_KEY });
|
|
31
|
+
expect(mocks.prefetchDetector).toHaveBeenCalledWith(expect.anything(), undefined, SITE_KEY);
|
|
32
|
+
});
|
|
33
|
+
it("passes the ip-mode preference through to the prefetch", async () => {
|
|
34
|
+
await renderAndFlush({ siteKey: SITE_KEY, ipv4: true });
|
|
35
|
+
expect(mocks.prefetchDetector).toHaveBeenCalledWith(expect.anything(), "ipv4", SITE_KEY);
|
|
36
|
+
});
|
|
37
|
+
it("does not prefetch without a site key", async () => {
|
|
38
|
+
await renderAndFlush({ siteKey: "" });
|
|
39
|
+
expect(mocks.prefetchDetector).not.toHaveBeenCalled();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=detectorPrefetch.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectorPrefetch.unit.test.js","sourceRoot":"","sources":["../../src/tests/detectorPrefetch.unit.test.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/B,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE;IACzB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;CACtB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAAC,CAAC;IAClD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;CACxC,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,4BAA4B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;IAC1B,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,KAAqD,EAAE,EAAE,CAC3E,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAChC;CACD,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1C,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC;IAC/C,CAAC,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;AAE/C,MAAM,QAAQ,GAAG,kDAAkD,CAAC;AAIpE,MAAM,cAAc,GAAG,KAAK,EAC3B,OAAqC,EACrB,EAAE;IAClB,MAAM,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,UAAU,CAAC,GAAG,EAAE;IACf,EAAE,CAAC,aAAa,EAAE,CAAC;IACnB,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAY,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAClD,MAAM,CAAC,QAAQ,EAAE,EACjB,SAAS,EACT,QAAQ,CACR,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAExD,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAClD,MAAM,CAAC,QAAQ,EAAE,EACjB,MAAM,EACN,QAAQ,CACR,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAEtC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACvD,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/procaptcha-bundle",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.46",
|
|
4
4
|
"author": "PROSOPO LIMITED <info@prosopo.io>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
},
|
|
40
40
|
"browserslist": ["> 0.5%, last 2 versions, not dead"],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@prosopo/dotenv": "3.0.
|
|
43
|
-
"@prosopo/locale": "3.2.
|
|
44
|
-
"@prosopo/procaptcha-common": "2.11.
|
|
45
|
-
"@prosopo/procaptcha-frictionless": "2.13.
|
|
46
|
-
"@prosopo/types": "5.0.
|
|
42
|
+
"@prosopo/dotenv": "3.0.51",
|
|
43
|
+
"@prosopo/locale": "3.2.9",
|
|
44
|
+
"@prosopo/procaptcha-common": "2.11.21",
|
|
45
|
+
"@prosopo/procaptcha-frictionless": "2.13.2",
|
|
46
|
+
"@prosopo/types": "5.0.1",
|
|
47
47
|
"@prosopo/util": "3.3.5",
|
|
48
48
|
"@prosopo/widget-skeleton": "2.8.5",
|
|
49
49
|
"dotenv": "16.4.5",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"registry": "https://registry.npmjs.org"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@prosopo/config": "3.3.
|
|
71
|
+
"@prosopo/config": "3.3.7",
|
|
72
72
|
"@types/jsdom": "21.1.7",
|
|
73
73
|
"@types/node": "22.10.2",
|
|
74
74
|
"@types/react": "18.3.1",
|
package/src/index.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
15
|
import { getWindowCallback } from "@prosopo/procaptcha-common";
|
|
16
|
-
import type { ProcaptchaRenderOptions } from "@prosopo/types";
|
|
16
|
+
import type { EnvironmentTypes, ProcaptchaRenderOptions } from "@prosopo/types";
|
|
17
17
|
import { at } from "@prosopo/util";
|
|
18
18
|
import type { Root } from "react-dom/client";
|
|
19
19
|
import { extractParams, getProcaptchaScript } from "./util/config.js";
|
|
@@ -25,6 +25,36 @@ let procaptchaRoots: Root[] = [];
|
|
|
25
25
|
|
|
26
26
|
const widgetFactory = new WidgetFactory(new WidgetThemeResolver());
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Kick off provider resolution + detector assignment without blocking render.
|
|
30
|
+
*
|
|
31
|
+
* Loaded via dynamic import on purpose: it pulls in the provider selector and
|
|
32
|
+
* the provider API client, and importing those statically would push them into
|
|
33
|
+
* the entry chunk and delay first paint. Firing the import here starts that
|
|
34
|
+
* download in parallel with the widget's own chunks rather than after them.
|
|
35
|
+
*
|
|
36
|
+
* Fire-and-forget by design — a failed prefetch is indistinguishable from no
|
|
37
|
+
* prefetch, and the detection path falls back to resolving a provider itself.
|
|
38
|
+
*/
|
|
39
|
+
const startDetectorPrefetch = (
|
|
40
|
+
siteKey: string | null,
|
|
41
|
+
flags: { ipv4?: boolean; ipv6?: boolean },
|
|
42
|
+
): void => {
|
|
43
|
+
if (!siteKey) return;
|
|
44
|
+
void Promise.all([
|
|
45
|
+
import("@prosopo/procaptcha-frictionless"),
|
|
46
|
+
import("@prosopo/procaptcha-common"),
|
|
47
|
+
])
|
|
48
|
+
.then(([frictionless, common]) => {
|
|
49
|
+
frictionless.prefetchDetector(
|
|
50
|
+
process.env.PROSOPO_DEFAULT_ENVIRONMENT as EnvironmentTypes,
|
|
51
|
+
common.pickIpMode(flags),
|
|
52
|
+
siteKey,
|
|
53
|
+
);
|
|
54
|
+
})
|
|
55
|
+
.catch(() => undefined);
|
|
56
|
+
};
|
|
57
|
+
|
|
28
58
|
// Define a custom event name for procaptcha execution
|
|
29
59
|
const PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
|
|
30
60
|
|
|
@@ -50,6 +80,13 @@ const implicitRender = async () => {
|
|
|
50
80
|
return;
|
|
51
81
|
}
|
|
52
82
|
|
|
83
|
+
// Everything the detector assignment needs is known right here: the site
|
|
84
|
+
// key and IP-mode flags come off the DOM, the environment is a build-time
|
|
85
|
+
// constant. Start it now so the round-trip overlaps the widget's own
|
|
86
|
+
// dynamic-import chain instead of queueing behind it —
|
|
87
|
+
// `customDetectBot` claims the in-flight promise when it eventually runs.
|
|
88
|
+
startDetectorPrefetch(siteKey, { ipv4, ipv6 });
|
|
89
|
+
|
|
53
90
|
const root = await widgetFactory.createWidgets(
|
|
54
91
|
elements,
|
|
55
92
|
{
|
|
@@ -75,6 +112,8 @@ const implicitRender = async () => {
|
|
|
75
112
|
const ipv4 = button.getAttribute("data-ipv4") === "true";
|
|
76
113
|
const ipv6 = button.getAttribute("data-ipv6") === "true";
|
|
77
114
|
|
|
115
|
+
startDetectorPrefetch(siteKey, { ipv4, ipv6 });
|
|
116
|
+
|
|
78
117
|
const root = await widgetFactory.createWidgets(
|
|
79
118
|
[button],
|
|
80
119
|
{
|
|
@@ -103,6 +142,8 @@ export const render = async (
|
|
|
103
142
|
element: Element,
|
|
104
143
|
renderOptions: ProcaptchaRenderOptions,
|
|
105
144
|
) => {
|
|
145
|
+
startDetectorPrefetch(renderOptions.siteKey, renderOptions);
|
|
146
|
+
|
|
106
147
|
const hasInvisibleSize =
|
|
107
148
|
Object.prototype.hasOwnProperty.call(renderOptions, "size") &&
|
|
108
149
|
renderOptions.size === "invisible";
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
/**
|
|
16
|
+
* Every entry point that mounts a widget must start the detector prefetch.
|
|
17
|
+
* `render()` did not, so pages using the explicit API (and any page loading
|
|
18
|
+
* the bundle via dynamic import, where implicit render never runs) fell back
|
|
19
|
+
* to assigning a detector inline on the widget's critical path.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { Root } from "react-dom/client";
|
|
23
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
24
|
+
|
|
25
|
+
const mocks = vi.hoisted(() => ({
|
|
26
|
+
prefetchDetector: vi.fn(),
|
|
27
|
+
createWidgets: vi.fn(),
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
vi.mock("@prosopo/procaptcha-frictionless", () => ({
|
|
31
|
+
prefetchDetector: mocks.prefetchDetector,
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
vi.mock("@prosopo/procaptcha-common", () => ({
|
|
35
|
+
getWindowCallback: vi.fn(),
|
|
36
|
+
pickIpMode: vi.fn((flags: { ipv4?: boolean; ipv6?: boolean } | undefined) =>
|
|
37
|
+
flags?.ipv4 ? "ipv4" : undefined,
|
|
38
|
+
),
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
vi.mock("../util/widgetFactory.js", () => ({
|
|
42
|
+
WidgetFactory: vi.fn(function () {
|
|
43
|
+
return { createWidgets: mocks.createWidgets };
|
|
44
|
+
}),
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const { render } = await import("../index.js");
|
|
48
|
+
|
|
49
|
+
const SITE_KEY = "5CcNvLUdiXFpzKDMjThGLSK9rhWHA1H4EF3zrgkpkjAdqmuP";
|
|
50
|
+
|
|
51
|
+
// The prefetch is fire-and-forget behind two dynamic imports, so it lands a
|
|
52
|
+
// few microtasks after render() resolves.
|
|
53
|
+
const renderAndFlush = async (
|
|
54
|
+
options: Parameters<typeof render>[1],
|
|
55
|
+
): Promise<void> => {
|
|
56
|
+
await render(document.createElement("div"), options);
|
|
57
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
vi.clearAllMocks();
|
|
62
|
+
mocks.createWidgets.mockResolvedValue([] as Root[]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("render", () => {
|
|
66
|
+
it("starts the detector prefetch", async () => {
|
|
67
|
+
await renderAndFlush({ siteKey: SITE_KEY });
|
|
68
|
+
|
|
69
|
+
expect(mocks.prefetchDetector).toHaveBeenCalledWith(
|
|
70
|
+
expect.anything(),
|
|
71
|
+
undefined,
|
|
72
|
+
SITE_KEY,
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("passes the ip-mode preference through to the prefetch", async () => {
|
|
77
|
+
await renderAndFlush({ siteKey: SITE_KEY, ipv4: true });
|
|
78
|
+
|
|
79
|
+
expect(mocks.prefetchDetector).toHaveBeenCalledWith(
|
|
80
|
+
expect.anything(),
|
|
81
|
+
"ipv4",
|
|
82
|
+
SITE_KEY,
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("does not prefetch without a site key", async () => {
|
|
87
|
+
await renderAndFlush({ siteKey: "" });
|
|
88
|
+
|
|
89
|
+
expect(mocks.prefetchDetector).not.toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
});
|