@prosopo/provider 5.12.2 → 5.13.0

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.
Files changed (69) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +13 -10
  2. package/.turbo/turbo-build$colon$tsc.log +27 -27
  3. package/.turbo/turbo-build.log +13 -10
  4. package/CHANGELOG.md +69 -0
  5. package/dist/api/captcha/assetSeal.d.ts +15 -0
  6. package/dist/api/captcha/assetSeal.d.ts.map +1 -0
  7. package/dist/api/captcha/assetSeal.js +22 -0
  8. package/dist/api/captcha/assetSeal.js.map +1 -0
  9. package/dist/api/captcha/assetSealFormat.d.ts +23 -0
  10. package/dist/api/captcha/assetSealFormat.d.ts.map +1 -0
  11. package/dist/api/captcha/assetSealFormat.js +87 -0
  12. package/dist/api/captcha/assetSealFormat.js.map +1 -0
  13. package/dist/api/captcha/getImageCaptchaChallenge.d.ts.map +1 -1
  14. package/dist/api/captcha/getImageCaptchaChallenge.js +2 -1
  15. package/dist/api/captcha/getImageCaptchaChallenge.js.map +1 -1
  16. package/dist/api/captcha/sealedAssetsResolver.d.ts +22 -0
  17. package/dist/api/captcha/sealedAssetsResolver.d.ts.map +1 -0
  18. package/dist/api/captcha/sealedAssetsResolver.js +69 -0
  19. package/dist/api/captcha/sealedAssetsResolver.js.map +1 -0
  20. package/dist/api/captcha/signedAssetsResolver.d.ts +2 -1
  21. package/dist/api/captcha/signedAssetsResolver.d.ts.map +1 -1
  22. package/dist/api/captcha/signedAssetsResolver.js +6 -5
  23. package/dist/api/captcha/signedAssetsResolver.js.map +1 -1
  24. package/dist/cjs/api/captcha/assetSeal.cjs +22 -0
  25. package/dist/cjs/api/captcha/assetSealFormat.cjs +95 -0
  26. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +2 -1
  27. package/dist/cjs/api/captcha/sealedAssetsResolver.cjs +70 -0
  28. package/dist/cjs/api/captcha/signedAssetsResolver.cjs +6 -4
  29. package/dist/cjs/compositeIpAddress.cjs +44 -0
  30. package/dist/cjs/index.cjs +1 -0
  31. package/dist/cjs/tasks/captchaManager.cjs +15 -1
  32. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +12 -2
  33. package/dist/compositeIpAddress.d.ts +1 -0
  34. package/dist/compositeIpAddress.d.ts.map +1 -1
  35. package/dist/compositeIpAddress.js +44 -1
  36. package/dist/compositeIpAddress.js.map +1 -1
  37. package/dist/edge/assetSealHandler.d.ts +9 -0
  38. package/dist/edge/assetSealHandler.d.ts.map +1 -0
  39. package/dist/edge/assetSealHandler.js +74 -0
  40. package/dist/edge/assetSealHandler.js.map +1 -0
  41. package/dist/index.js +2 -2
  42. package/dist/tasks/captchaManager.d.ts +1 -1
  43. package/dist/tasks/captchaManager.d.ts.map +1 -1
  44. package/dist/tasks/captchaManager.js +15 -1
  45. package/dist/tasks/captchaManager.js.map +1 -1
  46. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  47. package/dist/tasks/powCaptcha/powTasks.js +13 -3
  48. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  49. package/dist/tests/unit/api/captcha/assetSeal.unit.test.d.ts +2 -0
  50. package/dist/tests/unit/api/captcha/assetSeal.unit.test.d.ts.map +1 -0
  51. package/dist/tests/unit/api/captcha/assetSeal.unit.test.js +132 -0
  52. package/dist/tests/unit/api/captcha/assetSeal.unit.test.js.map +1 -0
  53. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.d.ts +2 -0
  54. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.d.ts.map +1 -0
  55. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.js +151 -0
  56. package/dist/tests/unit/api/captcha/sealedAssetsResolver.unit.test.js.map +1 -0
  57. package/dist/tests/unit/compositeIpAddress.unit.test.js +37 -1
  58. package/dist/tests/unit/compositeIpAddress.unit.test.js.map +1 -1
  59. package/dist/tests/unit/edge/assetSealHandler.unit.test.d.ts +2 -0
  60. package/dist/tests/unit/edge/assetSealHandler.unit.test.d.ts.map +1 -0
  61. package/dist/tests/unit/edge/assetSealHandler.unit.test.js +145 -0
  62. package/dist/tests/unit/edge/assetSealHandler.unit.test.js.map +1 -0
  63. package/dist/tests/unit/tasks/captchaManager.unit.test.js +41 -0
  64. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
  65. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +100 -1
  66. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
  67. package/edge/entry.ts +62 -0
  68. package/package.json +16 -14
  69. package/scripts/buildEdgeScript.mjs +31 -0
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/provider@5.12.2 build:cjs
2
+ > @prosopo/provider@5.13.0 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -32,6 +32,7 @@ ViteCommonJSConfig: .
32
32
  {
33
33
  externals: [
34
34
  '@prosopo/api-route',
35
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
35
36
  '@prosopo/logger',
36
37
  '@prosopo/util',
37
38
  '@prosopo/api-express-router',
@@ -55,11 +56,10 @@ ViteCommonJSConfig: .
55
56
  '@prosopo/web-bot-auth'
56
57
  ]
57
58
  }
