@prosopo/procaptcha-frictionless 2.13.0 → 2.13.2
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 +6 -5
- package/.turbo/turbo-build$colon$tsc.log +24 -24
- package/.turbo/turbo-build.log +7 -6
- package/CHANGELOG.md +36 -0
- package/dist/cjs/customDetectBot.cjs +21 -13
- package/dist/cjs/detectorPrefetch.cjs +65 -0
- package/dist/cjs/index.cjs +4 -0
- package/dist/customDetectBot.d.ts.map +1 -1
- package/dist/customDetectBot.js +21 -13
- package/dist/customDetectBot.js.map +1 -1
- package/dist/detectorPrefetch.d.ts +12 -0
- package/dist/detectorPrefetch.d.ts.map +1 -0
- package/dist/detectorPrefetch.js +63 -0
- package/dist/detectorPrefetch.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/tests/customDetectBotAssignTimeout.test.d.ts +2 -0
- package/dist/tests/customDetectBotAssignTimeout.test.d.ts.map +1 -0
- package/dist/tests/customDetectBotAssignTimeout.test.js +118 -0
- package/dist/tests/customDetectBotAssignTimeout.test.js.map +1 -0
- package/dist/tests/detectorPrefetch.test.d.ts +2 -0
- package/dist/tests/detectorPrefetch.test.d.ts.map +1 -0
- package/dist/tests/detectorPrefetch.test.js +71 -0
- package/dist/tests/detectorPrefetch.test.js.map +1 -0
- package/package.json +10 -10
- package/src/customDetectBot.ts +67 -33
- package/src/detectorPrefetch.ts +115 -0
- package/src/index.ts +1 -0
- package/src/tests/customDetectBotAssignTimeout.test.ts +180 -0
- package/src/tests/detectorPrefetch.test.ts +114 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/procaptcha-frictionless@2.13.
|
|
2
|
+
> @prosopo/procaptcha-frictionless@2.13.2 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
@@ -53,13 +53,14 @@ ViteCommonJSConfig: .
|
|
|
53
53
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
54
54
|
Bundle build started
|
|
55
55
|
[2K
|
|
56
|
-
✓
|
|
56
|
+
✓ 7 modules transformed.
|
|
57
57
|
rendering chunks...
|
|
58
58
|
computing gzip size...
|
|
59
|
-
dist/cjs/index.cjs 0.
|
|
59
|
+
dist/cjs/index.cjs 0.54 kB │ gzip: 0.21 kB
|
|
60
60
|
dist/cjs/detectorLoader.cjs 0.62 kB │ gzip: 0.40 kB
|
|
61
61
|
dist/cjs/sessionInvalidatedRecovery.cjs 2.07 kB │ gzip: 0.99 kB
|
|
62
|
-
dist/cjs/
|
|
62
|
+
dist/cjs/detectorPrefetch.cjs 2.98 kB │ gzip: 1.35 kB
|
|
63
|
+
dist/cjs/customDetectBot.cjs 5.43 kB │ gzip: 1.64 kB
|
|
63
64
|
dist/cjs/ProcaptchaFrictionless.cjs 7.00 kB │ gzip: 2.02 kB
|
|
64
65
|
|
|
65
|
-
[32m✓ built in
|
|
66
|
+
[32m✓ built in 53ms[39m
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/procaptcha-frictionless@2.13.
|
|
2
|
+
> @prosopo/procaptcha-frictionless@2.13.2 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
1:57:48 PM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
7
|
* ../locale/tsconfig.json
|
|
8
8
|
* ../util/tsconfig.json
|
|
@@ -25,47 +25,47 @@
|
|
|
25
25
|
* ../procaptcha-react/tsconfig.json
|
|
26
26
|
* tsconfig.json
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
1:57: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'
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
1:57:48 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
1:57:48 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: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'
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
1:57:48 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'
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
1:57:48 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
1:57:48 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/logger.ts' is older than output '../logger/tsconfig.tsbuildinfo'
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
1:57:48 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
1:57:48 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
1:57:48 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
1:57:48 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'
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
1:57:48 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'
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
1:57:48 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
1:57:48 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'
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
1:57:48 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'
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
1:57:48 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'
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
1:57:48 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'
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
1:57:48 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'
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
1:57:48 PM - Project '../procaptcha/tsconfig.json' is up to date because newest input '../procaptcha/src/modules/Manager.ts' is older than output '../procaptcha/tsconfig.tsbuildinfo'
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
1:57:48 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'
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
1:57:48 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
1:57:48 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-frictionless/tsconfig.json'...
|
|
71
71
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/procaptcha-frictionless@2.13.
|
|
2
|
+
> @prosopo/procaptcha-frictionless@2.13.2 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/procaptcha-frictionless@2.13.
|
|
6
|
+
> @prosopo/procaptcha-frictionless@2.13.2 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -57,14 +57,15 @@ ViteEsmConfig: .
|
|
|
57
57
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
58
58
|
Bundle build started
|
|
59
59
|
[2K
|
|
60
|
-
✓
|
|
60
|
+
✓ 7 modules transformed.
|
|
61
61
|
rendering chunks...
|
|
62
62
|
computing gzip size...
|
|
63
63
|
dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
|
|
64
|
-
dist/index.js 0.
|
|
64
|
+
dist/index.js 0.32 kB │ gzip: 0.15 kB
|
|
65
65
|
dist/detectorLoader.js 0.60 kB │ gzip: 0.39 kB
|
|
66
66
|
dist/sessionInvalidatedRecovery.js 2.01 kB │ gzip: 0.98 kB
|
|
67
|
-
dist/
|
|
67
|
+
dist/detectorPrefetch.js 2.86 kB │ gzip: 1.32 kB
|
|
68
|
+
dist/customDetectBot.js 5.26 kB │ gzip: 1.61 kB
|
|
68
69
|
dist/ProcaptchaFrictionless.js 6.49 kB │ gzip: 1.97 kB
|
|
69
70
|
|
|
70
|
-
[32m✓ built in
|
|
71
|
+
[32m✓ built in 50ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @prosopo/procaptcha-frictionless
|
|
2
2
|
|
|
3
|
+
## 2.13.2
|
|
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
|
+
- 2aabe73: Remove the client-controlled `detectorUnavailable` frictionless bypass. A client could set the flag and be handed a PoW challenge without any detection running. The flag is gone from the wire format, the API client and the widget; the only remaining bypasses are provider-side (maintenance mode, empty detector bundle pool).
|
|
12
|
+
|
|
13
|
+
The frictionless decision machine now gates on payload presence after the access-rule ladder: no token serves a 3-round image captcha, a token without its head hash serves a 2-round one.
|
|
14
|
+
- Updated dependencies [9fec7bd]
|
|
15
|
+
- Updated dependencies [2aabe73]
|
|
16
|
+
- Updated dependencies [bcef918]
|
|
17
|
+
- @prosopo/common@3.1.49
|
|
18
|
+
- @prosopo/types@5.0.1
|
|
19
|
+
- @prosopo/api@4.0.1
|
|
20
|
+
- @prosopo/locale@3.2.9
|
|
21
|
+
- @prosopo/procaptcha-common@2.11.21
|
|
22
|
+
- @prosopo/procaptcha-pow@2.10.28
|
|
23
|
+
- @prosopo/procaptcha-puzzle@2.10.44
|
|
24
|
+
- @prosopo/procaptcha-react@2.9.101
|
|
25
|
+
|
|
26
|
+
## 2.13.1
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- fa4fedb: Start the detector-bundle assignment at page load instead of after the widget mounts.
|
|
30
|
+
|
|
31
|
+
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.
|
|
32
|
+
|
|
33
|
+
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.
|
|
34
|
+
|
|
35
|
+
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.
|
|
36
|
+
|
|
37
|
+
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.
|
|
38
|
+
|
|
3
39
|
## 2.13.0
|
|
4
40
|
### Minor Changes
|
|
5
41
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const require_detectorLoader = require("./detectorLoader.cjs");
|
|
2
|
+
const require_detectorPrefetch = require("./detectorPrefetch.cjs");
|
|
2
3
|
let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
|
|
3
4
|
let _prosopo_api = require("@prosopo/api");
|
|
4
5
|
let _prosopo_common = require("@prosopo/common");
|
|
5
6
|
//#region src/customDetectBot.ts
|
|
6
|
-
var ASSIGN_TIMEOUT_MS =
|
|
7
|
+
var ASSIGN_TIMEOUT_MS = 1e4;
|
|
7
8
|
var sanitiseHref = (href) => {
|
|
8
9
|
try {
|
|
9
10
|
const u = new URL(href);
|
|
@@ -67,24 +68,31 @@ var customDetectBot = async (config, container, restartFn, retryContext) => {
|
|
|
67
68
|
if (!config.account.address) throw new _prosopo_common.ProsopoEnvError("GENERAL.SITE_KEY_MISSING");
|
|
68
69
|
const ipMode = (0, _prosopo_procaptcha_common.pickIpMode)(config);
|
|
69
70
|
const extClassPromise = (0, _prosopo_procaptcha_common.ExtensionLoader)(config.web2);
|
|
70
|
-
const
|
|
71
|
+
const prefetched = !retryContext || retryContext.attempt <= 1 ? require_detectorPrefetch.takePrefetchedDetector(config.defaultEnvironment, ipMode, config.account.address) : void 0;
|
|
72
|
+
let prefetchedResult;
|
|
73
|
+
if (prefetched) try {
|
|
74
|
+
prefetchedResult = await prefetched;
|
|
75
|
+
} catch {
|
|
76
|
+
prefetchedResult = void 0;
|
|
77
|
+
}
|
|
78
|
+
const provider = prefetchedResult?.provider ?? await (0, _prosopo_procaptcha_common.getProcaptchaRandomActiveProvider)(config.defaultEnvironment, ipMode, retryContext);
|
|
71
79
|
const providerApi = new _prosopo_api.ProviderApi(provider.provider.url, config.account.address);
|
|
72
80
|
let detectorSessionId;
|
|
73
81
|
let providerDetect;
|
|
74
82
|
try {
|
|
75
|
-
const assigned = await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
|
|
83
|
+
const assigned = prefetchedResult?.assigned ?? await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
|
|
76
84
|
if (assigned.useProviderBundle && assigned.detectorScript) {
|
|
85
|
+
providerDetect = await require_detectorLoader.DetectorLoaderFromScript(assigned.detectorScript);
|
|
77
86
|
detectorSessionId = assigned.detectorSessionId;
|
|
78
|
-
providerDetect = await withTimeout(require_detectorLoader.DetectorLoaderFromScript(assigned.detectorScript), ASSIGN_TIMEOUT_MS);
|
|
79
87
|
}
|
|
80
88
|
} catch {}
|
|
81
89
|
const ext = new (await extClassPromise)();
|
|
82
90
|
if (providerDetect === void 0) {
|
|
83
91
|
const userAccount = await ext.getAccount(config);
|
|
84
92
|
const { currentUrl: fallbackUrl, iframeUrl: fallbackIframeUrl } = getCurrentPageUrls();
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
fetch(
|
|
93
|
+
const captcha = await withTimeout(providerApi.getFrictionlessCaptcha(void 0, void 0, config.account.address, userAccount.account.address, config.mode, void 0, void 0, fallbackUrl, fallbackIframeUrl), 1e4);
|
|
94
|
+
if (captcha.dns_url) try {
|
|
95
|
+
fetch(captcha.dns_url, {
|
|
88
96
|
method: "GET",
|
|
89
97
|
mode: "no-cors",
|
|
90
98
|
credentials: "omit",
|
|
@@ -93,19 +101,19 @@ var customDetectBot = async (config, container, restartFn, retryContext) => {
|
|
|
93
101
|
}).catch(() => void 0);
|
|
94
102
|
} catch {}
|
|
95
103
|
return {
|
|
96
|
-
captchaType:
|
|
97
|
-
sessionId:
|
|
104
|
+
captchaType: captcha.captchaType,
|
|
105
|
+
sessionId: captcha.sessionId,
|
|
98
106
|
provider,
|
|
99
|
-
status:
|
|
107
|
+
status: captcha.status,
|
|
100
108
|
userAccount,
|
|
101
|
-
error:
|
|
102
|
-
hp:
|
|
109
|
+
error: captcha.error,
|
|
110
|
+
hp: captcha.hp
|
|
103
111
|
};
|
|
104
112
|
}
|
|
105
113
|
const detectionResult = await providerDetect(container, restartFn, () => ext.getAccount(config));
|
|
106
114
|
const userAccount = detectionResult.userAccount;
|
|
107
115
|
const { currentUrl, iframeUrl } = getCurrentPageUrls();
|
|
108
|
-
const captchaPromise = providerApi.getFrictionlessCaptcha(detectionResult.token, detectionResult.encryptHeadHash, config.account.address, userAccount.account.address, config.mode, void 0, detectorSessionId,
|
|
116
|
+
const captchaPromise = providerApi.getFrictionlessCaptcha(detectionResult.token, detectionResult.encryptHeadHash, config.account.address, userAccount.account.address, config.mode, void 0, detectorSessionId, currentUrl, iframeUrl);
|
|
109
117
|
if (detectionResult.getSimdReadings) detectionResult.getSimdReadings(6e4).catch(() => void 0);
|
|
110
118
|
const captcha = await withTimeout(captchaPromise, 1e4);
|
|
111
119
|
if (captcha.dns_url) try {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
|
|
2
|
+
let _prosopo_api = require("@prosopo/api");
|
|
3
|
+
//#region src/detectorPrefetch.ts
|
|
4
|
+
/**
|
|
5
|
+
* Detector bundle prefetch.
|
|
6
|
+
*
|
|
7
|
+
* Since the detector moved into the provider-served pool, the frictionless flow
|
|
8
|
+
* cannot start until `/detector/assign` has returned. That request is issued by
|
|
9
|
+
* `customDetectBot`, which only runs once React has mounted the widget — and
|
|
10
|
+
* that mount sits behind the bundle's dynamic-import chain. Measured on a
|
|
11
|
+
* staging demo page the assign request did not leave the browser until 1513 ms,
|
|
12
|
+
* of which ~700 ms was purely waiting for chunks to arrive in sequence.
|
|
13
|
+
*
|
|
14
|
+
* Nothing in the request depends on React, i18n or the widget config: it needs
|
|
15
|
+
* the site key (a DOM attribute, readable immediately), the environment (a
|
|
16
|
+
* build-time constant) and the IP-mode flags (DOM attributes). So the entry
|
|
17
|
+
* point kicks it off as soon as it has read those, and `customDetectBot` picks
|
|
18
|
+
* up the in-flight promise instead of starting its own.
|
|
19
|
+
*
|
|
20
|
+
* The cache is deliberately single-use. A provider pin is only valid for the
|
|
21
|
+
* attempt it was made for — on a retry the previous pronode is the one that
|
|
22
|
+
* just failed — so a consumed entry is dropped and the retry re-resolves.
|
|
23
|
+
*/
|
|
24
|
+
var inFlight = /* @__PURE__ */ new Map();
|
|
25
|
+
var keyOf = (environment, ipMode, siteKey) => `${environment}|${ipMode ?? "auto"}|${siteKey}`;
|
|
26
|
+
/**
|
|
27
|
+
* Start resolving a provider and assigning a detector bundle. Safe to call more
|
|
28
|
+
* than once for the same key — subsequent calls join the in-flight request.
|
|
29
|
+
*
|
|
30
|
+
* Never rejects to the caller: a failed prefetch is indistinguishable from
|
|
31
|
+
* never having prefetched, and `customDetectBot` already handles assign failure
|
|
32
|
+
* by falling back to PoW. Returning a rejected promise here would surface as an
|
|
33
|
+
* unhandled rejection in the host page.
|
|
34
|
+
*/
|
|
35
|
+
var prefetchDetector = (environment, ipMode, siteKey) => {
|
|
36
|
+
const key = keyOf(environment, ipMode, siteKey);
|
|
37
|
+
if (inFlight.has(key)) return;
|
|
38
|
+
const promise = (async () => {
|
|
39
|
+
const provider = await (0, _prosopo_procaptcha_common.getProcaptchaRandomActiveProvider)(environment, ipMode);
|
|
40
|
+
return {
|
|
41
|
+
provider,
|
|
42
|
+
assigned: await new _prosopo_api.ProviderApi(provider.provider.url, siteKey).assignDetectorBundle(siteKey)
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
promise.catch(() => void 0);
|
|
46
|
+
inFlight.set(key, promise);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Claim a prefetched assignment, if one was started for this exact key. The
|
|
50
|
+
* entry is removed, so a retry does not reuse a pin that may have just failed.
|
|
51
|
+
*/
|
|
52
|
+
var takePrefetchedDetector = (environment, ipMode, siteKey) => {
|
|
53
|
+
const key = keyOf(environment, ipMode, siteKey);
|
|
54
|
+
const promise = inFlight.get(key);
|
|
55
|
+
if (promise) inFlight.delete(key);
|
|
56
|
+
return promise;
|
|
57
|
+
};
|
|
58
|
+
/** Test seam — drops any in-flight prefetches. */
|
|
59
|
+
var clearPrefetchedDetectors = () => {
|
|
60
|
+
inFlight.clear();
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
exports.clearPrefetchedDetectors = clearPrefetchedDetectors;
|
|
64
|
+
exports.prefetchDetector = prefetchDetector;
|
|
65
|
+
exports.takePrefetchedDetector = takePrefetchedDetector;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_detectorPrefetch = require("./detectorPrefetch.cjs");
|
|
2
3
|
const require_ProcaptchaFrictionless = require("./ProcaptchaFrictionless.cjs");
|
|
3
4
|
exports.ProcaptchaFrictionless = require_ProcaptchaFrictionless.ProcaptchaFrictionless;
|
|
5
|
+
exports.clearPrefetchedDetectors = require_detectorPrefetch.clearPrefetchedDetectors;
|
|
6
|
+
exports.prefetchDetector = require_detectorPrefetch.prefetchDetector;
|
|
7
|
+
exports.takePrefetchedDetector = require_detectorPrefetch.takePrefetchedDetector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customDetectBot.d.ts","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACX,oBAAoB,EAGpB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"customDetectBot.d.ts","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACX,oBAAoB,EAGpB,MAAM,gBAAgB,CAAC;AAyFxB,eAAO,MAAM,WAAW,GAAU,CAAC,WACzB,OAAO,CAAC,CAAC,CAAC,MACf,MAAM,KACR,OAAO,CAAC,CAAC,CAoBX,CAAC;AAEF,QAAA,MAAM,eAAe,EAAE,oBAwNtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
package/dist/customDetectBot.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { DetectorLoaderFromScript } from "./detectorLoader.js";
|
|
2
|
+
import { takePrefetchedDetector } from "./detectorPrefetch.js";
|
|
2
3
|
import { ExtensionLoader, getProcaptchaRandomActiveProvider, pickIpMode } from "@prosopo/procaptcha-common";
|
|
3
4
|
import { ProviderApi } from "@prosopo/api";
|
|
4
5
|
import { ProsopoEnvError } from "@prosopo/common";
|
|
5
6
|
//#region src/customDetectBot.ts
|
|
6
|
-
var ASSIGN_TIMEOUT_MS =
|
|
7
|
+
var ASSIGN_TIMEOUT_MS = 1e4;
|
|
7
8
|
var sanitiseHref = (href) => {
|
|
8
9
|
try {
|
|
9
10
|
const u = new URL(href);
|
|
@@ -67,24 +68,31 @@ var customDetectBot = async (config, container, restartFn, retryContext) => {
|
|
|
67
68
|
if (!config.account.address) throw new ProsopoEnvError("GENERAL.SITE_KEY_MISSING");
|
|
68
69
|
const ipMode = pickIpMode(config);
|
|
69
70
|
const extClassPromise = ExtensionLoader(config.web2);
|
|
70
|
-
const
|
|
71
|
+
const prefetched = !retryContext || retryContext.attempt <= 1 ? takePrefetchedDetector(config.defaultEnvironment, ipMode, config.account.address) : void 0;
|
|
72
|
+
let prefetchedResult;
|
|
73
|
+
if (prefetched) try {
|
|
74
|
+
prefetchedResult = await prefetched;
|
|
75
|
+
} catch {
|
|
76
|
+
prefetchedResult = void 0;
|
|
77
|
+
}
|
|
78
|
+
const provider = prefetchedResult?.provider ?? await getProcaptchaRandomActiveProvider(config.defaultEnvironment, ipMode, retryContext);
|
|
71
79
|
const providerApi = new ProviderApi(provider.provider.url, config.account.address);
|
|
72
80
|
let detectorSessionId;
|
|
73
81
|
let providerDetect;
|
|
74
82
|
try {
|
|
75
|
-
const assigned = await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
|
|
83
|
+
const assigned = prefetchedResult?.assigned ?? await withTimeout(providerApi.assignDetectorBundle(config.account.address), ASSIGN_TIMEOUT_MS);
|
|
76
84
|
if (assigned.useProviderBundle && assigned.detectorScript) {
|
|
85
|
+
providerDetect = await DetectorLoaderFromScript(assigned.detectorScript);
|
|
77
86
|
detectorSessionId = assigned.detectorSessionId;
|
|
78
|
-
providerDetect = await withTimeout(DetectorLoaderFromScript(assigned.detectorScript), ASSIGN_TIMEOUT_MS);
|
|
79
87
|
}
|
|
80
88
|
} catch {}
|
|
81
89
|
const ext = new (await extClassPromise)();
|
|
82
90
|
if (providerDetect === void 0) {
|
|
83
91
|
const userAccount = await ext.getAccount(config);
|
|
84
92
|
const { currentUrl: fallbackUrl, iframeUrl: fallbackIframeUrl } = getCurrentPageUrls();
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
fetch(
|
|
93
|
+
const captcha = await withTimeout(providerApi.getFrictionlessCaptcha(void 0, void 0, config.account.address, userAccount.account.address, config.mode, void 0, void 0, fallbackUrl, fallbackIframeUrl), 1e4);
|
|
94
|
+
if (captcha.dns_url) try {
|
|
95
|
+
fetch(captcha.dns_url, {
|
|
88
96
|
method: "GET",
|
|
89
97
|
mode: "no-cors",
|
|
90
98
|
credentials: "omit",
|
|
@@ -93,19 +101,19 @@ var customDetectBot = async (config, container, restartFn, retryContext) => {
|
|
|
93
101
|
}).catch(() => void 0);
|
|
94
102
|
} catch {}
|
|
95
103
|
return {
|
|
96
|
-
captchaType:
|
|
97
|
-
sessionId:
|
|
104
|
+
captchaType: captcha.captchaType,
|
|
105
|
+
sessionId: captcha.sessionId,
|
|
98
106
|
provider,
|
|
99
|
-
status:
|
|
107
|
+
status: captcha.status,
|
|
100
108
|
userAccount,
|
|
101
|
-
error:
|
|
102
|
-
hp:
|
|
109
|
+
error: captcha.error,
|
|
110
|
+
hp: captcha.hp
|
|
103
111
|
};
|
|
104
112
|
}
|
|
105
113
|
const detectionResult = await providerDetect(container, restartFn, () => ext.getAccount(config));
|
|
106
114
|
const userAccount = detectionResult.userAccount;
|
|
107
115
|
const { currentUrl, iframeUrl } = getCurrentPageUrls();
|
|
108
|
-
const captchaPromise = providerApi.getFrictionlessCaptcha(detectionResult.token, detectionResult.encryptHeadHash, config.account.address, userAccount.account.address, config.mode, void 0, detectorSessionId,
|
|
116
|
+
const captchaPromise = providerApi.getFrictionlessCaptcha(detectionResult.token, detectionResult.encryptHeadHash, config.account.address, userAccount.account.address, config.mode, void 0, detectorSessionId, currentUrl, iframeUrl);
|
|
109
117
|
if (detectionResult.getSimdReadings) detectionResult.getSimdReadings(6e4).catch(() => void 0);
|
|
110
118
|
const captcha = await withTimeout(captchaPromise, 1e4);
|
|
111
119
|
if (captcha.dns_url) try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customDetectBot.js","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACN,eAAe,EACf,iCAAiC,EACjC,UAAU,GACV,MAAM,4BAA4B,CAAC;AAOpC,OAAO,EACN,wBAAwB,GAExB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"customDetectBot.js","sourceRoot":"","sources":["../src/customDetectBot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getProcaptchaRandomActiveProvider } from "@prosopo/procaptcha-common";
|
|
2
|
+
import type { AssignDetectorBundleResponse, EnvironmentTypes, RandomProvider } from "@prosopo/types";
|
|
3
|
+
type IpModeParam = Parameters<typeof getProcaptchaRandomActiveProvider>[1];
|
|
4
|
+
export interface PrefetchedDetector {
|
|
5
|
+
provider: RandomProvider;
|
|
6
|
+
assigned: AssignDetectorBundleResponse;
|
|
7
|
+
}
|
|
8
|
+
export declare const prefetchDetector: (environment: EnvironmentTypes, ipMode: IpModeParam, siteKey: string) => void;
|
|
9
|
+
export declare const takePrefetchedDetector: (environment: EnvironmentTypes, ipMode: IpModeParam, siteKey: string) => Promise<PrefetchedDetector> | undefined;
|
|
10
|
+
export declare const clearPrefetchedDetectors: () => void;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=detectorPrefetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectorPrefetch.d.ts","sourceRoot":"","sources":["../src/detectorPrefetch.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,KAAK,EACX,4BAA4B,EAC5B,gBAAgB,EAChB,cAAc,EACd,MAAM,gBAAgB,CAAC;AAMxB,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iCAAiC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,4BAA4B,CAAC;CACvC;AAmBD,eAAO,MAAM,gBAAgB,gBACf,gBAAgB,UACrB,WAAW,WACV,MAAM,KACb,IAmBF,CAAC;AAMF,eAAO,MAAM,sBAAsB,gBACrB,gBAAgB,UACrB,WAAW,WACV,MAAM,KACb,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAKhC,CAAC;AAGF,eAAO,MAAM,wBAAwB,QAAO,IAE3C,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { getProcaptchaRandomActiveProvider } from "@prosopo/procaptcha-common";
|
|
2
|
+
import { ProviderApi } from "@prosopo/api";
|
|
3
|
+
//#region src/detectorPrefetch.ts
|
|
4
|
+
/**
|
|
5
|
+
* Detector bundle prefetch.
|
|
6
|
+
*
|
|
7
|
+
* Since the detector moved into the provider-served pool, the frictionless flow
|
|
8
|
+
* cannot start until `/detector/assign` has returned. That request is issued by
|
|
9
|
+
* `customDetectBot`, which only runs once React has mounted the widget — and
|
|
10
|
+
* that mount sits behind the bundle's dynamic-import chain. Measured on a
|
|
11
|
+
* staging demo page the assign request did not leave the browser until 1513 ms,
|
|
12
|
+
* of which ~700 ms was purely waiting for chunks to arrive in sequence.
|
|
13
|
+
*
|
|
14
|
+
* Nothing in the request depends on React, i18n or the widget config: it needs
|
|
15
|
+
* the site key (a DOM attribute, readable immediately), the environment (a
|
|
16
|
+
* build-time constant) and the IP-mode flags (DOM attributes). So the entry
|
|
17
|
+
* point kicks it off as soon as it has read those, and `customDetectBot` picks
|
|
18
|
+
* up the in-flight promise instead of starting its own.
|
|
19
|
+
*
|
|
20
|
+
* The cache is deliberately single-use. A provider pin is only valid for the
|
|
21
|
+
* attempt it was made for — on a retry the previous pronode is the one that
|
|
22
|
+
* just failed — so a consumed entry is dropped and the retry re-resolves.
|
|
23
|
+
*/
|
|
24
|
+
var inFlight = /* @__PURE__ */ new Map();
|
|
25
|
+
var keyOf = (environment, ipMode, siteKey) => `${environment}|${ipMode ?? "auto"}|${siteKey}`;
|
|
26
|
+
/**
|
|
27
|
+
* Start resolving a provider and assigning a detector bundle. Safe to call more
|
|
28
|
+
* than once for the same key — subsequent calls join the in-flight request.
|
|
29
|
+
*
|
|
30
|
+
* Never rejects to the caller: a failed prefetch is indistinguishable from
|
|
31
|
+
* never having prefetched, and `customDetectBot` already handles assign failure
|
|
32
|
+
* by falling back to PoW. Returning a rejected promise here would surface as an
|
|
33
|
+
* unhandled rejection in the host page.
|
|
34
|
+
*/
|
|
35
|
+
var prefetchDetector = (environment, ipMode, siteKey) => {
|
|
36
|
+
const key = keyOf(environment, ipMode, siteKey);
|
|
37
|
+
if (inFlight.has(key)) return;
|
|
38
|
+
const promise = (async () => {
|
|
39
|
+
const provider = await getProcaptchaRandomActiveProvider(environment, ipMode);
|
|
40
|
+
return {
|
|
41
|
+
provider,
|
|
42
|
+
assigned: await new ProviderApi(provider.provider.url, siteKey).assignDetectorBundle(siteKey)
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
promise.catch(() => void 0);
|
|
46
|
+
inFlight.set(key, promise);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Claim a prefetched assignment, if one was started for this exact key. The
|
|
50
|
+
* entry is removed, so a retry does not reuse a pin that may have just failed.
|
|
51
|
+
*/
|
|
52
|
+
var takePrefetchedDetector = (environment, ipMode, siteKey) => {
|
|
53
|
+
const key = keyOf(environment, ipMode, siteKey);
|
|
54
|
+
const promise = inFlight.get(key);
|
|
55
|
+
if (promise) inFlight.delete(key);
|
|
56
|
+
return promise;
|
|
57
|
+
};
|
|
58
|
+
/** Test seam — drops any in-flight prefetches. */
|
|
59
|
+
var clearPrefetchedDetectors = () => {
|
|
60
|
+
inFlight.clear();
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
export { clearPrefetchedDetectors, prefetchDetector, takePrefetchedDetector };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detectorPrefetch.js","sourceRoot":"","sources":["../src/detectorPrefetch.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAkB/E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuC,CAAC;AAEhE,MAAM,KAAK,GAAG,CACb,WAA6B,EAC7B,MAAmB,EACnB,OAAe,EACN,EAAE,CAAC,GAAG,WAAW,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;AAW7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,WAA6B,EAC7B,MAAmB,EACnB,OAAe,EACR,EAAE;IACT,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAE9B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAiC,EAAE;QACxD,MAAM,QAAQ,GAAG,MAAM,iCAAiC,CACvD,WAAW,EACX,MAAM,CACN,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC;IAKL,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACrC,WAA6B,EAC7B,MAAmB,EACnB,OAAe,EAC2B,EAAE;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,OAAO;QAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAS,EAAE;IAClD,QAAQ,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { clearPrefetchedDetectors, prefetchDetector, takePrefetchedDetector } from "./detectorPrefetch.js";
|
|
2
3
|
import { ProcaptchaFrictionless } from "./ProcaptchaFrictionless.js";
|
|
3
|
-
export { ProcaptchaFrictionless };
|
|
4
|
+
export { ProcaptchaFrictionless, clearPrefetchedDetectors, prefetchDetector, takePrefetchedDetector };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customDetectBotAssignTimeout.test.d.ts","sourceRoot":"","sources":["../../src/tests/customDetectBotAssignTimeout.test.ts"],"names":[],"mappings":""}
|