@prosopo/provider 5.3.6 → 5.3.7
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 +8 -8
- package/.turbo/turbo-build$colon$tsc.log +25 -25
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +14 -0
- package/dist/cjs/tasks/client/clientTasks.cjs +26 -10
- package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +75 -14
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +10 -1
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +10 -1
- package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +10 -1
- package/dist/cjs/tasks/tasks.cjs +1 -1
- package/dist/tasks/client/clientTasks.d.ts.map +1 -1
- package/dist/tasks/client/clientTasks.js +26 -10
- package/dist/tasks/client/clientTasks.js.map +1 -1
- package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts +3 -0
- package/dist/tasks/decisionMachine/decisionMachineRunner.d.ts.map +1 -1
- package/dist/tasks/decisionMachine/decisionMachineRunner.js +74 -15
- package/dist/tasks/decisionMachine/decisionMachineRunner.js.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +10 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.js +10 -1
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js +10 -1
- package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
- package/dist/tasks/tasks.js +1 -1
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +20 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js +128 -1
- package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/provider@5.3.
|
|
2
|
+
> @prosopo/provider@5.3.7 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
@@ -136,7 +136,7 @@ dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs 4
|
|
|
136
136
|
dist/cjs/api/captcha.cjs 4.51 kB │ gzip: 1.40 kB
|
|
137
137
|
dist/cjs/index.cjs 4.72 kB │ gzip: 0.98 kB
|
|
138
138
|
dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs 4.84 kB │ gzip: 1.74 kB
|
|
139
|
-
dist/cjs/tasks/tasks.cjs 5.07 kB │ gzip: 1.
|
|
139
|
+
dist/cjs/tasks/tasks.cjs 5.07 kB │ gzip: 1.57 kB
|
|
140
140
|
dist/cjs/util/usageCounters.cjs 5.72 kB │ gzip: 2.03 kB
|
|
141
141
|
dist/cjs/tasks/puzzle/puzzleRenderer.cjs 5.87 kB │ gzip: 2.13 kB
|
|
142
142
|
dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs 6.13 kB │ gzip: 1.79 kB
|
|
@@ -146,24 +146,24 @@ dist/cjs/api/metrics.cjs 7
|
|
|
146
146
|
dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs 7.55 kB │ gzip: 2.35 kB
|
|
147
147
|
dist/cjs/tasks/spam/checkTrafficFilter.cjs 7.65 kB │ gzip: 2.55 kB
|
|
148
148
|
dist/cjs/tasks/detection/bundlePool.cjs 8.72 kB │ gzip: 3.26 kB
|
|
149
|
-
dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs 9.67 kB │ gzip: 2.91 kB
|
|
150
149
|
dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs 11.45 kB │ gzip: 2.16 kB
|
|
151
150
|
dist/cjs/api/startProviderApi.cjs 11.62 kB │ gzip: 3.70 kB
|
|
152
151
|
dist/cjs/api/blacklistRequestInspector.cjs 12.28 kB │ gzip: 4.29 kB
|
|
153
|
-
dist/cjs/tasks/
|
|
152
|
+
dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs 12.32 kB │ gzip: 3.81 kB
|
|
154
153
|
dist/cjs/util.cjs 13.25 kB │ gzip: 3.22 kB
|
|
155
154
|
dist/cjs/api/verify.cjs 13.66 kB │ gzip: 2.57 kB
|
|
155
|
+
dist/cjs/tasks/client/clientTasks.cjs 13.81 kB │ gzip: 3.46 kB
|
|
156
156
|
dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs 17.55 kB │ gzip: 4.15 kB
|
|
157
157
|
dist/cjs/tasks/frictionless/frictionlessTasks.cjs 18.88 kB │ gzip: 5.03 kB
|
|
158
|
-
dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs 21.96 kB │ gzip: 4.76 kB
|
|
159
158
|
dist/cjs/tasks/captchaManager.cjs 22.21 kB │ gzip: 6.33 kB
|
|
160
|
-
dist/cjs/tasks/
|
|
161
|
-
dist/cjs/tasks/
|
|
159
|
+
dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs 22.33 kB │ gzip: 4.84 kB
|
|
160
|
+
dist/cjs/tasks/powCaptcha/powTasks.cjs 23.54 kB │ gzip: 5.69 kB
|
|
161
|
+
dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs 27.03 kB │ gzip: 6.27 kB
|
|
162
162
|
dist/cjs/tasks/detection/decodeBehavior.cjs 32.24 kB │ gzip: 10.32 kB
|
|
163
163
|
dist/cjs/tasks/detection/decodeSimd.cjs 36.03 kB │ gzip: 11.96 kB
|
|
164
164
|
dist/cjs/tasks/detection/decodePayload.cjs 49.79 kB │ gzip: 16.98 kB
|
|
165
165
|
|
|
166
|
-
[32m✓ built in
|
|
166
|
+
[32m✓ built in 184ms[39m
|
|
167
167
|
[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
|
|
168
168
|
[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
|
|
169
169
|
[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.3.
|
|
2
|
+
> @prosopo/provider@5.3.7 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
7:24:58 PM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
7
|
* ../util/tsconfig.json
|
|
8
8
|
* ../logger/tsconfig.json
|
|
@@ -26,49 +26,49 @@
|
|
|
26
26
|
* ../puzzle-assets/tsconfig.json
|
|
27
27
|
* tsconfig.json
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
7:24:58 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
7:24:58 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
7:24:58 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
7:24:58 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/tests/apiRoute.unit.test.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
7:24:58 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
7:24:58 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
7:24:58 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'
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
7:24:58 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/batches.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
7:24:58 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/index.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
7:24:58 PM - 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'
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
7:24:58 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/tests/apiHarness.ts' is older than output '../api/tsconfig.tsbuildinfo'
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
7:24:58 PM - 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'
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
7:24:58 PM - 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'
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
7:24:58 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/mongoGlobalSetup.ts' is older than output '../database/tsconfig.tsbuildinfo'
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
7:24:58 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/pair/decode.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
7:24:58 PM - 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'
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
7:24:59 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/env.ts' is older than output '../env/tsconfig.tsbuildinfo'
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
7:24:59 PM - 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'
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
7:24:59 PM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/index.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
7:24:59 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/tests/providers.unit.test.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
7:24:59 PM - 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'
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
7:24:59 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
7:24:59 PM - Building project '/home/runner/work/captcha/captcha/packages/provider/tsconfig.json'...
|
|
74
74
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/provider@5.3.
|
|
2
|
+
> @prosopo/provider@5.3.7 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/provider@5.3.
|
|
6
|
+
> @prosopo/provider@5.3.7 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -150,24 +150,24 @@ dist/api/metrics.js 6.96 k
|
|
|
150
150
|
dist/api/captcha/submitPoWCaptchaSolution.js 7.15 kB │ gzip: 2.31 kB
|
|
151
151
|
dist/tasks/spam/checkTrafficFilter.js 7.32 kB │ gzip: 2.53 kB
|
|
152
152
|
dist/tasks/detection/bundlePool.js 8.30 kB │ gzip: 3.21 kB
|
|
153
|
-
dist/tasks/decisionMachine/decisionMachineRunner.js 9.40 kB │ gzip: 2.86 kB
|
|
154
153
|
dist/api/startProviderApi.js 9.93 kB │ gzip: 3.42 kB
|
|
155
154
|
dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js 10.48 kB │ gzip: 2.13 kB
|
|
156
155
|
dist/api/blacklistRequestInspector.js 11.72 kB │ gzip: 4.25 kB
|
|
157
|
-
dist/tasks/
|
|
156
|
+
dist/tasks/decisionMachine/decisionMachineRunner.js 11.93 kB │ gzip: 3.75 kB
|
|
158
157
|
dist/api/verify.js 12.34 kB │ gzip: 2.47 kB
|
|
159
158
|
dist/util.js 12.57 kB │ gzip: 3.17 kB
|
|
159
|
+
dist/tasks/client/clientTasks.js 13.27 kB │ gzip: 3.43 kB
|
|
160
160
|
dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js 16.41 kB │ gzip: 4.06 kB
|
|
161
161
|
dist/tasks/frictionless/frictionlessTasks.js 18.47 kB │ gzip: 5.01 kB
|
|
162
|
-
dist/tasks/puzzleCaptcha/puzzleTasks.js
|
|
162
|
+
dist/tasks/puzzleCaptcha/puzzleTasks.js 21.03 kB │ gzip: 4.80 kB
|
|
163
163
|
dist/tasks/captchaManager.js 21.73 kB │ gzip: 6.27 kB
|
|
164
|
-
dist/tasks/powCaptcha/powTasks.js
|
|
165
|
-
dist/tasks/imgCaptcha/imgCaptchaTasks.js 25.
|
|
164
|
+
dist/tasks/powCaptcha/powTasks.js 22.25 kB │ gzip: 5.64 kB
|
|
165
|
+
dist/tasks/imgCaptcha/imgCaptchaTasks.js 25.68 kB │ gzip: 6.22 kB
|
|
166
166
|
dist/tasks/detection/decodeBehavior.js 32.26 kB │ gzip: 10.34 kB
|
|
167
167
|
dist/tasks/detection/decodeSimd.js 36.06 kB │ gzip: 12.00 kB
|
|
168
168
|
dist/tasks/detection/decodePayload.js 49.69 kB │ gzip: 16.96 kB
|
|
169
169
|
|
|
170
|
-
[32m✓ built in
|
|
170
|
+
[32m✓ built in 147ms[39m
|
|
171
171
|
[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
|
|
172
172
|
[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
|
|
173
173
|
[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,19 @@
|
|
|
1
1
|
# @prosopo/provider
|
|
2
2
|
|
|
3
|
+
## 5.3.7
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- 1afe466: Cache compiled decision-machine sandboxes; keyset-paginate the pending-stage sweep.
|
|
7
|
+
|
|
8
|
+
- `DecisionMachineRunner` now hits `vm.createContext` + `new vm.Script` at most once per source blob (keyed by SHA-256). Exports `invalidateDecisionMachineScriptCache` and `invalidateAllDecisionMachineArtifactCaches`, both called from `updateDecisionMachine` after any artifact upload.
|
|
9
|
+
- `getUnstoredDappUserCommitments` / `getUnstoredDappUserPoWCommitments` / `getUnstoredSessionRecords` switch from `skip(N)` pagination to keyset (`_id > afterId`). Compound partial index `{pendingStage:1, _id:1}` on all four collections so filter + sort ride one index. Fixes the sweep that was scanning 470k–1.2M docs per page under a large pending backlog.
|
|
10
|
+
- Updated dependencies [1afe466]
|
|
11
|
+
- @prosopo/database@4.0.15
|
|
12
|
+
- @prosopo/types-database@5.1.9
|
|
13
|
+
- @prosopo/env@3.6.38
|
|
14
|
+
- @prosopo/types-env@2.10.34
|
|
15
|
+
- @prosopo/api-express-router@3.1.69
|
|
16
|
+
|
|
3
17
|
## 5.3.6
|
|
4
18
|
### Patch Changes
|
|
5
19
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_validateAddress = require("../../api/validateAddress.cjs");
|
|
2
|
+
const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
|
|
2
3
|
let _prosopo_common = require("@prosopo/common");
|
|
3
4
|
let _prosopo_database = require("@prosopo/database");
|
|
4
5
|
let _prosopo_types = require("@prosopo/types");
|
|
@@ -37,32 +38,32 @@ var ClientTaskManager = class {
|
|
|
37
38
|
const captchaDB = this.getCaptchaDB(this.config.mongoCaptchaUri);
|
|
38
39
|
const sweepStartedAt = /* @__PURE__ */ new Date();
|
|
39
40
|
let processedCommitments = 0;
|
|
40
|
-
await this.processBatchesWithCursor(async (
|
|
41
|
+
await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserCommitments(BATCH_SIZE, afterId), async (batch) => {
|
|
41
42
|
const filteredBatch = (lastTask?.updated ? batch.filter((commitment) => this.isRecordUpdated(commitment)) : batch).filter((commitment) => commitment.id !== "");
|
|
42
43
|
if (filteredBatch.length > 0) {
|
|
43
44
|
await captchaDB.saveCaptchas([], filteredBatch, []);
|
|
44
45
|
await this.providerDB.markDappUserCommitmentsStored(filteredBatch.map((commitment) => commitment.id), sweepStartedAt);
|
|
45
46
|
}
|
|
46
47
|
processedCommitments += filteredBatch.length;
|
|
47
|
-
});
|
|
48
|
+
}, (row) => row._id);
|
|
48
49
|
let processedPowRecords = 0;
|
|
49
|
-
await this.processBatchesWithCursor(async (
|
|
50
|
+
await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserPoWCommitments(BATCH_SIZE, afterId), async (batch) => {
|
|
50
51
|
const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
|
|
51
52
|
if (filteredBatch.length > 0) {
|
|
52
53
|
await captchaDB.saveCaptchas([], [], filteredBatch);
|
|
53
54
|
await this.providerDB.markDappUserPoWCommitmentsStored(filteredBatch.map((record) => record.challenge), sweepStartedAt);
|
|
54
55
|
}
|
|
55
56
|
processedPowRecords += filteredBatch.length;
|
|
56
|
-
});
|
|
57
|
+
}, (row) => row._id);
|
|
57
58
|
let processedSessionRecords = 0;
|
|
58
|
-
await this.processBatchesWithCursor(async (
|
|
59
|
+
await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredSessionRecords(BATCH_SIZE, afterId), async (batch) => {
|
|
59
60
|
const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
|
|
60
61
|
if (filteredBatch.length > 0) {
|
|
61
62
|
await captchaDB.saveCaptchas(filteredBatch, [], []);
|
|
62
63
|
await this.providerDB.markSessionRecordsStored(filteredBatch.map((record) => record.sessionId), sweepStartedAt);
|
|
63
64
|
}
|
|
64
65
|
processedSessionRecords += filteredBatch.length;
|
|
65
|
-
});
|
|
66
|
+
}, (row) => row._id);
|
|
66
67
|
await this.providerDB.updateScheduledTaskStatus(taskID, _prosopo_types.ScheduledTaskStatus.Completed, { data: {
|
|
67
68
|
processedSessionRecords,
|
|
68
69
|
processedCommitments,
|
|
@@ -205,6 +206,8 @@ var ClientTaskManager = class {
|
|
|
205
206
|
createdAt: now,
|
|
206
207
|
updatedAt: now
|
|
207
208
|
});
|
|
209
|
+
require_decisionMachineRunner.invalidateAllDecisionMachineArtifactCaches();
|
|
210
|
+
require_decisionMachineRunner.invalidateDecisionMachineScriptCache();
|
|
208
211
|
return {
|
|
209
212
|
scope,
|
|
210
213
|
dappAccount,
|
|
@@ -307,13 +310,26 @@ var ClientTaskManager = class {
|
|
|
307
310
|
const { lastUpdatedTimestamp, storedAtTimestamp } = record;
|
|
308
311
|
return !lastUpdatedTimestamp || !storedAtTimestamp || lastUpdatedTimestamp.getTime() > storedAtTimestamp.getTime();
|
|
309
312
|
}
|
|
310
|
-
|
|
311
|
-
|
|
313
|
+
/**
|
|
314
|
+
* Drive a keyset-paginated sweep. Each iteration passes the `_id` of the
|
|
315
|
+
* previous batch's last row to `fetchBatch` so the query resumes from
|
|
316
|
+
* `_id > afterId` — see `getUnstoredDappUserCommitments` for why we
|
|
317
|
+
* moved off `skip(N)`. `getLastId` extracts the resumption cursor from
|
|
318
|
+
* a batch row; both `PoWCaptchaRecord` and `UserCommitmentRecord` are
|
|
319
|
+
* `mongoose.Document` subtypes so `_id` is always present at runtime
|
|
320
|
+
* even though our stored types don't spell it out.
|
|
321
|
+
*/
|
|
322
|
+
async processBatchesWithCursor(fetchBatch, processBatch, getLastId) {
|
|
323
|
+
let afterId;
|
|
312
324
|
while (true) {
|
|
313
|
-
const batch = await fetchBatch(
|
|
325
|
+
const batch = await fetchBatch(afterId);
|
|
314
326
|
if (!batch.length) break;
|
|
315
327
|
await processBatch(batch);
|
|
316
|
-
|
|
328
|
+
const last = batch[batch.length - 1];
|
|
329
|
+
if (last === void 0) break;
|
|
330
|
+
const nextId = getLastId(last);
|
|
331
|
+
if (nextId === void 0) break;
|
|
332
|
+
afterId = nextId;
|
|
317
333
|
}
|
|
318
334
|
}
|
|
319
335
|
};
|
|
@@ -1,19 +1,81 @@
|
|
|
1
1
|
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
|
|
2
2
|
let _prosopo_types = require("@prosopo/types");
|
|
3
|
+
let node_crypto = require("node:crypto");
|
|
3
4
|
let node_vm = require("node:vm");
|
|
4
5
|
node_vm = require_runtime.__toESM(node_vm, 1);
|
|
5
6
|
let zod = require("zod");
|
|
6
7
|
//#region src/tasks/decisionMachine/decisionMachineRunner.ts
|
|
7
8
|
var LOAD_TIMEOUT_MS = Number.parseInt(process.env.DECISION_MACHINE_LOAD_TIMEOUT_MS ?? "", 10) || 1e3;
|
|
8
9
|
var EXEC_TIMEOUT_MS = Number.parseInt(process.env.DECISION_MACHINE_EXEC_TIMEOUT_MS ?? "", 10) || 2e3;
|
|
10
|
+
var machineCache = /* @__PURE__ */ new Map();
|
|
11
|
+
var hashSource = (source) => (0, node_crypto.createHash)("sha256").update(source).digest("hex");
|
|
12
|
+
/**
|
|
13
|
+
* Compile + execute the artifact source in a fresh vm sandbox on first use,
|
|
14
|
+
* then reuse the resulting `module.exports` for every subsequent invocation
|
|
15
|
+
* of the same source. See {@link machineCache}.
|
|
16
|
+
*/
|
|
17
|
+
var loadMachine = (source) => {
|
|
18
|
+
const key = hashSource(source);
|
|
19
|
+
const cached = machineCache.get(key);
|
|
20
|
+
if (cached) return cached;
|
|
21
|
+
const sandbox = {
|
|
22
|
+
module: { exports: {} },
|
|
23
|
+
exports: {}
|
|
24
|
+
};
|
|
25
|
+
const context = node_vm.default.createContext(sandbox);
|
|
26
|
+
new node_vm.default.Script(source, { filename: "decision-machine.js" }).runInContext(context, { timeout: LOAD_TIMEOUT_MS });
|
|
27
|
+
const exported = sandbox.module.exports;
|
|
28
|
+
const entry = { exports: typeof exported === "function" ? { default: exported } : exported && typeof exported === "object" ? exported : {} };
|
|
29
|
+
machineCache.set(key, entry);
|
|
30
|
+
return entry;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Clear the module-level script cache. Call after any decision-machine
|
|
34
|
+
* artifact upload so the new source is executed on the next request instead
|
|
35
|
+
* of waiting for the artifact TTL. Also clear every `DecisionMachineRunner`
|
|
36
|
+
* instance's artifact cache — see {@link DecisionMachineRunner.invalidateAllArtifactCaches}.
|
|
37
|
+
*/
|
|
38
|
+
var invalidateDecisionMachineScriptCache = () => {
|
|
39
|
+
machineCache.clear();
|
|
40
|
+
};
|
|
9
41
|
/** How long cached artifacts are considered fresh (ms). */
|
|
10
42
|
var ARTIFACT_CACHE_TTL_MS = Number.parseInt(process.env.DECISION_MACHINE_ARTIFACT_CACHE_TTL_MS ?? "", 10) || 300 * 1e3;
|
|
11
43
|
var DEFAULT_DECISION = { decision: _prosopo_types.DecisionMachineDecision.Allow };
|
|
12
44
|
var RequiredCountersSchema = zod.z.array(_prosopo_types.CounterSpecSchema);
|
|
45
|
+
/**
|
|
46
|
+
* WeakSet-style registry of every live runner. Populated in the constructor
|
|
47
|
+
* and consulted by {@link invalidateAllDecisionMachineArtifactCaches} so an
|
|
48
|
+
* artifact upload can flush every runner's in-memory artifact cache in one
|
|
49
|
+
* call. Held as `WeakRef` so a runner that goes out of scope is garbage
|
|
50
|
+
* collected — this map only ever grows in prod (runners are constructed
|
|
51
|
+
* per task class at process start and live for the process's lifetime) so
|
|
52
|
+
* a plain array would also work, but `WeakRef` is defensive.
|
|
53
|
+
*/
|
|
54
|
+
var liveRunners = /* @__PURE__ */ new Set();
|
|
55
|
+
/**
|
|
56
|
+
* Flush every runner's in-memory artifact cache. Companion to
|
|
57
|
+
* {@link invalidateDecisionMachineScriptCache}. Call both after any
|
|
58
|
+
* `upsertDecisionMachineArtifact` upload.
|
|
59
|
+
*/
|
|
60
|
+
var invalidateAllDecisionMachineArtifactCaches = () => {
|
|
61
|
+
for (const ref of liveRunners) {
|
|
62
|
+
const runner = ref.deref();
|
|
63
|
+
if (runner === void 0) {
|
|
64
|
+
liveRunners.delete(ref);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
runner.invalidateArtifactCache();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
13
70
|
var DecisionMachineRunner = class DecisionMachineRunner {
|
|
14
71
|
constructor(db) {
|
|
15
72
|
this.db = db;
|
|
16
73
|
this.artifactCache = /* @__PURE__ */ new Map();
|
|
74
|
+
liveRunners.add(new WeakRef(this));
|
|
75
|
+
}
|
|
76
|
+
/** Drop every entry in this runner's artifact cache. */
|
|
77
|
+
invalidateArtifactCache() {
|
|
78
|
+
this.artifactCache.clear();
|
|
17
79
|
}
|
|
18
80
|
/** Build a cache key for a given scope + kind + dappAccount tuple. */
|
|
19
81
|
static cacheKey(scope, kind, dappAccount) {
|
|
@@ -168,22 +230,19 @@ var DecisionMachineRunner = class DecisionMachineRunner {
|
|
|
168
230
|
return artifact.captchaType === captchaType;
|
|
169
231
|
}
|
|
170
232
|
/**
|
|
171
|
-
*
|
|
172
|
-
* matching one of {exportNames} (or `
|
|
173
|
-
* function), invoke it with {input},
|
|
174
|
-
* {schema}. Returns undefined when
|
|
175
|
-
* matching export exists. Otherwise
|
|
176
|
-
* output, or sandbox failure.
|
|
233
|
+
* Look up the (cached) module exports for `artifact.source`, locate a
|
|
234
|
+
* callable matching one of {exportNames} (or the cached `default` slot
|
|
235
|
+
* if `module.exports` was itself a function), invoke it with {input},
|
|
236
|
+
* and validate the result with {schema}. Returns undefined when
|
|
237
|
+
* {options.optional} is true and no matching export exists. Otherwise
|
|
238
|
+
* throws on missing export, invalid output, or sandbox failure.
|
|
239
|
+
*
|
|
240
|
+
* The vm.Script compilation + top-level `runInContext` runs at most
|
|
241
|
+
* once per source blob (see {@link loadMachine} / {@link machineCache}).
|
|
177
242
|
*/
|
|
178
243
|
async runArtifactExport(artifact, exportNames, options, schema) {
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
exports: {}
|
|
182
|
-
};
|
|
183
|
-
const context = node_vm.default.createContext(sandbox);
|
|
184
|
-
new node_vm.default.Script(artifact.source, { filename: "decision-machine.js" }).runInContext(context, { timeout: LOAD_TIMEOUT_MS });
|
|
185
|
-
const exported = sandbox.module.exports;
|
|
186
|
-
const named = this.findExport(exported, exportNames);
|
|
244
|
+
const { exports } = loadMachine(artifact.source);
|
|
245
|
+
const named = this.findExport(exports, exportNames);
|
|
187
246
|
if (!named) {
|
|
188
247
|
if (options.optional) return void 0;
|
|
189
248
|
throw new Error(`Decision machine must export one of: ${exportNames.join(", ")}`);
|
|
@@ -220,3 +279,5 @@ var DecisionMachineRunner = class DecisionMachineRunner {
|
|
|
220
279
|
};
|
|
221
280
|
//#endregion
|
|
222
281
|
exports.DecisionMachineRunner = DecisionMachineRunner;
|
|
282
|
+
exports.invalidateAllDecisionMachineArtifactCaches = invalidateAllDecisionMachineArtifactCaches;
|
|
283
|
+
exports.invalidateDecisionMachineScriptCache = invalidateDecisionMachineScriptCache;
|
|
@@ -526,7 +526,16 @@ var ImgCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
526
526
|
ruleType: sessionRecord?.ruleType,
|
|
527
527
|
webView: sessionRecord?.webView,
|
|
528
528
|
iFrame: sessionRecord?.iFrame,
|
|
529
|
-
coords: solution.coords
|
|
529
|
+
coords: solution.coords,
|
|
530
|
+
synNs: sessionRecord?.synNs,
|
|
531
|
+
synackNs: sessionRecord?.synackNs,
|
|
532
|
+
ackNs: sessionRecord?.ackNs,
|
|
533
|
+
observedTtl: sessionRecord?.observedTtl,
|
|
534
|
+
tcpMss: sessionRecord?.tcpMss,
|
|
535
|
+
tcpWscale: sessionRecord?.tcpWscale,
|
|
536
|
+
tcpOptsFlags: sessionRecord?.tcpOptsFlags,
|
|
537
|
+
tcpOptsOrder: sessionRecord?.tcpOptsOrder,
|
|
538
|
+
tcpWindow: sessionRecord?.tcpWindow
|
|
530
539
|
};
|
|
531
540
|
try {
|
|
532
541
|
const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
|
|
@@ -475,7 +475,16 @@ var PowCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
475
475
|
ruleType: sessionRecord?.ruleType,
|
|
476
476
|
webView: sessionRecord?.webView,
|
|
477
477
|
iFrame: sessionRecord?.iFrame,
|
|
478
|
-
coords: challengeRecord.coords
|
|
478
|
+
coords: challengeRecord.coords,
|
|
479
|
+
synNs: sessionRecord?.synNs,
|
|
480
|
+
synackNs: sessionRecord?.synackNs,
|
|
481
|
+
ackNs: sessionRecord?.ackNs,
|
|
482
|
+
observedTtl: sessionRecord?.observedTtl,
|
|
483
|
+
tcpMss: sessionRecord?.tcpMss,
|
|
484
|
+
tcpWscale: sessionRecord?.tcpWscale,
|
|
485
|
+
tcpOptsFlags: sessionRecord?.tcpOptsFlags,
|
|
486
|
+
tcpOptsOrder: sessionRecord?.tcpOptsOrder,
|
|
487
|
+
tcpWindow: sessionRecord?.tcpWindow
|
|
479
488
|
};
|
|
480
489
|
const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
|
|
481
490
|
if (decision.decision === _prosopo_types.DecisionMachineDecision.Deny) {
|
|
@@ -435,7 +435,16 @@ var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
|
|
|
435
435
|
webView: sessionRecord?.webView,
|
|
436
436
|
iFrame: sessionRecord?.iFrame,
|
|
437
437
|
coords: challengeRecord.coords,
|
|
438
|
-
puzzleEvents: challengeRecord.puzzleEvents
|
|
438
|
+
puzzleEvents: challengeRecord.puzzleEvents,
|
|
439
|
+
synNs: sessionRecord?.synNs,
|
|
440
|
+
synackNs: sessionRecord?.synackNs,
|
|
441
|
+
ackNs: sessionRecord?.ackNs,
|
|
442
|
+
observedTtl: sessionRecord?.observedTtl,
|
|
443
|
+
tcpMss: sessionRecord?.tcpMss,
|
|
444
|
+
tcpWscale: sessionRecord?.tcpWscale,
|
|
445
|
+
tcpOptsFlags: sessionRecord?.tcpOptsFlags,
|
|
446
|
+
tcpOptsOrder: sessionRecord?.tcpOptsOrder,
|
|
447
|
+
tcpWindow: sessionRecord?.tcpWindow
|
|
439
448
|
};
|
|
440
449
|
const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
|
|
441
450
|
if (decision.decision === _prosopo_types.DecisionMachineDecision.Deny) {
|
package/dist/cjs/tasks/tasks.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const require_usageCounters = require("../util/usageCounters.cjs");
|
|
2
|
+
const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
|
|
2
3
|
const require_clientTasks = require("./client/clientTasks.cjs");
|
|
3
4
|
const require_datasetTasks = require("./dataset/datasetTasks.cjs");
|
|
4
|
-
const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
|
|
5
5
|
const require_frictionlessTasks = require("./frictionless/frictionlessTasks.cjs");
|
|
6
6
|
const require_imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
|
|
7
7
|
const require_powTasks = require("./powCaptcha/powTasks.cjs");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientTasks.d.ts","sourceRoot":"","sources":["../../../src/tasks/client/clientTasks.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAEN,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,oBAAoB,EACpB,KAAK,aAAa,EAElB,KAAK,mBAAmB,EAGxB,IAAI,EAEJ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAEX,iBAAiB,EAEjB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"clientTasks.d.ts","sourceRoot":"","sources":["../../../src/tasks/client/clientTasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { validateSiteKey } from "../../api/validateAddress.js";
|
|
2
|
+
import { invalidateAllDecisionMachineArtifactCaches, invalidateDecisionMachineScriptCache } from "../decisionMachine/decisionMachineRunner.js";
|
|
2
3
|
import { ProsopoApiError } from "@prosopo/common";
|
|
3
4
|
import { CaptchaDatabase, ClientDatabase } from "@prosopo/database";
|
|
4
5
|
import { DecisionMachineScope, ScheduledTaskNames, ScheduledTaskStatus, Tier } from "@prosopo/types";
|
|
@@ -37,32 +38,32 @@ var ClientTaskManager = class {
|
|
|
37
38
|
const captchaDB = this.getCaptchaDB(this.config.mongoCaptchaUri);
|
|
38
39
|
const sweepStartedAt = /* @__PURE__ */ new Date();
|
|
39
40
|
let processedCommitments = 0;
|
|
40
|
-
await this.processBatchesWithCursor(async (
|
|
41
|
+
await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserCommitments(BATCH_SIZE, afterId), async (batch) => {
|
|
41
42
|
const filteredBatch = (lastTask?.updated ? batch.filter((commitment) => this.isRecordUpdated(commitment)) : batch).filter((commitment) => commitment.id !== "");
|
|
42
43
|
if (filteredBatch.length > 0) {
|
|
43
44
|
await captchaDB.saveCaptchas([], filteredBatch, []);
|
|
44
45
|
await this.providerDB.markDappUserCommitmentsStored(filteredBatch.map((commitment) => commitment.id), sweepStartedAt);
|
|
45
46
|
}
|
|
46
47
|
processedCommitments += filteredBatch.length;
|
|
47
|
-
});
|
|
48
|
+
}, (row) => row._id);
|
|
48
49
|
let processedPowRecords = 0;
|
|
49
|
-
await this.processBatchesWithCursor(async (
|
|
50
|
+
await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredDappUserPoWCommitments(BATCH_SIZE, afterId), async (batch) => {
|
|
50
51
|
const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
|
|
51
52
|
if (filteredBatch.length > 0) {
|
|
52
53
|
await captchaDB.saveCaptchas([], [], filteredBatch);
|
|
53
54
|
await this.providerDB.markDappUserPoWCommitmentsStored(filteredBatch.map((record) => record.challenge), sweepStartedAt);
|
|
54
55
|
}
|
|
55
56
|
processedPowRecords += filteredBatch.length;
|
|
56
|
-
});
|
|
57
|
+
}, (row) => row._id);
|
|
57
58
|
let processedSessionRecords = 0;
|
|
58
|
-
await this.processBatchesWithCursor(async (
|
|
59
|
+
await this.processBatchesWithCursor(async (afterId) => await this.providerDB.getUnstoredSessionRecords(BATCH_SIZE, afterId), async (batch) => {
|
|
59
60
|
const filteredBatch = lastTask?.updated ? batch.filter((record) => this.isRecordUpdated(record)) : batch;
|
|
60
61
|
if (filteredBatch.length > 0) {
|
|
61
62
|
await captchaDB.saveCaptchas(filteredBatch, [], []);
|
|
62
63
|
await this.providerDB.markSessionRecordsStored(filteredBatch.map((record) => record.sessionId), sweepStartedAt);
|
|
63
64
|
}
|
|
64
65
|
processedSessionRecords += filteredBatch.length;
|
|
65
|
-
});
|
|
66
|
+
}, (row) => row._id);
|
|
66
67
|
await this.providerDB.updateScheduledTaskStatus(taskID, ScheduledTaskStatus.Completed, { data: {
|
|
67
68
|
processedSessionRecords,
|
|
68
69
|
processedCommitments,
|
|
@@ -205,6 +206,8 @@ var ClientTaskManager = class {
|
|
|
205
206
|
createdAt: now,
|
|
206
207
|
updatedAt: now
|
|
207
208
|
});
|
|
209
|
+
invalidateAllDecisionMachineArtifactCaches();
|
|
210
|
+
invalidateDecisionMachineScriptCache();
|
|
208
211
|
return {
|
|
209
212
|
scope,
|
|
210
213
|
dappAccount,
|
|
@@ -306,13 +309,26 @@ var ClientTaskManager = class {
|
|
|
306
309
|
const { lastUpdatedTimestamp, storedAtTimestamp } = record;
|
|
307
310
|
return !lastUpdatedTimestamp || !storedAtTimestamp || lastUpdatedTimestamp.getTime() > storedAtTimestamp.getTime();
|
|
308
311
|
}
|
|
309
|
-
|
|
310
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Drive a keyset-paginated sweep. Each iteration passes the `_id` of the
|
|
314
|
+
* previous batch's last row to `fetchBatch` so the query resumes from
|
|
315
|
+
* `_id > afterId` — see `getUnstoredDappUserCommitments` for why we
|
|
316
|
+
* moved off `skip(N)`. `getLastId` extracts the resumption cursor from
|
|
317
|
+
* a batch row; both `PoWCaptchaRecord` and `UserCommitmentRecord` are
|
|
318
|
+
* `mongoose.Document` subtypes so `_id` is always present at runtime
|
|
319
|
+
* even though our stored types don't spell it out.
|
|
320
|
+
*/
|
|
321
|
+
async processBatchesWithCursor(fetchBatch, processBatch, getLastId) {
|
|
322
|
+
let afterId;
|
|
311
323
|
while (true) {
|
|
312
|
-
const batch = await fetchBatch(
|
|
324
|
+
const batch = await fetchBatch(afterId);
|
|
313
325
|
if (!batch.length) break;
|
|
314
326
|
await processBatch(batch);
|
|
315
|
-
|
|
327
|
+
const last = batch[batch.length - 1];
|
|
328
|
+
if (last === void 0) break;
|
|
329
|
+
const nextId = getLastId(last);
|
|
330
|
+
if (nextId === void 0) break;
|
|
331
|
+
afterId = nextId;
|
|
316
332
|
}
|
|
317
333
|
}
|
|
318
334
|
};
|