58
- The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
59
59
  vite v8.1.5 building ssr environment for production...
60
60
  Bundle build started
61
61
  
62
- ✓ 113 modules transformed.
62
+ ✓ 116 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
@@ -79,6 +79,7 @@ dist/cjs/api/validateAddress.cjs 0
79
79
  dist/cjs/api/ja4.cjs 0.85 kB │ gzip: 0.47 kB
80
80
  dist/cjs/api/dnsEventUrl.cjs 0.85 kB │ gzip: 0.46 kB
81
81
  dist/cjs/tasks/dataset/datasetTasks.cjs 0.92 kB │ gzip: 0.41 kB
82
+ dist/cjs/api/captcha/assetSeal.cjs 0.99 kB │ gzip: 0.51 kB
82
83
  dist/cjs/_virtual/_rolldown/runtime.cjs 1.00 kB │ gzip: 0.50 kB
83
84
  dist/cjs/api/headerCheckMiddleware.cjs 1.02 kB │ gzip: 0.45 kB
84
85
  dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.cjs 1.03 kB │ gzip: 0.53 kB
@@ -103,7 +104,6 @@ dist/cjs/tasks/puzzle/backgroundBuffer.cjs 1
103
104
  dist/cjs/utils/clientMetaData.cjs 1.48 kB │ gzip: 0.72 kB
104
105
  dist/cjs/tasks/detection/assignSecret.cjs 1.48 kB │ gzip: 0.75 kB
105
106
  dist/cjs/api/assetDocument.cjs 1.50 kB │ gzip: 0.81 kB
106
- dist/cjs/compositeIpAddress.cjs 1.55 kB │ gzip: 0.57 kB
107
107
  dist/cjs/api/admin/apiGetAllDecisionMachinesEndpoint.cjs 1.59 kB │ gzip: 0.60 kB
108
108
  dist/cjs/schedulers/updateSpamEmailDomains.cjs 1.64 kB │ gzip: 0.62 kB
109
109
  dist/cjs/utils/honeypot/encoders.cjs 1.66 kB │ gzip: 0.67 kB
@@ -116,7 +116,6 @@ dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs 1
116
116
  dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs 1.80 kB │ gzip: 0.72 kB
117
117
  dist/cjs/utils/honeypot/phraseBank.cjs 1.87 kB │ gzip: 0.91 kB
118
118
  dist/cjs/api/handshakeTimingMiddleware.cjs 1.88 kB │ gzip: 0.71 kB
119
- dist/cjs/api/captcha/signedAssetsResolver.cjs 1.96 kB │ gzip: 0.96 kB
120
119
  dist/cjs/api/admin/apiClearAllCountersEndpoint.cjs 2.01 kB │ gzip: 0.78 kB
121
120
  dist/cjs/tasks/frictionless/ipMatch.cjs 2.03 kB │ gzip: 1.03 kB
122
121
  dist/cjs/tasks/spam/updateSpamEmailDomains.cjs 2.12 kB │ gzip: 0.85 kB
@@ -124,6 +123,8 @@ dist/cjs/migrations/frictionlessLadder.cjs 2
124
123
  dist/cjs/tasks/puzzle/stratifiedSampler.cjs 2.20 kB │ gzip: 1.08 kB
125
124
  dist/cjs/tasks/frictionless/routingMachine.cjs 2.21 kB │ gzip: 0.93 kB
126
125
  dist/cjs/tasks/frictionless/frictionlessTasksUtils.cjs 2.21 kB │ gzip: 1.10 kB
126
+ dist/cjs/api/captcha/signedAssetsResolver.cjs 2.24 kB │ gzip: 1.00 kB
127
+ dist/cjs/api/captcha/sealedAssetsResolver.cjs 2.37 kB │ gzip: 0.98 kB
127
128
  dist/cjs/tasks/captchaTypeSelection.cjs 2.44 kB │ gzip: 1.04 kB
128
129
  dist/cjs/api/admin/apiDnsEventEndpoint.cjs 2.59 kB │ gzip: 1.00 kB
129
130
  dist/cjs/utils/dns.cjs 2.66 kB │ gzip: 1.02 kB
@@ -135,6 +136,8 @@ dist/cjs/api/public.cjs 2
135
136
  dist/cjs/api/captcha/maintenanceModeResponses.cjs 2.91 kB │ gzip: 0.77 kB
136
137
  dist/cjs/api/captcha/submitImageCaptchaSolution.cjs 2.93 kB │ gzip: 1.03 kB
137
138
  dist/cjs/tasks/detection/getBotScore.cjs 3.37 kB │ gzip: 1.33 kB
139
+ dist/cjs/compositeIpAddress.cjs 3.39 kB │ gzip: 1.36 kB
140
+ dist/cjs/api/captcha/assetSealFormat.cjs 3.59 kB │ gzip: 1.37 kB
138
141
  dist/cjs/api/captcha/assignDetectorBundle.cjs 3.63 kB │ gzip: 1.37 kB
139
142
  dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs 3.66 kB │ gzip: 1.35 kB
140
143
  dist/cjs/api/admin/apiAdminRoutesProvider.cjs 3.67 kB │ gzip: 0.62 kB
@@ -150,13 +153,13 @@ dist/cjs/tasks/puzzle/puzzleRenderer.cjs 4
150
153
  dist/cjs/api/captcha.cjs 4.51 kB │ gzip: 1.40 kB
151
154
  dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs 4.56 kB │ gzip: 1.07 kB
