@prosopo/provider 5.10.1 → 5.10.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 +10 -9
- package/.turbo/turbo-build$colon$tsc.log +27 -27
- package/.turbo/turbo-build.log +12 -11
- package/CHANGELOG.md +95 -0
- package/dist/api/captcha/assignDetectorBundle.d.ts.map +1 -1
- package/dist/api/captcha/assignDetectorBundle.js +27 -9
- package/dist/api/captcha/assignDetectorBundle.js.map +1 -1
- package/dist/api/captcha/assignDetectorBundle.unit.test.d.ts +2 -0
- package/dist/api/captcha/assignDetectorBundle.unit.test.d.ts.map +1 -0
- package/dist/api/captcha/assignDetectorBundle.unit.test.js +153 -0
- package/dist/api/captcha/assignDetectorBundle.unit.test.js.map +1 -0
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +4 -2
- package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
- package/dist/cjs/api/captcha/assignDetectorBundle.cjs +26 -8
- package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +4 -2
- package/dist/cjs/tasks/captchaManager.cjs +34 -3
- package/dist/cjs/tasks/detection/assignSecret.cjs +45 -0
- package/dist/cjs/tasks/detection/bundlePool.cjs +11 -7
- package/dist/cjs/tasks/detection/decodePayload.cjs +1103 -1087
- package/dist/cjs/tasks/detection/decodePayload.js +1 -1
- package/dist/cjs/tasks/detection/getBotScore.cjs +2 -0
- package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +4 -3
- package/dist/tasks/captchaManager.d.ts +1 -0
- package/dist/tasks/captchaManager.d.ts.map +1 -1
- package/dist/tasks/captchaManager.js +34 -3
- package/dist/tasks/captchaManager.js.map +1 -1
- package/dist/tasks/detection/assignSecret.d.ts +8 -0
- package/dist/tasks/detection/assignSecret.d.ts.map +1 -0
- package/dist/tasks/detection/assignSecret.js +45 -0
- package/dist/tasks/detection/assignSecret.js.map +1 -0
- package/dist/tasks/detection/bundlePool.d.ts +2 -1
- package/dist/tasks/detection/bundlePool.d.ts.map +1 -1
- package/dist/tasks/detection/bundlePool.js +11 -8
- package/dist/tasks/detection/bundlePool.js.map +1 -1
- package/dist/tasks/detection/bundlePool.test.js +4 -3
- package/dist/tasks/detection/bundlePool.test.js.map +1 -1
- package/dist/tasks/detection/decodePayload.d.ts +2 -2
- package/dist/tasks/detection/decodePayload.d.ts.map +1 -1
- package/dist/tasks/detection/decodePayload.js +1 -1
- package/dist/tasks/detection/decodePayload.js.map +1 -1
- package/dist/tasks/detection/getBotScore.d.ts +2 -0
- package/dist/tasks/detection/getBotScore.d.ts.map +1 -1
- package/dist/tasks/detection/getBotScore.js +4 -2
- package/dist/tasks/detection/getBotScore.js.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.js +4 -3
- package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
- package/dist/tests/unit/tasks/captchaManager.unit.test.js +46 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
- package/package.json +15 -15
- package/dist/api/captcha/assignDetectorBundle.test.d.ts +0 -2
- package/dist/api/captcha/assignDetectorBundle.test.d.ts.map +0 -1
- package/dist/api/captcha/assignDetectorBundle.test.js +0 -71
- package/dist/api/captcha/assignDetectorBundle.test.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/provider@5.10.
|
|
2
|
+
> @prosopo/provider@5.10.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: .
|
|
@@ -59,7 +59,7 @@ ViteCommonJSConfig: .
|
|
|
59
59
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
60
60
|
Bundle build started
|
|
61
61
|
[2K
|
|
62
|
-
✓
|
|
62
|
+
✓ 111 modules transformed.
|
|
63
63
|
rendering chunks...
|
|
64
64
|
computing gzip size...
|
|
65
65
|
dist/cjs/tasks/index.cjs 0.08 kB │ gzip: 0.07 kB
|
|
@@ -99,6 +99,7 @@ dist/cjs/tasks/puzzle/backgroundBuffer.cjs 1
|
|
|
99
99
|
dist/cjs/pairs.cjs 1.39 kB │ gzip: 0.60 kB
|
|
100
100
|
dist/cjs/tasks/dataset/datasetTasksUtils.cjs 1.42 kB │ gzip: 0.49 kB
|
|
101
101
|
dist/cjs/utils/clientMetaData.cjs 1.48 kB │ gzip: 0.72 kB
|
|
102
|
+
dist/cjs/tasks/detection/assignSecret.cjs 1.48 kB │ gzip: 0.75 kB
|
|
102
103
|
dist/cjs/compositeIpAddress.cjs 1.55 kB │ gzip: 0.57 kB
|
|
103
104
|
dist/cjs/api/admin/apiGetAllDecisionMachinesEndpoint.cjs 1.59 kB │ gzip: 0.60 kB
|
|
104
105
|
dist/cjs/schedulers/updateSpamEmailDomains.cjs 1.64 kB │ gzip: 0.62 kB
|
|
@@ -114,7 +115,6 @@ dist/cjs/utils/honeypot/phraseBank.cjs 1
|
|
|
114
115
|
dist/cjs/api/handshakeTimingMiddleware.cjs 1.88 kB │ gzip: 0.71 kB
|
|
115
116
|
dist/cjs/api/captcha/signedAssetsResolver.cjs 1.96 kB │ gzip: 0.96 kB
|
|
116
117
|
dist/cjs/api/admin/apiClearAllCountersEndpoint.cjs 2.01 kB │ gzip: 0.78 kB
|
|
117
|
-
dist/cjs/api/captcha/assignDetectorBundle.cjs 2.03 kB │ gzip: 0.86 kB
|
|
118
118
|
dist/cjs/tasks/frictionless/ipMatch.cjs 2.03 kB │ gzip: 1.03 kB
|
|
119
119
|
dist/cjs/tasks/spam/updateSpamEmailDomains.cjs 2.12 kB │ gzip: 0.85 kB
|
|
120
120
|
dist/cjs/tasks/frictionless/routingMachine.cjs 2.17 kB │ gzip: 0.91 kB
|
|
@@ -123,13 +123,14 @@ dist/cjs/tasks/puzzle/stratifiedSampler.cjs 2
|
|
|
123
123
|
dist/cjs/tasks/frictionless/frictionlessTasksUtils.cjs 2.21 kB │ gzip: 1.10 kB
|
|
124
124
|
dist/cjs/tasks/captchaTypeSelection.cjs 2.44 kB │ gzip: 1.04 kB
|
|
125
125
|
dist/cjs/api/admin/apiDnsEventEndpoint.cjs 2.59 kB │ gzip: 1.00 kB
|
|
126
|
-
dist/cjs/tasks/detection/getBotScore.cjs 2.
|
|
126
|
+
dist/cjs/tasks/detection/getBotScore.cjs 2.63 kB │ gzip: 0.96 kB
|
|
127
127
|
dist/cjs/utils/dns.cjs 2.66 kB │ gzip: 1.02 kB
|
|
128
128
|
dist/cjs/api/forwardVerify.cjs 2.66 kB │ gzip: 1.12 kB
|
|
129
129
|
dist/cjs/tasks/puzzle/puzzleDifficulty.cjs 2.66 kB │ gzip: 1.10 kB
|
|
130
130
|
dist/cjs/api/public.cjs 2.67 kB │ gzip: 1.05 kB
|
|
131
131
|
dist/cjs/api/captcha/checkSpamEmail.cjs 2.73 kB │ gzip: 0.95 kB
|
|
132
132
|
dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs 2.77 kB │ gzip: 0.99 kB
|
|
133
|
+
dist/cjs/api/captcha/assignDetectorBundle.cjs 2.90 kB │ gzip: 1.15 kB
|
|
133
134
|
dist/cjs/api/captcha/maintenanceModeResponses.cjs 2.91 kB │ gzip: 0.77 kB
|
|
134
135
|
dist/cjs/api/captcha/submitImageCaptchaSolution.cjs 2.93 kB │ gzip: 1.03 kB
|
|
135
136
|
dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs 3.66 kB │ gzip: 1.35 kB
|
|
@@ -154,7 +155,7 @@ dist/cjs/api/captcha/getImageCaptchaChallenge.cjs 7
|
|
|
154
155
|
dist/cjs/tasks/spam/checkTrafficFilter.cjs 7.47 kB │ gzip: 2.48 kB
|
|
155
156
|
dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs 7.56 kB │ gzip: 2.03 kB
|
|
156
157
|
dist/cjs/api/metrics.cjs 7.96 kB │ gzip: 2.23 kB
|
|
157
|
-
dist/cjs/tasks/detection/bundlePool.cjs 8.
|
|
158
|
+
dist/cjs/tasks/detection/bundlePool.cjs 8.89 kB │ gzip: 3.29 kB
|
|
158
159
|
dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs 9.54 kB │ gzip: 2.81 kB
|
|
159
160
|
dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs 10.33 kB │ gzip: 1.82 kB
|
|
160
161
|
dist/cjs/api/startProviderApi.cjs 11.62 kB │ gzip: 3.70 kB
|
|
@@ -163,17 +164,17 @@ dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs 12
|
|
|
163
164
|
dist/cjs/api/blacklistRequestInspector.cjs 13.10 kB │ gzip: 4.41 kB
|
|
164
165
|
dist/cjs/util.cjs 13.15 kB │ gzip: 3.26 kB
|
|
165
166
|
dist/cjs/api/verify.cjs 16.79 kB │ gzip: 2.93 kB
|
|
166
|
-
dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs 20.
|
|
167
|
+
dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs 20.65 kB │ gzip: 4.74 kB
|
|
167
168
|
dist/cjs/tasks/frictionless/frictionlessTasks.cjs 20.69 kB │ gzip: 5.49 kB
|
|
168
|
-
dist/cjs/tasks/captchaManager.cjs
|
|
169
|
+
dist/cjs/tasks/captchaManager.cjs 23.52 kB │ gzip: 6.78 kB
|
|
169
170
|
dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs 24.03 kB │ gzip: 5.15 kB
|
|
170
171
|
dist/cjs/tasks/powCaptcha/powTasks.cjs 24.84 kB │ gzip: 5.97 kB
|
|
171
172
|
dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs 27.96 kB │ gzip: 6.37 kB
|
|
172
173
|
dist/cjs/tasks/detection/decodeBehavior.cjs 32.24 kB │ gzip: 10.32 kB
|
|
173
174
|
dist/cjs/tasks/detection/decodeSimd.cjs 36.03 kB │ gzip: 11.96 kB
|
|
174
|
-
dist/cjs/tasks/detection/decodePayload.cjs
|
|
175
|
+
dist/cjs/tasks/detection/decodePayload.cjs 53.96 kB │ gzip: 18.08 kB
|
|
175
176
|
|
|
176
|
-
[32m✓ built in
|
|
177
|
+
[32m✓ built in 173ms[39m
|
|
177
178
|
[copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeBehavior.js to /home/runner/work/captcha/captcha/packages/provider/dist/cjs/tasks/detection/decodeBehavior.js
|
|
178
179
|
[copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodePayload.js to /home/runner/work/captcha/captcha/packages/provider/dist/cjs/tasks/detection/decodePayload.js
|
|
179
180
|
[copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeSimd.js to /home/runner/work/captcha/captcha/packages/provider/dist/cjs/tasks/detection/decodeSimd.js
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/provider@5.10.
|
|
2
|
+
> @prosopo/provider@5.10.2 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
5:39:46 AM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
7
|
* ../util/tsconfig.json
|
|
8
8
|
* ../logger/tsconfig.json
|
|
@@ -28,53 +28,53 @@
|
|
|
28
28
|
* ../web-bot-auth/tsconfig.json
|
|
29
29
|
* tsconfig.json
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
5:39:46 AM - 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'
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
5:39:46 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
5:39:46 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
5:39:46 AM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
5:39:46 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
5:39:46 AM - 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'
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
5:39:46 AM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
5:39:46 AM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
5:39:46 AM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/types.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
5:39:46 AM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
5:39:46 AM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
5:39:47 AM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/ruleRecord.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
5:39:47 AM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/index.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
5:39:47 AM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/mongoGlobalSetup.ts' is older than output '../database/tsconfig.tsbuildinfo'
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
5:39:47 AM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/keyring/keyring.test.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
5:39:47 AM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/env.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
5:39:47 AM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/tests/env.maintenance.unit.test.ts' is older than output '../env/tsconfig.tsbuildinfo'
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
5:39:47 AM - Project '../api-express-router/tsconfig.json' is up to date because newest input '../api-express-router/src/errorHandler.ts' is older than output '../api-express-router/tsconfig.tsbuildinfo'
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
5:39:47 AM - Project '../captcha-severity/tsconfig.json' is up to date because newest input '../captcha-severity/src/index.test.ts' is older than output '../captcha-severity/tsconfig.tsbuildinfo'
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
5:39:47 AM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/index.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
5:39:47 AM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/tests/productionProviderList.unit.test.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
5:39:47 AM - Project '../puzzle-assets/tsconfig.json' is up to date because newest input '../puzzle-assets/src/background.ts' is older than output '../puzzle-assets/tsconfig.tsbuildinfo'
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
5:39:47 AM - Project '../web-bot-auth/tsconfig.json' is up to date because newest input '../web-bot-auth/src/base64.ts' is older than output '../web-bot-auth/tsconfig.tsbuildinfo'
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
5:39:47 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
5:39:47 AM - Building project '/home/runner/work/captcha/captcha/packages/provider/tsconfig.json'...
|
|
80
80
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/provider@5.10.
|
|
2
|
+
> @prosopo/provider@5.10.2 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/provider@5.10.
|
|
6
|
+
> @prosopo/provider@5.10.2 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -63,7 +63,7 @@ ViteEsmConfig: .
|
|
|
63
63
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
64
64
|
Bundle build started
|
|
65
65
|
[2K
|
|
66
|
-
✓
|
|
66
|
+
✓ 111 modules transformed.
|
|
67
67
|
rendering chunks...
|
|
68
68
|
computing gzip size...
|
|
69
69
|
dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
|
|
@@ -103,6 +103,7 @@ dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js 1.27 k
|
|
|
103
103
|
dist/api/admin/apiRemoveDecisionMachineEndpoint.js 1.29 kB │ gzip: 0.51 kB
|
|
104
104
|
dist/tasks/dataset/datasetTasksUtils.js 1.30 kB │ gzip: 0.48 kB
|
|
105
105
|
dist/compositeIpAddress.js 1.36 kB │ gzip: 0.55 kB
|
|
106
|
+
dist/tasks/detection/assignSecret.js 1.42 kB │ gzip: 0.74 kB
|
|
106
107
|
dist/utils/clientMetaData.js 1.42 kB │ gzip: 0.72 kB
|
|
107
108
|
dist/api/admin/apiGetAllDecisionMachinesEndpoint.js 1.48 kB │ gzip: 0.57 kB
|
|
108
109
|
dist/schedulers/updateSpamEmailDomains.js 1.52 kB │ gzip: 0.60 kB
|
|
@@ -119,7 +120,6 @@ dist/api/handshakeTimingMiddleware.js 1.75 k
|
|
|
119
120
|
dist/tasks/spam/updateSpamEmailDomains.js 1.87 kB │ gzip: 0.77 kB
|
|
120
121
|
dist/api/captcha/signedAssetsResolver.js 1.89 kB │ gzip: 0.94 kB
|
|
121
122
|
dist/api/admin/apiClearAllCountersEndpoint.js 1.89 kB │ gzip: 0.76 kB
|
|
122
|
-
dist/api/captcha/assignDetectorBundle.js 1.90 kB │ gzip: 0.84 kB
|
|
123
123
|
dist/tasks/frictionless/ipMatch.js 1.98 kB │ gzip: 1.02 kB
|
|
124
124
|
dist/migrations/frictionlessLadder.js 2.12 kB │ gzip: 0.93 kB
|
|
125
125
|
dist/tasks/puzzle/stratifiedSampler.js 2.14 kB │ gzip: 1.07 kB
|
|
@@ -132,10 +132,11 @@ dist/utils/dns.js 2.36 k
|
|
|
132
132
|
dist/api/admin/apiDnsEventEndpoint.js 2.43 kB │ gzip: 0.96 kB
|
|
133
133
|
dist/api/captcha/checkSpamEmail.js 2.47 kB │ gzip: 0.91 kB
|
|
134
134
|
dist/tasks/puzzle/puzzleDifficulty.js 2.50 kB │ gzip: 1.09 kB
|
|
135
|
-
dist/tasks/detection/getBotScore.js 2.
|
|
135
|
+
dist/tasks/detection/getBotScore.js 2.55 kB │ gzip: 0.95 kB
|
|
136
136
|
dist/api/captcha/submitPuzzleCaptchaSolution.js 2.55 kB │ gzip: 0.96 kB
|
|
137
137
|
dist/api/forwardVerify.js 2.59 kB │ gzip: 1.10 kB
|
|
138
138
|
dist/api/captcha/submitImageCaptchaSolution.js 2.59 kB │ gzip: 1.00 kB
|
|
139
|
+
dist/api/captcha/assignDetectorBundle.js 2.69 kB │ gzip: 1.11 kB
|
|
139
140
|
dist/api/admin/apiAdminRoutesProvider.js 2.78 kB │ gzip: 0.55 kB
|
|
140
141
|
dist/index.js 2.92 kB │ gzip: 0.80 kB
|
|
141
142
|
dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js 3.39 kB │ gzip: 1.32 kB
|
|
@@ -158,7 +159,7 @@ dist/api/captcha/getPuzzleCaptchaChallenge.js 6.84 k
|
|
|
158
159
|
dist/api/healthzGeo.js 6.86 kB │ gzip: 2.68 kB
|
|
159
160
|
dist/tasks/spam/checkTrafficFilter.js 7.16 kB │ gzip: 2.45 kB
|
|
160
161
|
dist/api/metrics.js 7.36 kB │ gzip: 2.19 kB
|
|
161
|
-
dist/tasks/detection/bundlePool.js 8.
|
|
162
|
+
dist/tasks/detection/bundlePool.js 8.46 kB │ gzip: 3.25 kB
|
|
162
163
|
dist/api/captcha/submitPoWCaptchaSolution.js 9.02 kB │ gzip: 2.76 kB
|
|
163
164
|
dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js 9.36 kB │ gzip: 1.80 kB
|
|
164
165
|
dist/api/startProviderApi.js 9.93 kB │ gzip: 3.42 kB
|
|
@@ -167,17 +168,17 @@ dist/tasks/decisionMachine/decisionMachineRunner.js 11.93 k
|
|
|
167
168
|
dist/api/blacklistRequestInspector.js 12.46 kB │ gzip: 4.37 kB
|
|
168
169
|
dist/util.js 12.47 kB │ gzip: 3.20 kB
|
|
169
170
|
dist/api/verify.js 15.12 kB │ gzip: 2.82 kB
|
|
170
|
-
dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js 19.
|
|
171
|
-
dist/tasks/frictionless/frictionlessTasks.js 20.
|
|
172
|
-
dist/tasks/captchaManager.js 21.92 kB │ gzip: 6.32 kB
|
|
171
|
+
dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js 19.13 kB │ gzip: 4.63 kB
|
|
172
|
+
dist/tasks/frictionless/frictionlessTasks.js 20.12 kB │ gzip: 5.46 kB
|
|
173
173
|
dist/tasks/puzzleCaptcha/puzzleTasks.js 22.62 kB │ gzip: 5.10 kB
|
|
174
|
+
dist/tasks/captchaManager.js 23.01 kB │ gzip: 6.72 kB
|
|
174
175
|
dist/tasks/powCaptcha/powTasks.js 23.47 kB │ gzip: 5.93 kB
|
|
175
176
|
dist/tasks/imgCaptcha/imgCaptchaTasks.js 26.44 kB │ gzip: 6.31 kB
|
|
176
177
|
dist/tasks/detection/decodeBehavior.js 32.26 kB │ gzip: 10.34 kB
|
|
177
178
|
dist/tasks/detection/decodeSimd.js 36.06 kB │ gzip: 12.00 kB
|
|
178
|
-
dist/tasks/detection/decodePayload.js
|
|
179
|
+
dist/tasks/detection/decodePayload.js 53.87 kB │ gzip: 18.06 kB
|
|
179
180
|
|
|
180
|
-
[32m✓ built in
|
|
181
|
+
[32m✓ built in 170ms[39m
|
|
181
182
|
[copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeBehavior.js to /home/runner/work/captcha/captcha/packages/provider/dist/tasks/detection/decodeBehavior.js
|
|
182
183
|
[copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodePayload.js to /home/runner/work/captcha/captcha/packages/provider/dist/tasks/detection/decodePayload.js
|
|
183
184
|
[copy-plugin] copying /home/runner/work/captcha/captcha/packages/provider/src/tasks/detection/decodeSimd.js to /home/runner/work/captcha/captcha/packages/provider/dist/tasks/detection/decodeSimd.js
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# @prosopo/provider
|
|
2
2
|
|
|
3
|
+
## 5.10.2
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- 98ab052: Serve a repeat caller the same detector bundle.
|
|
7
|
+
|
|
8
|
+
`/detector/assign` picked a bundle at random on every request. The provider now
|
|
9
|
+
records which bundle it served a caller and returns that one for a bounded
|
|
10
|
+
period, so a returning visitor gets a stable bundle instead of a fresh draw each
|
|
11
|
+
time. Any bundle performs identically, so this is not visible to users. If Redis
|
|
12
|
+
cannot answer, assign falls back to the previous behaviour rather than failing.
|
|
13
|
+
|
|
14
|
+
Also fixes the `assignDetectorBundle` tests, which were failing on main and had
|
|
15
|
+
gone unnoticed because the file was named `*.test.ts` while CI only runs
|
|
16
|
+
`*.unit.test.ts`. Renamed so it runs, and replaced the mock that
|
|
17
|
+
`clearAllMocks` was silently emptying.
|
|
18
|
+
- 028a158: Add optional field `dz` to detector payload
|
|
19
|
+
- 1f0598c: Derive the detector bundle for a caller instead of storing it.
|
|
20
|
+
|
|
21
|
+
`assignDetectorBundle` now picks the bundle with a keyed hash of the caller's
|
|
22
|
+
address, using a per-provider secret kept on the pool volume. Same caller, same
|
|
23
|
+
bundle, with nothing recorded and nothing to expire — which also means the
|
|
24
|
+
result no longer changes when the cache is unavailable.
|
|
25
|
+
|
|
26
|
+
Replaces the Redis client → bundle entry added in the previous patch, so
|
|
27
|
+
`bindDetectorBundleToClient` and its TTL constant are gone.
|
|
28
|
+
- 3958046: Keep a detector bundle binding for as long as its payload is accepted
|
|
29
|
+
|
|
30
|
+
The `detectorSessionId → bundleId` binding held the only key able to read a
|
|
31
|
+
detector payload, and expired after 60 seconds. The frictionless flow accepts a
|
|
32
|
+
payload for ten minutes (`DEFAULT_MAX_TIMESTAMP_AGE`). For nine of those ten
|
|
33
|
+
minutes the provider would therefore accept a payload it had already discarded
|
|
34
|
+
the means to decrypt: `resolveDecryptAttempts` returns an empty key list, the
|
|
35
|
+
decrypt loop never runs, the score is forced to 1 and the caller is challenged
|
|
36
|
+
despite nothing having been measured about them.
|
|
37
|
+
|
|
38
|
+
Sixty seconds is ample for the assign → submit gap in the normal case — it is
|
|
39
|
+
around 1.5s — but it only has to stall once to be lost, and a backgrounded
|
|
40
|
+
mobile tab is enough.
|
|
41
|
+
|
|
42
|
+
The two values are now one value. `DEFAULT_MAX_TIMESTAMP_AGE` moves from a
|
|
43
|
+
private constant in `frictionlessTasks` to `@prosopo/types`, the only package
|
|
44
|
+
both the provider and the database can see, and `DETECTOR_BUNDLE_TTL_SECONDS` is
|
|
45
|
+
derived from it instead of being written down a second time. A unit test pins
|
|
46
|
+
the relationship so they cannot drift apart again.
|
|
47
|
+
|
|
48
|
+
The TTL cannot now outlive the payload-age check, so this does not widen the
|
|
49
|
+
window in which any payload is usable. Bundle selection is unaffected: which
|
|
50
|
+
bundle a caller receives is derived from their IP and a server secret, not from
|
|
51
|
+
this binding's lifetime.
|
|
52
|
+
- 0cdf286: Log why a detector bundle could not be resolved
|
|
53
|
+
|
|
54
|
+
`resolveBundleByDetectorSession` returns undefined on three unrelated
|
|
55
|
+
conditions: the caller sent no detector session id, the
|
|
56
|
+
`detectorSessionId → bundleId` Redis binding was absent or had expired, or the
|
|
57
|
+
binding named a bundle this provider no longer holds in its pool.
|
|
58
|
+
|
|
59
|
+
All three surface downstream as the same thing — `resolveDecryptAttempts`
|
|
60
|
+
hands back an empty key list, the decrypt loop never runs, and the score is
|
|
61
|
+
forced to 1 with `DECRYPTION_FAILED`, so the caller is challenged despite
|
|
62
|
+
nothing having been measured about it. They need different fixes, but nothing
|
|
63
|
+
recorded which one had happened: the only line carrying that detail logged at
|
|
64
|
+
`debug`, which is below the level aggregated log search runs at, and it could
|
|
65
|
+
not have separated them anyway because `resolveDecryptAttempts` omits the
|
|
66
|
+
`bundleId` whenever the attempt list is empty.
|
|
67
|
+
|
|
68
|
+
Adds a single `info` line, `"Detector bundle not resolved"`, carrying a `cause`
|
|
69
|
+
of `noDetectorSession`, `noBinding` or `bundleNotInPool`, plus the `bundleId`
|
|
70
|
+
in the last case. It is emitted only on the failure path, so there is no cost
|
|
71
|
+
on the hot path, and the pool lookup now happens after the binding check rather
|
|
72
|
+
than before it.
|
|
73
|
+
|
|
74
|
+
No behavioural change — the same conditions return undefined as before.
|
|
75
|
+
- ea4e6aa: Persist the optional `cg` and `sm` session fields, which were not being written.
|
|
76
|
+
- 028a158: Add optional session field `dz`.
|
|
77
|
+
- Updated dependencies [98ab052]
|
|
78
|
+
- Updated dependencies [028a158]
|
|
79
|
+
- Updated dependencies [1f0598c]
|
|
80
|
+
- Updated dependencies [3958046]
|
|
81
|
+
- Updated dependencies [864ddde]
|
|
82
|
+
- Updated dependencies [028a158]
|
|
83
|
+
- @prosopo/database@4.0.33
|
|
84
|
+
- @prosopo/types-database@5.5.3
|
|
85
|
+
- @prosopo/types@5.8.3
|
|
86
|
+
- @prosopo/locale@3.4.2
|
|
87
|
+
- @prosopo/env@3.6.56
|
|
88
|
+
- @prosopo/types-env@2.11.2
|
|
89
|
+
- @prosopo/api@4.2.3
|
|
90
|
+
- @prosopo/api-express-router@3.1.87
|
|
91
|
+
- @prosopo/common@3.1.55
|
|
92
|
+
- @prosopo/datasets@3.1.82
|
|
93
|
+
- @prosopo/ipinfo@0.4.2
|
|
94
|
+
- @prosopo/keyring@2.9.89
|
|
95
|
+
- @prosopo/load-balancer@2.10.44
|
|
96
|
+
- @prosopo/user-access-policy@3.14.3
|
|
97
|
+
|
|
3
98
|
## 5.10.1
|
|
4
99
|
### Patch Changes
|
|
5
100
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assignDetectorBundle.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/assignDetectorBundle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assignDetectorBundle.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/assignDetectorBundle.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;8BA4BpC,mBAAmB,WAEjC,OAAO,GAAG,gBAAgB,OAC1B,QAAQ,SACN,YAAY,KACjB,OAAO,CAAC,QAAQ,CAAC;AALrB,wBA+DG"}
|
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import { getDetectorBundlePool } from "../../tasks/detection/bundlePool.js";
|
|
1
|
+
import { getDetectorBundlePool, getDetectorBundlePoolDir } from "../../tasks/detection/bundlePool.js";
|
|
2
2
|
import { Tasks } from "../../tasks/tasks.js";
|
|
3
|
+
import { getAssignSecret } from "../../tasks/detection/assignSecret.js";
|
|
4
|
+
import { normalizeRequestIp } from "../../utils/normalizeRequestIp.js";
|
|
3
5
|
import { ApiParams } from "@prosopo/types";
|
|
6
|
+
import { createHmac } from "node:crypto";
|
|
4
7
|
import { v4 } from "uuid";
|
|
5
8
|
//#region src/api/captcha/assignDetectorBundle.ts
|
|
9
|
+
/** Pool position for this caller: a keyed hash of their address. */
|
|
10
|
+
var clientIndex = (ip, secret) => createHmac("sha256", secret).update(ip).digest().readUIntBE(0, 6);
|
|
6
11
|
/**
|
|
7
12
|
* Assigns a precomputed detector bundle for this detection session.
|
|
8
13
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
14
|
+
* The bundle is derived from the caller's address and this provider's secret,
|
|
15
|
+
* so a repeat caller keeps getting the same one with nothing stored and nothing
|
|
16
|
+
* to expire. Any bundle detects equally well, so this is not visible to users.
|
|
12
17
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
18
|
+
* The `detectorSessionId → bundleId` binding is still written to Redis; the
|
|
19
|
+
* decrypt side resolves the session's bundle from it on the next hop.
|
|
20
|
+
*
|
|
21
|
+
* Returns `useProviderBundle: false` when there is no pool, no secret, or Redis
|
|
22
|
+
* could not store that binding. There is NO bundled detector to fall back to —
|
|
23
|
+
* the client sends an empty token on the frictionless hop and the provider
|
|
24
|
+
* decides what to serve.
|
|
17
25
|
*/
|
|
18
26
|
var assignDetectorBundle_default = (env) => async (req, res, _next) => {
|
|
19
27
|
try {
|
|
@@ -23,7 +31,17 @@ var assignDetectorBundle_default = (env) => async (req, res, _next) => {
|
|
|
23
31
|
};
|
|
24
32
|
const pool = getDetectorBundlePool();
|
|
25
33
|
if (!pool || pool.size() === 0) return res.json(noBundle);
|
|
26
|
-
const
|
|
34
|
+
const secret = getAssignSecret(getDetectorBundlePoolDir(), {
|
|
35
|
+
info: (msg, data) => req.logger.info(() => ({
|
|
36
|
+
msg,
|
|
37
|
+
data
|
|
38
|
+
})),
|
|
39
|
+
warn: (msg, data) => req.logger.warn(() => ({
|
|
40
|
+
msg,
|
|
41
|
+
data
|
|
42
|
+
}))
|
|
43
|
+
});
|
|
44
|
+
const { bundleId, bundle } = pool.at(clientIndex(normalizeRequestIp(req.ip, req.logger), secret));
|
|
27
45
|
const detectorSessionId = `det-${v4()}`;
|
|
28
46
|
const writeQueue = new Tasks(env, req.logger).frictionlessManager.writeQueue;
|
|
29
47
|
if (!writeQueue) return res.json(noBundle);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assignDetectorBundle.js","sourceRoot":"","sources":["../../../src/api/captcha/assignDetectorBundle.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,SAAS,EAAqC,MAAM,gBAAgB,CAAC;AAG9E,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"assignDetectorBundle.js","sourceRoot":"","sources":["../../../src/api/captcha/assignDetectorBundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assignDetectorBundle.unit.test.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/assignDetectorBundle.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { mkdtempSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { resetAssignSecretCache } from "../../tasks/detection/assignSecret.js";
|
|
6
|
+
import { initDetectorBundlePool } from "../../tasks/detection/bundlePool.js";
|
|
7
|
+
import assignDetectorBundle from "./assignDetectorBundle.js";
|
|
8
|
+
const cacheDetectorBundle = vi.fn(async (_detectorSessionId, _bundleId) => true);
|
|
9
|
+
vi.mock("../../tasks/index.js", () => ({
|
|
10
|
+
Tasks: class {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.frictionlessManager = {
|
|
13
|
+
writeQueue: { cacheDetectorBundle },
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
}));
|
|
18
|
+
const makeReq = (ip = "203.0.113.1") => ({
|
|
19
|
+
ip,
|
|
20
|
+
body: { dapp: "site-key" },
|
|
21
|
+
logger: { warn: vi.fn(), info: vi.fn(), debug: vi.fn() },
|
|
22
|
+
});
|
|
23
|
+
const writePool = (dir, count) => {
|
|
24
|
+
const ids = [];
|
|
25
|
+
for (let i = 0; i < count; i++) {
|
|
26
|
+
const id = `bundle-${i}`;
|
|
27
|
+
writeFileSync(join(dir, `${id}.js`), `export default ${i};`);
|
|
28
|
+
writeFileSync(join(dir, `${id}.json`), JSON.stringify({ privateKey: `PK${i}`, innerConfig: `C${i}` }));
|
|
29
|
+
ids.push(id);
|
|
30
|
+
}
|
|
31
|
+
return ids;
|
|
32
|
+
};
|
|
33
|
+
const assignedBundleId = () => cacheDetectorBundle.mock.calls.at(-1)?.[1];
|
|
34
|
+
const assignOnceWith = async (ip) => {
|
|
35
|
+
const r = makeRes();
|
|
36
|
+
await assignDetectorBundle(env)(makeReq(ip), r.res, next);
|
|
37
|
+
return r;
|
|
38
|
+
};
|
|
39
|
+
const assignOnce = async (ip) => {
|
|
40
|
+
await assignOnceWith(ip);
|
|
41
|
+
};
|
|
42
|
+
const makeRes = () => {
|
|
43
|
+
const json = vi.fn((body) => body);
|
|
44
|
+
return { res: { json }, json };
|
|
45
|
+
};
|
|
46
|
+
const env = {};
|
|
47
|
+
const next = vi.fn();
|
|
48
|
+
describe("assignDetectorBundle", () => {
|
|
49
|
+
let dir;
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
dir = mkdtempSync(join(tmpdir(), "assign-"));
|
|
52
|
+
cacheDetectorBundle.mockClear();
|
|
53
|
+
resetAssignSecretCache();
|
|
54
|
+
});
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
rmSync(dir, { recursive: true, force: true });
|
|
57
|
+
vi.clearAllMocks();
|
|
58
|
+
});
|
|
59
|
+
it("returns useProviderBundle:false when the pool is empty", async () => {
|
|
60
|
+
initDetectorBundlePool(dir);
|
|
61
|
+
const { res, json } = makeRes();
|
|
62
|
+
await assignDetectorBundle(env)(makeReq(), res, next);
|
|
63
|
+
expect(json).toHaveBeenCalledWith({
|
|
64
|
+
useProviderBundle: false,
|
|
65
|
+
status: "ok",
|
|
66
|
+
});
|
|
67
|
+
expect(cacheDetectorBundle).not.toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
it("assigns a bundle, stores the binding, and returns the script", async () => {
|
|
70
|
+
writeFileSync(join(dir, "bundle-0.js"), "export default 1;");
|
|
71
|
+
writeFileSync(join(dir, "bundle-0.json"), JSON.stringify({ privateKey: "PK", innerConfig: "C" }));
|
|
72
|
+
initDetectorBundlePool(dir);
|
|
73
|
+
const { res, json } = makeRes();
|
|
74
|
+
await assignDetectorBundle(env)(makeReq(), res, next);
|
|
75
|
+
expect(cacheDetectorBundle).toHaveBeenCalledTimes(1);
|
|
76
|
+
const [detSessionId, bundleId] = cacheDetectorBundle.mock.calls[0];
|
|
77
|
+
expect(bundleId).toBe("bundle-0");
|
|
78
|
+
expect(detSessionId).toMatch(/^det-/);
|
|
79
|
+
const body = json.mock.calls[0]?.[0];
|
|
80
|
+
expect(body.useProviderBundle).toBe(true);
|
|
81
|
+
expect(body.detectorScript).toBe("export default 1;");
|
|
82
|
+
expect(body.detectorSessionId).toBe(detSessionId);
|
|
83
|
+
});
|
|
84
|
+
it("falls back to bundled when the Redis binding cannot be stored", async () => {
|
|
85
|
+
writeFileSync(join(dir, "bundle-0.js"), "JS");
|
|
86
|
+
writeFileSync(join(dir, "bundle-0.json"), JSON.stringify({ privateKey: "PK", innerConfig: "C" }));
|
|
87
|
+
initDetectorBundlePool(dir);
|
|
88
|
+
cacheDetectorBundle.mockResolvedValueOnce(false);
|
|
89
|
+
const { res, json } = makeRes();
|
|
90
|
+
await assignDetectorBundle(env)(makeReq(), res, next);
|
|
91
|
+
expect(json).toHaveBeenCalledWith({
|
|
92
|
+
useProviderBundle: false,
|
|
93
|
+
status: "ok",
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
it("serves one caller the same bundle across many assigns", async () => {
|
|
97
|
+
writePool(dir, 50);
|
|
98
|
+
initDetectorBundlePool(dir);
|
|
99
|
+
const served = new Set();
|
|
100
|
+
for (let i = 0; i < 200; i++) {
|
|
101
|
+
await assignOnce();
|
|
102
|
+
served.add(assignedBundleId());
|
|
103
|
+
}
|
|
104
|
+
expect(served.size).toBe(1);
|
|
105
|
+
});
|
|
106
|
+
it("keeps serving that bundle after the secret is re-read from disk", async () => {
|
|
107
|
+
writePool(dir, 50);
|
|
108
|
+
initDetectorBundlePool(dir);
|
|
109
|
+
await assignOnce();
|
|
110
|
+
const first = assignedBundleId();
|
|
111
|
+
resetAssignSecretCache();
|
|
112
|
+
await assignOnce();
|
|
113
|
+
expect(assignedBundleId()).toBe(first);
|
|
114
|
+
});
|
|
115
|
+
it("returns the bundle body matching the id it recorded", async () => {
|
|
116
|
+
writePool(dir, 50);
|
|
117
|
+
initDetectorBundlePool(dir);
|
|
118
|
+
const { json } = await assignOnceWith();
|
|
119
|
+
const body = json.mock.calls[0]?.[0];
|
|
120
|
+
expect(body.detectorScript).toBe(`export default ${assignedBundleId().replace("bundle-", "")};`);
|
|
121
|
+
});
|
|
122
|
+
it("spreads distinct callers across the pool", async () => {
|
|
123
|
+
writePool(dir, 50);
|
|
124
|
+
initDetectorBundlePool(dir);
|
|
125
|
+
const served = new Set();
|
|
126
|
+
for (let i = 0; i < 60; i++) {
|
|
127
|
+
await assignOnce(`203.0.113.${i}`);
|
|
128
|
+
served.add(assignedBundleId());
|
|
129
|
+
}
|
|
130
|
+
expect(served.size).toBeGreaterThan(1);
|
|
131
|
+
});
|
|
132
|
+
it("still assigns when Redis holds no client state", async () => {
|
|
133
|
+
writePool(dir, 50);
|
|
134
|
+
initDetectorBundlePool(dir);
|
|
135
|
+
const { json } = await assignOnceWith();
|
|
136
|
+
const body = json.mock.calls[0]?.[0];
|
|
137
|
+
expect(body.useProviderBundle).toBe(true);
|
|
138
|
+
expect(assignedBundleId()).toMatch(/^bundle-\d+$/);
|
|
139
|
+
});
|
|
140
|
+
it("writes the secret 0600 and leaves it alone on reload", async () => {
|
|
141
|
+
writePool(dir, 50);
|
|
142
|
+
initDetectorBundlePool(dir);
|
|
143
|
+
await assignOnce();
|
|
144
|
+
const secretPath = join(dir, ".assign-secret");
|
|
145
|
+
const first = readFileSync(secretPath);
|
|
146
|
+
expect(first.length).toBe(32);
|
|
147
|
+
expect(statSync(secretPath).mode & 0o777).toBe(0o600);
|
|
148
|
+
resetAssignSecretCache();
|
|
149
|
+
await assignOnce();
|
|
150
|
+
expect(readFileSync(secretPath)).toEqual(first);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=assignDetectorBundle.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assignDetectorBundle.unit.test.js","sourceRoot":"","sources":["../../../src/api/captcha/assignDetectorBundle.unit.test.ts"],"names":[],"mappings":"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"}
|