152
155
  dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs 4.84 kB │ gzip: 1.74 kB
153
- dist/cjs/index.cjs 4.95 kB │ gzip: 1.03 kB
156
+ dist/cjs/index.cjs 5.02 kB │ gzip: 1.05 kB
154
157
  dist/cjs/tasks/tasks.cjs 5.07 kB │ gzip: 1.57 kB
155
158
  dist/cjs/tasks/detection/decoderPool.cjs 5.47 kB │ gzip: 2.06 kB
156
159
  dist/cjs/util/usageCounters.cjs 5.72 kB │ gzip: 2.03 kB
157
160
  dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs 6.73 kB │ gzip: 1.89 kB
158
161
  dist/cjs/api/healthzGeo.cjs 7.03 kB │ gzip: 2.70 kB
159
- dist/cjs/api/captcha/getImageCaptchaChallenge.cjs 7.25 kB │ gzip: 2.05 kB
162
+ dist/cjs/api/captcha/getImageCaptchaChallenge.cjs 7.39 kB │ gzip: 2.06 kB
160
163
  dist/cjs/tasks/spam/checkTrafficFilter.cjs 7.47 kB │ gzip: 2.48 kB
161
164
  dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs 7.56 kB │ gzip: 2.03 kB
162
165
  dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs 9.12 kB │ gzip: 2.71 kB
@@ -171,12 +174,12 @@ dist/cjs/api/blacklistRequestInspector.cjs 13
171
174
  dist/cjs/api/verify.cjs 16.79 kB │ gzip: 2.93 kB
172
175
  dist/cjs/tasks/frictionless/frictionlessTasks.cjs 18.37 kB │ gzip: 4.89 kB
173
176
  dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs 20.05 kB │ gzip: 4.59 kB
174
- dist/cjs/tasks/captchaManager.cjs 23.94 kB │ gzip: 7.10 kB
175
177
  dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs 24.12 kB │ gzip: 5.17 kB
176
- dist/cjs/tasks/powCaptcha/powTasks.cjs 24.99 kB │ gzip: 6.02 kB
178
+ dist/cjs/tasks/captchaManager.cjs 24.62 kB │ gzip: 7.42 kB
179
+ dist/cjs/tasks/powCaptcha/powTasks.cjs 25.55 kB │ gzip: 6.16 kB
177
180
  dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs 27.94 kB │ gzip: 6.36 kB
178
181
 
179
- ✓ built in 126ms
182
+ ✓ built in 191ms
180
183
  [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
181
184
  [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
182
185
  [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.12.2 build:tsc
2
+ > @prosopo/provider@5.13.0 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 3:29:13 PM - Projects in this build:
5
+ 9:06:33 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
- 3:29:14 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
31
+ 9:06:33 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
- 3:29:14 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
33
+ 9:06:33 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
- 3:29:14 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/logger.ts' is older than output '../logger/tsconfig.tsbuildinfo'
35
+ 9:06:33 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
- 3:29:14 PM - 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'
37
+ 9:06:33 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
- 3:29:14 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
39
+ 9:06:33 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
- 3:29:14 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
41
+ 9:06:33 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
- 3:29:14 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
43
+ 9:06:33 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
- 3:29:14 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
45
+ 9:06:33 AM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
46
46
 
47
- 3:29:14 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/index.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
47
+ 9:06:33 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
- 3:29:14 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'
49
+ 9:06:33 AM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/redisClient.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
50
50
 
51
- 3:29:14 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
51
+ 9:06:33 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
- 3:29:14 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
53
+ 9:06:33 AM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
54
54
 
55
- 3:29:14 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'
55
+ 9:06:33 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
- 3:29:14 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/unit/captchaLabel.unit.test.ts' is older than output '../database/tsconfig.tsbuildinfo'
57
+ 9:06:33 AM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/unit/captchaLabel.unit.test.ts' is older than output '../database/tsconfig.tsbuildinfo'
58
58
 
59
- 3:29:14 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
59
+ 9:06:33 AM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
60
60
 
61
- 3:29:14 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/tests/typesEnv.test-d.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
61
+ 9:06:33 AM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/index.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
62
62
 
63
- 3:29:14 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/index.ts' is older than output '../env/tsconfig.tsbuildinfo'
63
+ 9:06:33 AM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/env.ts' is older than output '../env/tsconfig.tsbuildinfo'
64
64
 
65
- 3:29:14 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'
65
+ 9:06:33 AM - Project '../api-express-router/tsconfig.json' is up to date because newest input '../api-express-router/src/tests/unit/testDoubles.ts' is older than output '../api-express-router/tsconfig.tsbuildinfo'
66
66
 
67
- 3:29:14 PM - Project '../captcha-severity/tsconfig.json' is up to date because newest input '../captcha-severity/src/index.ts' is older than output '../captcha-severity/tsconfig.tsbuildinfo'
67
+ 9:06:33 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
- 3:29:14 PM - Project '../datasets/tsconfig.json' is up to date because newest input '../datasets/src/tests/dataset.unit.test.ts' is older than output '../datasets/tsconfig.tsbuildinfo'
69
+ 9:06:33 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
- 3:29:14 PM - 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'
71
+ 9:06:33 AM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
72
72
 
73
- 3:29:14 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'
73
+ 9:06:33 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
- 3:29:14 PM - 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'
75
+ 9:06:33 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
- 3:29:14 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
77
+ 9:06:33 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
78
78
 
79
- 3:29:14 PM - Building project '/home/runner/work/captcha/captcha/packages/provider/tsconfig.json'...
79
+ 9:06:33 AM - Building project '/home/runner/work/captcha/captcha/packages/provider/tsconfig.json'...
80
80
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/provider@5.12.2 build
2
+ > @prosopo/provider@5.13.0 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/provider@5.12.2 build:cross-env
6
+ > @prosopo/provider@5.13.0 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
  vite v8.1.5 building ssr environment for production...
64
64
  Bundle build started
65
65
  
66
- ✓ 113 modules transformed.
66
+ ✓ 116 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
@@ -85,6 +85,7 @@ dist/api/dnsEventUrl.js 0.80 k
85
85
  dist/api/ja4.js 0.80 kB │ gzip: 0.44 kB
86
86
  dist/tasks/dataset/datasetTasks.js 0.85 kB │ gzip: 0.39 kB
87
87
  dist/tasks/powCaptcha/powTasksUtils.js 0.89 kB │ gzip: 0.46 kB
88
+ dist/api/captcha/assetSeal.js 0.91 kB │ gzip: 0.50 kB
88
89
  dist/api/headerCheckMiddleware.js 0.91 kB │ gzip: 0.43 kB
89
90
  dist/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.js 0.95 kB │ gzip: 0.51 kB
90
91
  dist/api/admin/apiRegisterSiteKeyEndpoint.js 1.00 kB │ gzip: 0.46 kB
@@ -105,7 +106,6 @@ dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js 1.27 k
105
106
  dist/api/admin/apiRemoveDecisionMachineEndpoint.js 1.29 kB │ gzip: 0.51 kB
106
107
  dist/tasks/dataset/datasetTasksUtils.js 1.30 kB │ gzip: 0.48 kB
107
108
  dist/api/assetDocument.js 1.36 kB │ gzip: 0.75 kB
108
- dist/compositeIpAddress.js 1.36 kB │ gzip: 0.55 kB
109
109
  dist/tasks/detection/assignSecret.js 1.42 kB │ gzip: 0.74 kB
110
110
  dist/utils/clientMetaData.js 1.42 kB │ gzip: 0.72 kB
111
111
  dist/api/admin/apiGetAllDecisionMachinesEndpoint.js 1.48 kB │ gzip: 0.57 kB
@@ -121,15 +121,16 @@ dist/api/admin/apiUpdateDecisionMachineEndpoint.js 1.68 k
121
121
  dist/utils/honeypot/phraseBank.js 1.69 kB │ gzip: 0.84 kB
122
122
  dist/api/handshakeTimingMiddleware.js 1.75 kB │ gzip: 0.69 kB
123
123
  dist/tasks/spam/updateSpamEmailDomains.js 1.87 kB │ gzip: 0.77 kB
124
- dist/api/captcha/signedAssetsResolver.js 1.89 kB │ gzip: 0.94 kB
125
124
  dist/api/admin/apiClearAllCountersEndpoint.js 1.89 kB │ gzip: 0.76 kB
126
125
  dist/tasks/frictionless/ipMatch.js 1.98 kB │ gzip: 1.02 kB
126
+ dist/api/captcha/signedAssetsResolver.js 2.08 kB │ gzip: 0.98 kB
127
127
  dist/migrations/frictionlessLadder.js 2.12 kB │ gzip: 0.93 kB
128
128
  dist/tasks/puzzle/stratifiedSampler.js 2.14 kB │ gzip: 1.07 kB
129
129
  dist/tasks/frictionless/frictionlessTasksUtils.js 2.16 kB │ gzip: 1.09 kB
130
130
  dist/api/captcha/maintenanceModeResponses.js 2.16 kB │ gzip: 0.73 kB
131
131
  dist/tasks/frictionless/routingMachine.js 2.20 kB │ gzip: 0.93 kB
132
132
  dist/tasks/captchaTypeSelection.js 2.22 kB │ gzip: 1.03 kB
133
+ dist/api/captcha/sealedAssetsResolver.js 2.26 kB │ gzip: 0.97 kB
133
134
  dist/utils/dns.js 2.36 kB │ gzip: 0.95 kB
134
135
  dist/api/admin/apiDnsEventEndpoint.js 2.43 kB │ gzip: 0.96 kB
135
136
  dist/api/public.js 2.45 kB │ gzip: 0.98 kB
@@ -139,8 +140,10 @@ dist/api/captcha/submitPuzzleCaptchaSolution.js 2.55 k
139
140
  dist/api/forwardVerify.js 2.59 kB │ gzip: 1.10 kB
140
141
  dist/api/captcha/submitImageCaptchaSolution.js 2.59 kB │ gzip: 1.00 kB
141
142
  dist/api/admin/apiAdminRoutesProvider.js 2.78 kB │ gzip: 0.55 kB
142
- dist/index.js 2.92 kB │ gzip: 0.80 kB
143
+ dist/index.js 2.95 kB │ gzip: 0.81 kB
144
+ dist/compositeIpAddress.js 3.15 kB │ gzip: 1.34 kB
143
145
  dist/tasks/detection/getBotScore.js 3.29 kB │ gzip: 1.32 kB
146
+ dist/api/captcha/assetSealFormat.js 3.38 kB │ gzip: 1.34 kB
144
147
  dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js 3.39 kB │ gzip: 1.32 kB
145
148
  dist/api/captcha/assignDetectorBundle.js 3.40 kB │ gzip: 1.34 kB
146
149
  dist/api/domainMiddleware.js 3.52 kB │ gzip: 1.22 kB
@@ -159,7 +162,7 @@ dist/tasks/dnsEvent/enrichDnsEvent.js 4.71 k
159
162
  dist/tasks/detection/decoderPool.js 5.34 kB │ gzip: 2.02 kB
160
163
  dist/util/usageCounters.js 5.65 kB │ gzip: 2.01 kB
161
164
  dist/api/captcha/getPoWCaptchaChallenge.js 6.09 kB │ gzip: 1.83 kB
162
- dist/api/captcha/getImageCaptchaChallenge.js 6.51 kB │ gzip: 1.99 kB
165
+ dist/api/captcha/getImageCaptchaChallenge.js 6.61 kB │ gzip: 2.00 kB
163
166
  dist/api/captcha/getPuzzleCaptchaChallenge.js 6.84 kB │ gzip: 1.97 kB
164
167
  dist/api/healthzGeo.js 6.86 kB │ gzip: 2.68 kB
165
168
  dist/tasks/spam/checkTrafficFilter.js 7.16 kB │ gzip: 2.45 kB
@@ -176,11 +179,11 @@ dist/api/verify.js 15.12 k
176
179
  dist/tasks/frictionless/frictionlessTasks.js 17.80 kB │ gzip: 4.86 kB
177
180
  dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js 18.54 kB │ gzip: 4.48 kB
178
181
  dist/tasks/puzzleCaptcha/puzzleTasks.js 22.71 kB │ gzip: 5.12 kB
179
- dist/tasks/captchaManager.js 23.44 kB │ gzip: 7.03 kB
180
- dist/tasks/powCaptcha/powTasks.js 23.61 kB │ gzip: 5.97 kB
182
+ dist/tasks/captchaManager.js 24.12 kB │ gzip: 7.34 kB
183
+ dist/tasks/powCaptcha/powTasks.js 24.13 kB │ gzip: 6.12 kB
181
184
  dist/tasks/imgCaptcha/imgCaptchaTasks.js 26.42 kB │ gzip: 6.30 kB
182
185
 
183
- ✓ built in 127ms
186
+ ✓ built in 484ms
184
187
  [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
185
188
  [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
186
189
  [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,74 @@
1
1
  # @prosopo/provider
2
2
 
3
+ ## 5.13.0
4
+ ### Minor Changes
5
+
6
+ - 85a1bb9: Seal captcha image paths into opaque URLs, opened by a CDN edge script.
7
+
8
+ An image URL used to say which image it was: `https://cdn.example.net/dataset/images/abc.webp`. Signed URLs already stop a harvested URL being refetched forever, but the path stays in plain sight, and the path is a stable identifier for the image behind it — which makes it a usable key for caching answers between sessions.
9
+
10
+ The path is now AES-256-GCM sealed, with an expiry, into an opaque blob drawn fresh every time:
11
+
12
+ ```
13
+ https://cdn.example.net/s/AgHk1n...Qx9.webp
14
+ ```
15
+
16
+ The edge script opens it, puts the canonical path back on the request, and the CDN serves the one object that path names. The same image therefore has a different URL in every session, with nothing in the URL to group those together, and there is still only one cached copy and one stored object.
17
+
18
+ Sealing happens strictly below `item.data`. The item hash, the captchaId and the datasetId are untouched, so nothing about the dataset or how a solution is verified changes.
19
+
20
+ The provider seals with `node:crypto`, because `AssetsResolver.resolveAsset` is synchronous and every WebCrypto call returns a promise; the edge opens with WebCrypto, because that is what its runtime has. The wire format, the validation and the base64url alphabet live in one module both ends import, and a test seals with one end and opens with the other so the two cannot drift.
21
+
22
+ Inert unless its key is configured, since a sealed URL is unservable until the matching edge script is live. Configured, it takes precedence over the signed resolver; leaving the signing key in place keeps that as the fallback for any zone not yet moved over. More than one key opens at a time, so keys can be rotated without a flag day. `npm run -w @prosopo/provider build:edge` emits the edge script as a single file. Rollout order, environment variables and rotation are documented for operators outside this repository.
23
+
24
+ Test coverage: 51 unit tests over the wire format, the sealer, the resolver and the edge handler — round trip, tamper, truncation, expiry at the boundary, swapped key id, rotation across two live keys, path traversal and prefix confinement, URL shape and per-call uniqueness, passthrough of requests that are not sealed, idempotency when the handler runs at both hooks, and the provider-seals/edge-opens interop.
25
+
26
+ ### Patch Changes
27
+
28
+ - 4c9b84b: Escalate a PoW solve to an image captcha when it arrives from a different address than the challenge.
29
+
30
+ A PoW challenge is bound to the user account and the site key and to nothing about where the request came from, so a solved challenge can be carried to any host that wants a free pass. The issuing address is already on the record, so binding to it costs nothing: `verifyPowCaptchaSolution` now compares it against the address submitting the solve and escalates when they differ, under a new `IP_CHANGED` reason.
31
+
32
+ Escalation, not denial. A phone handing off between towers mid-solve is a real user and should pay a picture rather than be turned away. For the same reason IPv6 is judged on the /64 alone — the interface identifier in the low 64 bits rotates by design under RFC 8981, several times a day on one unchanged connection — and an address we could not read counts as unchanged.
33
+
34
+ Only applies where a session is linked, since escalation carries the originating session's risk profile forward. Missing coordinates still takes precedence as the reported reason when both fire.
35
+ - 2cca36e: Report a bot score of zero to Pro and Enterprise instead of dropping the field.
36
+
37
+ `canClientSeeScore` tested `score && tier && tier !== Tier.Free`. A session with nothing wrong with it scores 0, which is falsy, so `score` was omitted from the siteverify response for exactly those users: a paying customer got a score for every suspicious visitor and no score at all for their cleanest ones, which reads as "no score available" rather than "no risk".
38
+
39
+ Invisible in production today because `Math.random() * 0.3` is added to every score, making an exact 0 all but impossible. Removing that noise — captcha-private#4433, where this was found — is what would have exposed it.
40
+
41
+ The function also returned `number | boolean | undefined` from its `&&` chain; it now returns `boolean`.
42
+ - Updated dependencies [4c9b84b]
43
+ - Updated dependencies [f13bea8]
44
+ - @prosopo/types@5.10.1
45
+ - @prosopo/load-balancer@2.11.0
46
+ - @prosopo/api@4.3.4
47
+ - @prosopo/api-express-router@3.1.94
48
+ - @prosopo/database@4.0.40
49
+ - @prosopo/datasets@3.1.90
50
+ - @prosopo/env@3.6.63
51
+ - @prosopo/ipinfo@0.4.9
52
+ - @prosopo/keyring@2.9.96
53
+ - @prosopo/types-database@5.6.4
54
+ - @prosopo/types-env@2.11.9
55
+ - @prosopo/user-access-policy@3.14.10
56
+
57
+ ## 5.12.3
58
+ ### Patch Changes
59
+
60
+ - aed164d: Make asset signing survive contact with a CDN that actually enforces it.
61
+
62
+ Signing image URLs is optional and has been off in practice, so two paths that only break when a zone starts checking tokens have never been exercised. Both are fixed here, so enabling enforcement is a config change rather than a config change plus an incident.
63
+
64
+ **A dataset could not be imported.** Hashing an item downloads the image from the URL stored in the dataset, and that URL is the canonical, unsigned one. Against an enforcing zone every one of those downloads is rejected, so a dataset becomes impossible to import on exactly the configuration it is meant to be served from. `downloadImage` now signs the URL when a signing key is configured, and leaves it alone when one is not.
65
+
66
+ **A failed image never recovered.** The widget retried a broken image by appending a cache-busting query parameter. A token is a signature over the query string, so on a signed URL that parameter invalidates it and every retry is rejected — a transient failure turned permanent. The retry now re-requests the signed URL unchanged, and keeps the cache-buster for unsigned URLs, where it is still worth having and costs nothing.
67
+
68
+ The token scheme itself now lives in one place, `@prosopo/datasets`, rather than being written out twice. The provider keeps its synchronous implementation, because `resolveAsset` cannot await, but both ends build the string to hash and encode the result through the same helpers.
69
+ - Updated dependencies [aed164d]
70
+ - @prosopo/datasets@3.1.89
71
+
3
72
  ## 5.12.2
4
73
  ### Patch Changes
5
74
 
@@ -0,0 +1,15 @@
1
+ export interface SealAssetPathParams {
2
+ readonly path: string;
3
+ readonly key: Uint8Array;
4
+ readonly keyId: number;
5
+ readonly expiresAtSeconds: number;
6
+ }
7
+ export declare const sealAssetPath: (params: SealAssetPathParams) => string;
8
+ export interface UnsealAssetPathParams {
9
+ readonly blob: string;
10
+ readonly keys: ReadonlyMap<number, Uint8Array>;
11
+ readonly nowSeconds: number;
12
+ readonly requiredPathPrefix?: string;
13
+ }
14
+ export declare const unsealAssetPath: (params: UnsealAssetPathParams) => string | undefined;
15
+ //# sourceMappingURL=assetSeal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetSeal.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/assetSeal.ts"],"names":[],"mappings":"AAsCA,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,WAAY,mBAAmB,KAAG,MAqB3D,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,eAAO,MAAM,eAAe,WACnB,qBAAqB,KAC3B,MAAM,GAAG,SAiBX,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { additionalData, encodeEnvelope, encodePayload, isSafeAssetPath } from "./assetSealFormat.js";
2
+ import { createCipheriv, randomBytes } from "node:crypto";
3
+ //#region src/api/captcha/assetSeal.ts
4
+ var CIPHER = "aes-256-gcm";
5
+ var GCM_OPTIONS = { authTagLength: 16 };
6
+ var sealAssetPath = (params) => {
7
+ if (!isSafeAssetPath(params.path)) throw new Error(`Refusing to seal an unusable asset path: ${params.path}`);
8
+ const iv = randomBytes(12);
9
+ const cipher = createCipheriv(CIPHER, params.key, iv, GCM_OPTIONS);
10
+ cipher.setAAD(additionalData(params.keyId));
11
+ const ciphertext = Buffer.concat([cipher.update(encodePayload({
12
+ expiresAtSeconds: params.expiresAtSeconds,
13
+ path: params.path
14
+ })), cipher.final()]);
15
+ return encodeEnvelope({
16
+ keyId: params.keyId,
17
+ iv: new Uint8Array(iv),
18
+ sealed: new Uint8Array(Buffer.concat([ciphertext, cipher.getAuthTag()]))
19
+ });
20
+ };
21
+ //#endregion
22
+ export { sealAssetPath };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetSeal.js","sourceRoot":"","sources":["../../../src/api/captcha/assetSeal.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACN,QAAQ,EAER,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,GACf,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,GAAG,aAAa,CAAC;AAC7B,MAAM,SAAS,GAAG,EAAE,CAAC;AASrB,MAAM,WAAW,GAAG,EAAE,aAAa,EAAE,SAAS,EAAW,CAAC;AAS1D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA2B,EAAU,EAAE;IACpE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,4CAA4C,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;IACnE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,MAAM,CAAC,MAAM,CACZ,aAAa,CAAC;YACb,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,IAAI,EAAE,MAAM,CAAC,IAAI;SACjB,CAAC,CACF;QACD,MAAM,CAAC,KAAK,EAAE;KACd,CAAC,CAAC;IACH,OAAO,cAAc,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,EAAE,EAAE,IAAI,UAAU,CAAC,EAAE,CAAC;QACtB,MAAM,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;KACxE,CAAC,CAAC;AACJ,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,MAA6B,EACR,EAAE;IACvB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACjD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,gBAAgB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/D,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,kBAAkB,CAAC;QAC9D,CAAC,CAAC,OAAO,CAAC,IAAI;QACd,CAAC,CAAC,SAAS,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,CACZ,MAAkB,EAClB,EAAc,EACd,GAAe,EACf,KAAa,EACe,EAAE;IAC9B,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAChE,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC/B,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;YAC9D,QAAQ,CAAC,KAAK,EAAE;SAChB,CAAC,CAAC;QACH,OAAO,aAAa,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ export declare const SEAL_VERSION = 1;
2
+ export declare const IV_BYTES = 12;
3
+ export declare const MAX_ASSET_PATH_LENGTH = 512;
4
+ export declare const SEAL_KEY_BYTES = 32;
5
+ export interface SealEnvelope {
6
+ readonly keyId: number;
7
+ readonly iv: Uint8Array;
8
+ readonly sealed: Uint8Array;
9
+ }
10
+ export interface SealedPayload {
11
+ readonly expiresAtSeconds: number;
12
+ readonly path: string;
13
+ }
14
+ export declare const toBase64Url: (bytes: Uint8Array) => string;
15
+ export declare const fromBase64Url: (value: string) => Uint8Array | undefined;
16
+ export declare const additionalData: (keyId: number) => Uint8Array;
17
+ export declare const encodeEnvelope: (envelope: SealEnvelope) => string;
18
+ export declare const decodeEnvelope: (blob: string) => SealEnvelope | undefined;
19
+ export declare const encodePayload: (payload: SealedPayload) => Uint8Array;
20
+ export declare const decodePayload: (bytes: Uint8Array) => SealedPayload | undefined;
21
+ export declare const isSafeAssetPath: (path: string, requiredPrefix?: string) => boolean;
22
+ export declare const parseSealKeys: (spec: string) => Map<number, Uint8Array>;
23
+ //# sourceMappingURL=assetSealFormat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetSealFormat.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/assetSealFormat.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,eAAO,MAAM,QAAQ,KAAK,CAAC;AAM3B,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAIzC,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAKD,eAAO,MAAM,WAAW,UAAW,UAAU,KAAG,MAS/C,CAAC;AAEF,eAAO,MAAM,aAAa,UAAW,MAAM,KAAG,UAAU,GAAG,SAmB1D,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,MAAM,KAAG,UACT,CAAC;AAEvC,eAAO,MAAM,cAAc,aAAc,YAAY,KAAG,MAQvD,CAAC;AAEF,eAAO,MAAM,cAAc,SAAU,MAAM,KAAG,YAAY,GAAG,SAiB5D,CAAC;AAEF,eAAO,MAAM,aAAa,YAAa,aAAa,KAAG,UAMtD,CAAC;AAEF,eAAO,MAAM,aAAa,UAAW,UAAU,KAAG,aAAa,GAAG,SAajE,CAAC;AAEF,eAAO,MAAM,eAAe,SACrB,MAAM,mBACK,MAAM,KACrB,OAYF,CAAC;AAEF,eAAO,MAAM,aAAa,SAAU,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAiClE,CAAC"}
@@ -0,0 +1,87 @@
1
+ var AAD_BYTES = 2;
2
+ var EXPIRY_BYTES = 4;
3
+ var MAX_KEY_ID = 255;
4
+ var BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;
5
+ var textEncoder = new TextEncoder();
6
+ var textDecoder = new TextDecoder("utf-8", { fatal: true });
7
+ var toBase64Url = (bytes) => {
8
+ let binary = "";
9
+ for (const byte of bytes) binary += String.fromCharCode(byte);
10
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
11
+ };
12
+ var fromBase64Url = (value) => {
13
+ if (!BASE64URL_PATTERN.test(value)) return;
14
+ const normalised = value.replace(/-/g, "+").replace(/_/g, "/");
15
+ const padded = normalised.padEnd(normalised.length + (4 - normalised.length % 4) % 4, "=");
16
+ try {
17
+ const binary = atob(padded);
18
+ const bytes = new Uint8Array(binary.length);
19
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
20
+ return bytes;
21
+ } catch {
22
+ return;
23
+ }
24
+ };
25
+ var additionalData = (keyId) => new Uint8Array([1, keyId]);
26
+ var encodeEnvelope = (envelope) => {
27
+ const bytes = new Uint8Array(AAD_BYTES + envelope.iv.length + envelope.sealed.length);
28
+ bytes.set(additionalData(envelope.keyId), 0);
29
+ bytes.set(envelope.iv, AAD_BYTES);
30
+ bytes.set(envelope.sealed, AAD_BYTES + envelope.iv.length);
31
+ return toBase64Url(bytes);
32
+ };
33
+ var decodeEnvelope = (blob) => {
34
+ const bytes = fromBase64Url(blob);
35
+ if (!bytes || bytes.length <= 14) return;
36
+ if (bytes[0] !== 1) return;
37
+ const keyId = bytes[1];
38
+ if (void 0 === keyId) return;
39
+ return {
40
+ keyId,
41
+ iv: bytes.slice(AAD_BYTES, 14),
42
+ sealed: bytes.slice(14)
43
+ };
44
+ };
45
+ var encodePayload = (payload) => {
46
+ const path = textEncoder.encode(payload.path);
47
+ const bytes = new Uint8Array(EXPIRY_BYTES + path.length);
48
+ new DataView(bytes.buffer).setUint32(0, payload.expiresAtSeconds, false);
49
+ bytes.set(path, EXPIRY_BYTES);
50
+ return bytes;
51
+ };
52
+ var decodePayload = (bytes) => {
53
+ if (bytes.length <= EXPIRY_BYTES) return;
54
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
55
+ try {
56
+ return {
57
+ expiresAtSeconds: view.getUint32(0, false),
58
+ path: textDecoder.decode(bytes.subarray(EXPIRY_BYTES))
59
+ };
60
+ } catch {
61
+ return;
62
+ }
63
+ };
64
+ var isSafeAssetPath = (path, requiredPrefix) => {
65
+ if (!path.startsWith("/") || path.length > 512) return false;
66
+ if (path.includes("..") || path.includes("//")) return false;
67
+ if (/[\u0000-\u001f\u007f]/.test(path)) return false;
68
+ return void 0 === requiredPrefix || path.startsWith(requiredPrefix);
69
+ };
70
+ var parseSealKeys = (spec) => {
71
+ const keys = /* @__PURE__ */ new Map();
72
+ for (const entry of spec.split(",")) {
73
+ const trimmed = entry.trim();
74
+ if ("" === trimmed) continue;
75
+ const separator = trimmed.indexOf(":");
76
+ if (separator <= 0) throw new Error("Malformed seal key entry: expected \"keyId:base64key\"");
77
+ const keyId = Number(trimmed.slice(0, separator));
78
+ if (!Number.isInteger(keyId) || keyId < 0 || keyId > MAX_KEY_ID) throw new Error(`Seal key id must be an integer in [0, ${MAX_KEY_ID}]`);
79
+ const key = fromBase64Url(trimmed.slice(separator + 1).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""));
80
+ if (!key || key.length !== 32) throw new Error(`Seal key ${keyId} must be 32 base64-encoded bytes`);
81
+ keys.set(keyId, key);
82
+ }
83
+ if (0 === keys.size) throw new Error("No seal keys configured");
84
+ return keys;
85
+ };
86
+ //#endregion
87
+ export { additionalData, decodeEnvelope, decodePayload, encodeEnvelope, encodePayload, fromBase64Url, isSafeAssetPath, parseSealKeys, toBase64Url };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetSealFormat.js","sourceRoot":"","sources":["../../../src/api/captcha/assetSealFormat.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getImageCaptchaChallenge.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/getImageCaptchaChallenge.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;8BAgBnD,mBAAmB,0BACA,kBAAkB,WAGpC,OAAO,GAAG,gBAAgB,OAC1B,QAAQ,QACP,YAAY;AAPpB,wBAqTG"}
1
+ {"version":3,"file":"getImageCaptchaChallenge.d.ts","sourceRoot":"","sources":["../../../src/api/captcha/getImageCaptchaChallenge.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;8BAiBnD,mBAAmB,0BACA,kBAAkB,WAGpC,OAAO,GAAG,gBAAgB,OAC1B,QAAQ,QACP,YAAY;AAPpB,wBAmTG"}
@@ -7,6 +7,7 @@ import { isReservedTestSiteKey } from "../testSiteKey.js";
7
7
  import { normalizeRequestIp } from "../../utils/normalizeRequestIp.js";
8
8
  import { buildImageMaintenanceResponse } from "./maintenanceModeResponses.js";
9
9
  import { applyTrafficFilterAtRequestTime } from "./trafficFilterRequestTime.js";
10
+ import { getSealedAssetsResolver } from "./sealedAssetsResolver.js";
10
11
  import { getSignedAssetsResolver } from "./signedAssetsResolver.js";
11
12
  import { ProsopoApiError } from "@prosopo/common";
12
13
  import { ApiParams, CaptchaRequestBody, CaptchaType, SimdReadingsStage, clampImageRounds } from "@prosopo/types";
@@ -111,7 +112,7 @@ var getImageCaptchaChallenge_default = (env, userAccessRulesStorage) => async (r
111
112
  }));
112
113
  });
113
114
  const taskData = await tasks.imgCaptchaManager.getRandomCaptchasAndRequestHash(datasetId, user, ipAddress, captchaConfig, clientRecord.settings.imageThreshold ?? .8, validSessionId, req.ipInfo);
114
- const assetsResolver = getSignedAssetsResolver(ipAddress.toString()) ?? env.assetsResolver;
115
+ const assetsResolver = getSealedAssetsResolver() ?? getSignedAssetsResolver(ipAddress.toString()) ?? env.assetsResolver;
115
116
  const captchaResponse = {
116
117
  [ApiParams.status]: "ok",
117
118
  [ApiParams.captchas]: taskData.captchas.map((captcha) => ({