@prosopo/provider 4.15.14 → 4.15.16

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 (232) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +106 -106
  2. package/.turbo/turbo-build$colon$tsc.log +24 -24
  3. package/.turbo/turbo-build.log +107 -104
  4. package/CHANGELOG.md +63 -0
  5. package/dist/_virtual/_rolldown/runtime.js +3 -0
  6. package/dist/api/admin/apiAdminRoutesProvider.js +27 -46
  7. package/dist/api/admin/apiClearAllCountersEndpoint.js +62 -57
  8. package/dist/api/admin/apiDnsEventEndpoint.js +79 -92
  9. package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js +43 -45
  10. package/dist/api/admin/apiGetDecisionMachineEndpoint.js +40 -40
  11. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +23 -22
  12. package/dist/api/admin/apiRegisterSiteKeysEndpoint.js +26 -30
  13. package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js +35 -37
  14. package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js +40 -40
  15. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +1 -1
  16. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js +29 -31
  17. package/dist/api/admin/apiRemoveSiteKeyEndpoint.js +33 -29
  18. package/dist/api/admin/apiRemoveSiteKeysEndpoint.js +32 -31
  19. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +43 -35
  20. package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js +43 -63
  21. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js +36 -35
  22. package/dist/api/admin/createApiAdminRoutesProvider.js +6 -8
  23. package/dist/api/blacklistRequestInspector.js +285 -377
  24. package/dist/api/block.js +17 -30
  25. package/dist/api/captcha/checkSpamEmail.js +88 -98
  26. package/dist/api/captcha/contextAwareValidation.js +21 -15
  27. package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js +126 -140
  28. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js +11 -12
  29. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +236 -299
  30. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decryptSimdReadings.js +10 -13
  31. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +336 -462
  32. package/dist/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.js +17 -14
  33. package/dist/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.js +27 -27
  34. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +42 -63
  35. package/dist/api/captcha/getFrictionlessCaptchaChallenge.js +2 -4
  36. package/dist/api/captcha/getImageCaptchaChallenge.js +136 -207
  37. package/dist/api/captcha/getPoWCaptchaChallenge.js +128 -198
  38. package/dist/api/captcha/getPuzzleCaptchaChallenge.js +132 -201
  39. package/dist/api/captcha/maintenanceModeResponses.js +38 -47
  40. package/dist/api/captcha/submitImageCaptchaSolution.js +75 -101
  41. package/dist/api/captcha/submitPoWCaptchaSolution.js +137 -207
  42. package/dist/api/captcha/submitPuzzleCaptchaSolution.js +73 -105
  43. package/dist/api/captcha.js +76 -58
  44. package/dist/api/dnsEventUrl.js +20 -22
  45. package/dist/api/domainMiddleware.js +104 -115
  46. package/dist/api/forwardVerify.js +62 -48
  47. package/dist/api/handshakeTimingMiddleware.js +43 -62
  48. package/dist/api/hardBlockVerdictCache.js +114 -117
  49. package/dist/api/headerCheckMiddleware.js +34 -34
  50. package/dist/api/ignoreMiddleware.js +13 -15
  51. package/dist/api/ipInfoMiddleware.js +17 -19
  52. package/dist/api/ja4.js +149 -188
  53. package/dist/api/ja4Middleware.js +39 -54
  54. package/dist/api/metrics.js +245 -257
  55. package/dist/api/public.js +52 -54
  56. package/dist/api/robotsMiddleware.js +10 -10
  57. package/dist/api/startProviderApi.js +205 -232
  58. package/dist/api/testSiteKey.js +16 -16
  59. package/dist/api/validateAddress.js +23 -21
  60. package/dist/api/verify.js +334 -377
  61. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  62. package/dist/cjs/api/admin/apiAdminRoutesProvider.cjs +40 -59
  63. package/dist/cjs/api/admin/apiClearAllCountersEndpoint.cjs +63 -58
  64. package/dist/cjs/api/admin/apiDnsEventEndpoint.cjs +82 -93
  65. package/dist/cjs/api/admin/apiGetAllDecisionMachinesEndpoint.cjs +46 -48
  66. package/dist/cjs/api/admin/apiGetDecisionMachineEndpoint.cjs +41 -41
  67. package/dist/cjs/api/admin/apiRegisterSiteKeyEndpoint.cjs +25 -24
  68. package/dist/cjs/api/admin/apiRegisterSiteKeysEndpoint.cjs +28 -32
  69. package/dist/cjs/api/admin/apiRemoveAllDecisionMachinesEndpoint.cjs +38 -40
  70. package/dist/cjs/api/admin/apiRemoveDecisionMachineEndpoint.cjs +41 -41
  71. package/dist/cjs/api/admin/apiRemoveDetectorKeyEndpoint.cjs +31 -33
  72. package/dist/cjs/api/admin/apiRemoveSiteKeyEndpoint.cjs +35 -31
  73. package/dist/cjs/api/admin/apiRemoveSiteKeysEndpoint.cjs +34 -33
  74. package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +45 -35
  75. package/dist/cjs/api/admin/apiUpdateDecisionMachineEndpoint.cjs +45 -65
  76. package/dist/cjs/api/admin/apiUpdateDetectorKeyEndpoint.cjs +38 -37
  77. package/dist/cjs/api/admin/createApiAdminRoutesProvider.cjs +7 -8
  78. package/dist/cjs/api/blacklistRequestInspector.cjs +288 -376
  79. package/dist/cjs/api/block.cjs +18 -30
  80. package/dist/cjs/api/captcha/checkSpamEmail.cjs +90 -100
  81. package/dist/cjs/api/captcha/contextAwareValidation.cjs +21 -14
  82. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs +125 -140
  83. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/constants.cjs +10 -10
  84. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +238 -301
  85. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decryptSimdReadings.cjs +9 -12
  86. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +349 -473
  87. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.cjs +18 -14
  88. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.cjs +26 -26
  89. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +42 -63
  90. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge.cjs +2 -3
  91. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +138 -208
  92. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +131 -200
  93. package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +135 -203
  94. package/dist/cjs/api/captcha/maintenanceModeResponses.cjs +38 -44
  95. package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +77 -102
  96. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +140 -209
  97. package/dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs +76 -107
  98. package/dist/cjs/api/captcha.cjs +79 -58
  99. package/dist/cjs/api/dnsEventUrl.cjs +20 -21
  100. package/dist/cjs/api/domainMiddleware.cjs +106 -117
  101. package/dist/cjs/api/forwardVerify.cjs +63 -49
  102. package/dist/cjs/api/handshakeTimingMiddleware.cjs +43 -61
  103. package/dist/cjs/api/hardBlockVerdictCache.cjs +114 -114
  104. package/dist/cjs/api/headerCheckMiddleware.cjs +34 -34
  105. package/dist/cjs/api/ignoreMiddleware.cjs +12 -14
  106. package/dist/cjs/api/ipInfoMiddleware.cjs +16 -18
  107. package/dist/cjs/api/ja4.cjs +149 -187
  108. package/dist/cjs/api/ja4Middleware.cjs +40 -53
  109. package/dist/cjs/api/metrics.cjs +229 -228
  110. package/dist/cjs/api/public.cjs +57 -57
  111. package/dist/cjs/api/robotsMiddleware.cjs +9 -9
  112. package/dist/cjs/api/startProviderApi.cjs +219 -237
  113. package/dist/cjs/api/testSiteKey.cjs +15 -14
  114. package/dist/cjs/api/validateAddress.cjs +24 -21
  115. package/dist/cjs/api/verify.cjs +338 -379
  116. package/dist/cjs/compositeIpAddress.cjs +40 -47
  117. package/dist/cjs/index.cjs +65 -71
  118. package/dist/cjs/pairs.cjs +31 -35
  119. package/dist/cjs/rules/lang.cjs +10 -14
  120. package/dist/cjs/schedulers/captchaScheduler.cjs +26 -32
  121. package/dist/cjs/schedulers/getClientList.cjs +35 -33
  122. package/dist/cjs/schedulers/setClientEntropy.cjs +35 -33
  123. package/dist/cjs/schedulers/updateSpamEmailDomains.cjs +39 -43
  124. package/dist/cjs/services/ipComparison.cjs +122 -119
  125. package/dist/cjs/tasks/captchaManager.cjs +407 -486
  126. package/dist/cjs/tasks/client/clientTasks.cjs +347 -470
  127. package/dist/cjs/tasks/dataset/datasetTasks.cjs +25 -29
  128. package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +16 -32
  129. package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +220 -307
  130. package/dist/cjs/tasks/detection/decodeBehavior.cjs +408 -317
  131. package/dist/cjs/tasks/detection/decodePayload.cjs +686 -468
  132. package/dist/cjs/tasks/detection/decodeSimd.cjs +462 -304
  133. package/dist/cjs/tasks/detection/getBotScore.cjs +37 -43
  134. package/dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs +88 -71
  135. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +348 -486
  136. package/dist/cjs/tasks/frictionless/frictionlessTasksUtils.cjs +13 -30
  137. package/dist/cjs/tasks/frictionless/routingMachine.cjs +71 -55
  138. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +555 -806
  139. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +22 -23
  140. package/dist/cjs/tasks/index.cjs +2 -4
  141. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +491 -687
  142. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +17 -29
  143. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +422 -591
  144. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasksUtils.cjs +8 -5
  145. package/dist/cjs/tasks/spam/checkSpamEmail.cjs +133 -141
  146. package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +118 -76
  147. package/dist/cjs/tasks/spam/evaluateEmailSpamRules.cjs +75 -84
  148. package/dist/cjs/tasks/spam/updateSpamEmailDomains.cjs +40 -56
  149. package/dist/cjs/tasks/tasks.cjs +107 -158
  150. package/dist/cjs/util/usageCounters.cjs +220 -211
  151. package/dist/cjs/util.cjs +329 -359
  152. package/dist/cjs/utils/devicePlatform.cjs +14 -8
  153. package/dist/cjs/utils/dns.cjs +68 -93
  154. package/dist/cjs/utils/hashUserAgent.cjs +14 -7
  155. package/dist/cjs/utils/hashUserIp.cjs +14 -6
  156. package/dist/cjs/utils/honeypot/encoders.cjs +74 -80
  157. package/dist/cjs/utils/honeypot/phraseBank.cjs +51 -44
  158. package/dist/cjs/utils/normalizeRequestIp.cjs +33 -25
  159. package/dist/compositeIpAddress.js +38 -46
  160. package/dist/index.js +12 -56
  161. package/dist/pairs.js +31 -37
  162. package/dist/rules/lang.js +11 -15
  163. package/dist/schedulers/captchaScheduler.js +25 -31
  164. package/dist/schedulers/getClientList.js +34 -32
  165. package/dist/schedulers/setClientEntropy.js +34 -32
  166. package/dist/schedulers/updateSpamEmailDomains.js +38 -42
  167. package/dist/services/ipComparison.js +122 -119
  168. package/dist/tasks/captchaManager.js +403 -483
  169. package/dist/tasks/client/clientTasks.js +343 -467
  170. package/dist/tasks/dataset/datasetTasks.js +24 -28
  171. package/dist/tasks/dataset/datasetTasksUtils.js +15 -31
  172. package/dist/tasks/decisionMachine/decisionMachineRunner.js +217 -306
  173. package/dist/tasks/detection/getBotScore.js +37 -43
  174. package/dist/tasks/dnsEvent/enrichDnsEvent.d.ts.map +1 -1
  175. package/dist/tasks/dnsEvent/enrichDnsEvent.js +88 -74
  176. package/dist/tasks/dnsEvent/enrichDnsEvent.js.map +1 -1
  177. package/dist/tasks/frictionless/frictionlessTasks.js +342 -479
  178. package/dist/tasks/frictionless/frictionlessTasksUtils.js +14 -32
  179. package/dist/tasks/frictionless/routingMachine.js +72 -56
  180. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +550 -801
  181. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +21 -22
  182. package/dist/tasks/index.js +1 -3
  183. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  184. package/dist/tasks/powCaptcha/powTasks.js +486 -682
  185. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  186. package/dist/tasks/powCaptcha/powTasksUtils.js +15 -28
  187. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
  188. package/dist/tasks/puzzleCaptcha/puzzleTasks.js +417 -586
  189. package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
  190. package/dist/tasks/puzzleCaptcha/puzzleTasksUtils.js +9 -6
  191. package/dist/tasks/spam/checkSpamEmail.js +133 -141
  192. package/dist/tasks/spam/checkTrafficFilter.d.ts +1 -0
  193. package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
  194. package/dist/tasks/spam/checkTrafficFilter.js +117 -77
  195. package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
  196. package/dist/tasks/spam/evaluateEmailSpamRules.js +75 -86
  197. package/dist/tasks/spam/updateSpamEmailDomains.js +36 -54
  198. package/dist/tasks/tasks.js +98 -150
  199. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +4 -1
  200. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +1 -1
  201. package/dist/tests/unit/api/block.unit.test.js +8 -4
  202. package/dist/tests/unit/api/block.unit.test.js.map +1 -1
  203. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js +8 -6
  204. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js.map +1 -1
  205. package/dist/tests/unit/api/forwardVerify.unit.test.js +3 -1
  206. package/dist/tests/unit/api/forwardVerify.unit.test.js.map +1 -1
  207. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +15 -7
  208. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
  209. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +24 -18
  210. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +1 -1
  211. package/dist/tests/unit/schedulers/getClientList.unit.test.js +19 -13
  212. package/dist/tests/unit/schedulers/getClientList.unit.test.js.map +1 -1
  213. package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js +19 -13
  214. package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js.map +1 -1
  215. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
  216. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +22 -16
  217. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
  218. package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js +140 -0
  219. package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js.map +1 -1
  220. package/dist/tests/unit/testUtils/mockProviderEnv.d.ts +7 -7
  221. package/dist/util/usageCounters.js +220 -212
  222. package/dist/util.d.ts.map +1 -1
  223. package/dist/util.js +327 -364
  224. package/dist/util.js.map +1 -1
  225. package/dist/utils/devicePlatform.js +15 -9
  226. package/dist/utils/dns.js +64 -77
  227. package/dist/utils/hashUserAgent.js +14 -7
  228. package/dist/utils/hashUserIp.js +14 -6
  229. package/dist/utils/honeypot/encoders.js +74 -80
  230. package/dist/utils/honeypot/phraseBank.js +49 -44
  231. package/dist/utils/normalizeRequestIp.js +34 -26
  232. package/package.json +24 -24
@@ -1,212 +1,143 @@
1
- "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const common = require("@prosopo/common");
4
- const types = require("@prosopo/types");
5
- const util = require("@prosopo/util");
6
- const tasks = require("../../tasks/tasks.cjs");
7
- const devicePlatform = require("../../utils/devicePlatform.cjs");
8
- const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
9
- const testSiteKey = require("../testSiteKey.cjs");
10
- const validateAddress = require("../validateAddress.cjs");
11
- const submitPoWCaptchaSolution = (env) => async (req, res, next) => {
12
- if (apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
13
- req.logger.info(() => ({
14
- msg: "Maintenance mode active - returning verified"
15
- }));
16
- const response = {
17
- status: "ok",
18
- verified: true
19
- };
20
- return res.json(response);
21
- }
22
- let parsed;
23
- const tasks$1 = new tasks.Tasks(env, req.logger);
24
- try {
25
- parsed = types.SubmitPowCaptchaSolutionBody.parse(req.body);
26
- } catch (err) {
27
- return next(
28
- new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
29
- context: { code: 400, error: err, body: req.body },
30
- i18n: req.i18n,
31
- logger: req.logger
32
- })
33
- );
34
- }
35
- const {
36
- challenge,
37
- signature,
38
- nonce,
39
- dapp,
40
- user,
41
- behavioralData,
42
- salt,
43
- simdReadings,
44
- clientMetaData,
45
- fingerprintProof
46
- } = parsed;
47
- validateAddress.validateSiteKey(dapp);
48
- validateAddress.validateAddr(user);
49
- const testVerdict = testSiteKey.resolveTestSiteKeyVerdict(dapp, req.logger);
50
- if (testVerdict !== null) {
51
- const response = {
52
- status: "ok",
53
- verified: testVerdict
54
- };
55
- return res.json(response);
56
- }
57
- try {
58
- const clientRecord = await tasks$1.db.getClientRecord(dapp);
59
- if (!clientRecord) {
60
- return next(
61
- new common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
62
- context: { code: 400, siteKey: dapp },
63
- i18n: req.i18n,
64
- logger: req.logger
65
- })
66
- );
67
- }
68
- const flatHeaders = util.flatten(req.headers);
69
- const userAgent = req.headers["user-agent"] ?? "";
70
- const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
71
- req.logger.info(() => ({
72
- msg: fingerprintProof ? "fingerprintProof detected" : "no fingerprintProof on PoW submission",
73
- data: {
74
- fingerprintProofPresent: fingerprintProof !== void 0,
75
- fingerprintProofBytes: fingerprintProof?.length ?? 0,
76
- challenge
77
- }
78
- }));
79
- tasks$1.powCaptchaManager.setPostPowContext({
80
- ip: req.ip || "",
81
- countryCode,
82
- // `false` here is a placeholder — `runPostPowRouting` overrides
83
- // isWebView with the value recorded on the originating session.
84
- platform: devicePlatform.derivePlatform(userAgent, false),
85
- raw: {
86
- headers: flatHeaders,
87
- userAgent,
88
- ...req.ja4 && { ja4: req.ja4 },
89
- ...fingerprintProof && { fingerprintProof },
90
- ...req.tcpToChelloUs !== void 0 && {
91
- tcpToChelloUs: req.tcpToChelloUs
92
- },
93
- ...req.chelloToHandshakeUs !== void 0 && {
94
- chelloToHandshakeUs: req.chelloToHandshakeUs
95
- }
96
- }
97
- });
98
- const persistedSolutionTimeout = clientRecord.settings.solutionTimeout;
99
- const submitWindowMs = persistedSolutionTimeout ?? clientRecord.settings.verifiedTimeout;
100
- const result = await tasks$1.powCaptchaManager.verifyPowCaptchaSolution(
101
- challenge,
102
- signature.provider.challenge,
103
- nonce,
104
- submitWindowMs,
105
- signature.user.timestamp,
106
- util.getIPAddress(req.ip || ""),
107
- flatHeaders,
108
- behavioralData,
109
- salt,
110
- simdReadings,
111
- clientMetaData
112
- );
113
- if (result.routingOutput) {
114
- req.logger.info(() => ({
115
- msg: "post-PoW routing decision",
116
- data: {
117
- routedCaptchaType: result.routingOutput?.captchaType,
118
- routingReason: result.routingOutput?.reason,
119
- challenge
120
- }
121
- }));
122
- }
123
- const escalation = await buildEscalation(tasks$1, result, challenge, {
124
- tcpToChelloUs: req.tcpToChelloUs,
125
- chelloToHandshakeUs: req.chelloToHandshakeUs
126
- });
127
- const response = {
128
- status: "ok",
129
- // On escalation the user is not done — they still need to clear
130
- // the follow-up image/puzzle challenge before we hand them a token.
131
- verified: escalation ? false : result.verified,
132
- ...escalation && { escalation }
133
- };
134
- return res.json(response);
135
- } catch (err) {
136
- req.logger.error(() => ({
137
- err,
138
- body: req.body,
139
- msg: "Error in PoW captcha solution submission"
140
- }));
141
- return next(
142
- new common.ProsopoApiError("API.BAD_REQUEST", {
143
- context: {
144
- code: 500,
145
- siteKey: req.body.dapp,
146
- error: err
147
- },
148
- i18n: req.i18n,
149
- logger: req.logger
150
- })
151
- );
152
- }
1
+ const require_validateAddress = require("../validateAddress.cjs");
2
+ const require_tasks = require("../../tasks/tasks.cjs");
3
+ const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
4
+ const require_devicePlatform = require("../../utils/devicePlatform.cjs");
5
+ const require_testSiteKey = require("../testSiteKey.cjs");
6
+ let _prosopo_common = require("@prosopo/common");
7
+ let _prosopo_types = require("@prosopo/types");
8
+ let _prosopo_util = require("@prosopo/util");
9
+ //#region src/api/captcha/submitPoWCaptchaSolution.ts
10
+ var submitPoWCaptchaSolution_default = (env) => async (req, res, next) => {
11
+ if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
12
+ req.logger.info(() => ({ msg: "Maintenance mode active - returning verified" }));
13
+ return res.json({
14
+ status: "ok",
15
+ verified: true
16
+ });
17
+ }
18
+ let parsed;
19
+ const tasks = new require_tasks.Tasks(env, req.logger);
20
+ try {
21
+ parsed = _prosopo_types.SubmitPowCaptchaSolutionBody.parse(req.body);
22
+ } catch (err) {
23
+ return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
24
+ context: {
25
+ code: 400,
26
+ error: err,
27
+ body: req.body
28
+ },
29
+ i18n: req.i18n,
30
+ logger: req.logger
31
+ }));
32
+ }
33
+ const { challenge, signature, nonce, dapp, user, behavioralData, salt, simdReadings, clientMetaData, fingerprintProof } = parsed;
34
+ require_validateAddress.validateSiteKey(dapp);
35
+ require_validateAddress.validateAddr(user);
36
+ const testVerdict = require_testSiteKey.resolveTestSiteKeyVerdict(dapp, req.logger);
37
+ if (testVerdict !== null) {
38
+ const response = {
39
+ status: "ok",
40
+ verified: testVerdict
41
+ };
42
+ return res.json(response);
43
+ }
44
+ try {
45
+ const clientRecord = await tasks.db.getClientRecord(dapp);
46
+ if (!clientRecord) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
47
+ context: {
48
+ code: 400,
49
+ siteKey: dapp
50
+ },
51
+ i18n: req.i18n,
52
+ logger: req.logger
53
+ }));
54
+ const flatHeaders = (0, _prosopo_util.flatten)(req.headers);
55
+ const userAgent = req.headers["user-agent"] ?? "";
56
+ const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
57
+ req.logger.info(() => ({
58
+ msg: fingerprintProof ? "fingerprintProof detected" : "no fingerprintProof on PoW submission",
59
+ data: {
60
+ fingerprintProofPresent: fingerprintProof !== void 0,
61
+ fingerprintProofBytes: fingerprintProof?.length ?? 0,
62
+ challenge
63
+ }
64
+ }));
65
+ tasks.powCaptchaManager.setPostPowContext({
66
+ ip: req.ip || "",
67
+ countryCode,
68
+ platform: require_devicePlatform.derivePlatform(userAgent, false),
69
+ raw: {
70
+ headers: flatHeaders,
71
+ userAgent,
72
+ ...req.ja4 && { ja4: req.ja4 },
73
+ ...fingerprintProof && { fingerprintProof },
74
+ ...req.tcpToChelloUs !== void 0 && { tcpToChelloUs: req.tcpToChelloUs },
75
+ ...req.chelloToHandshakeUs !== void 0 && { chelloToHandshakeUs: req.chelloToHandshakeUs }
76
+ }
77
+ });
78
+ const submitWindowMs = clientRecord.settings.solutionTimeout ?? clientRecord.settings.verifiedTimeout;
79
+ const result = await tasks.powCaptchaManager.verifyPowCaptchaSolution(challenge, signature.provider.challenge, nonce, submitWindowMs, signature.user.timestamp, (0, _prosopo_util.getIPAddress)(req.ip || ""), flatHeaders, behavioralData, salt, simdReadings, clientMetaData);
80
+ if (result.routingOutput) req.logger.info(() => ({
81
+ msg: "post-PoW routing decision",
82
+ data: {
83
+ routedCaptchaType: result.routingOutput?.captchaType,
84
+ routingReason: result.routingOutput?.reason,
85
+ challenge
86
+ }
87
+ }));
88
+ const escalation = await buildEscalation(tasks, result, challenge, {
89
+ tcpToChelloUs: req.tcpToChelloUs,
90
+ chelloToHandshakeUs: req.chelloToHandshakeUs
91
+ });
92
+ const response = {
93
+ status: "ok",
94
+ verified: escalation ? false : result.verified,
95
+ ...escalation && { escalation }
96
+ };
97
+ return res.json(response);
98
+ } catch (err) {
99
+ req.logger.error(() => ({
100
+ err,
101
+ body: req.body,
102
+ msg: "Error in PoW captcha solution submission"
103
+ }));
104
+ return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
105
+ context: {
106
+ code: 500,
107
+ siteKey: req.body.dapp,
108
+ error: err
109
+ },
110
+ i18n: req.i18n,
111
+ logger: req.logger
112
+ }));
113
+ }
153
114
  };
154
- const buildEscalation = async (tasks2, result, challenge, handshakeTiming) => {
155
- if (!result.verified || !result.routingOutput) return void 0;
156
- const routedType = result.routingOutput.captchaType;
157
- if (routedType !== types.CaptchaType.image && routedType !== types.CaptchaType.puzzle) {
158
- return void 0;
159
- }
160
- const powRecord = await tasks2.db.getPowCaptchaRecordByChallenge(challenge);
161
- if (!powRecord?.sessionId) return void 0;
162
- const originSession = await tasks2.db.getSessionRecordBySessionId(
163
- powRecord.sessionId
164
- );
165
- if (!originSession) return void 0;
166
- const routed = result.routingOutput;
167
- const selectionReason = routed.reason ?? originSession.reason;
168
- const newSession = await tasks2.frictionlessManager.createSession(
169
- originSession.token,
170
- originSession.score,
171
- originSession.threshold,
172
- originSession.scoreComponents,
173
- originSession.ipAddress,
174
- routed.captchaType,
175
- originSession.siteKey ?? powRecord.dappAccount,
176
- routed.captchaType === types.CaptchaType.image ? routed.solvedImagesCount ?? originSession.solvedImagesCount : void 0,
177
- void 0,
178
- originSession.userSitekeyIpHash,
179
- originSession.webView,
180
- originSession.iFrame,
181
- originSession.decryptedHeadHash,
182
- selectionReason,
183
- void 0,
184
- void 0,
185
- originSession.ipInfo,
186
- originSession.headers,
187
- originSession.mode,
188
- originSession.simdReadings,
189
- originSession.entropyMathRandomFingerprint,
190
- originSession.entropyCryptoFingerprint,
191
- originSession.entropyWallClockOffsetMs,
192
- originSession.entropyMathRandomFirst,
193
- originSession.currentUrl,
194
- handshakeTiming?.tcpToChelloUs,
195
- handshakeTiming?.chelloToHandshakeUs,
196
- true,
197
- originSession.iframeUrl,
198
- originSession.isProtect
199
- );
200
- if (tasks2.writeQueue) {
201
- await tasks2.writeQueue.cacheSessionEscalation(
202
- powRecord.sessionId,
203
- newSession.sessionId
204
- );
205
- }
206
- return {
207
- captchaType: routed.captchaType,
208
- sessionId: newSession.sessionId
209
- };
115
+ /**
116
+ * Translate the routing-machine output into an escalation by minting a fresh
117
+ * session of the chosen captcha type, carrying forward the originating
118
+ * session's risk profile (score, headers, IP, etc.). Returns undefined when
119
+ * the router decided to keep the user on PoW (i.e. no escalation needed).
120
+ *
121
+ * Exported for unit testing only — the handler above is the production entry
122
+ * point.
123
+ */
124
+ var buildEscalation = async (tasks, result, challenge, handshakeTiming) => {
125
+ if (!result.verified || !result.routingOutput) return void 0;
126
+ const routedType = result.routingOutput.captchaType;
127
+ if (routedType !== _prosopo_types.CaptchaType.image && routedType !== _prosopo_types.CaptchaType.puzzle) return;
128
+ const powRecord = await tasks.db.getPowCaptchaRecordByChallenge(challenge);
129
+ if (!powRecord?.sessionId) return void 0;
130
+ const originSession = await tasks.db.getSessionRecordBySessionId(powRecord.sessionId);
131
+ if (!originSession) return void 0;
132
+ const routed = result.routingOutput;
133
+ const selectionReason = routed.reason ?? originSession.reason;
134
+ const newSession = await tasks.frictionlessManager.createSession(originSession.token, originSession.score, originSession.threshold, originSession.scoreComponents, originSession.ipAddress, routed.captchaType, originSession.siteKey ?? powRecord.dappAccount, routed.captchaType === _prosopo_types.CaptchaType.image ? routed.solvedImagesCount ?? originSession.solvedImagesCount : void 0, void 0, originSession.userSitekeyIpHash, originSession.webView, originSession.iFrame, originSession.decryptedHeadHash, selectionReason, void 0, void 0, originSession.ipInfo, originSession.headers, originSession.mode, originSession.simdReadings, originSession.entropyMathRandomFingerprint, originSession.entropyCryptoFingerprint, originSession.entropyWallClockOffsetMs, originSession.entropyMathRandomFirst, originSession.currentUrl, handshakeTiming?.tcpToChelloUs, handshakeTiming?.chelloToHandshakeUs, true, originSession.iframeUrl, originSession.isProtect);
135
+ if (tasks.writeQueue) await tasks.writeQueue.cacheSessionEscalation(powRecord.sessionId, newSession.sessionId);
136
+ return {
137
+ captchaType: routed.captchaType,
138
+ sessionId: newSession.sessionId
139
+ };
210
140
  };
141
+ //#endregion
211
142
  exports.buildEscalation = buildEscalation;
212
- exports.default = submitPoWCaptchaSolution;
143
+ exports.default = submitPoWCaptchaSolution_default;
@@ -1,108 +1,77 @@
1
- "use strict";
2
- const common = require("@prosopo/common");
3
- const types = require("@prosopo/types");
4
- const util = require("@prosopo/util");
5
- const tasks = require("../../tasks/tasks.cjs");
6
- const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
7
- const testSiteKey = require("../testSiteKey.cjs");
8
- const validateAddress = require("../validateAddress.cjs");
9
- const submitPuzzleCaptchaSolution = (env) => async (req, res, next) => {
10
- if (apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
11
- req.logger.info(() => ({
12
- msg: "Maintenance mode active - returning verified"
13
- }));
14
- const response = {
15
- status: "ok",
16
- verified: true
17
- };
18
- return res.json(response);
19
- }
20
- let parsed;
21
- const tasks$1 = new tasks.Tasks(env, req.logger);
22
- try {
23
- parsed = types.SubmitPuzzleCaptchaSolutionBody.parse(req.body);
24
- } catch (err) {
25
- return next(
26
- new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
27
- context: { code: 400, error: err, body: req.body },
28
- i18n: req.i18n,
29
- logger: req.logger
30
- })
31
- );
32
- }
33
- const {
34
- challenge,
35
- signature,
36
- finalX,
37
- finalY,
38
- puzzleEvents,
39
- dapp,
40
- user,
41
- behavioralData,
42
- salt,
43
- simdReadings,
44
- clientMetaData
45
- } = parsed;
46
- validateAddress.validateSiteKey(dapp);
47
- validateAddress.validateAddr(user);
48
- const testVerdict = testSiteKey.resolveTestSiteKeyVerdict(dapp, req.logger);
49
- if (testVerdict !== null) {
50
- const response = {
51
- status: "ok",
52
- verified: testVerdict
53
- };
54
- return res.json(response);
55
- }
56
- try {
57
- const clientRecord = await tasks$1.db.getClientRecord(dapp);
58
- if (!clientRecord) {
59
- return next(
60
- new common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
61
- context: { code: 400, siteKey: dapp },
62
- i18n: req.i18n,
63
- logger: req.logger
64
- })
65
- );
66
- }
67
- const persistedSolutionTimeout = clientRecord.settings.solutionTimeout;
68
- const submitWindowMs = persistedSolutionTimeout ?? clientRecord.settings.verifiedTimeout;
69
- const verified = await tasks$1.puzzleCaptchaManager.verifyPuzzleCaptchaSolution(
70
- challenge,
71
- signature.provider.challenge,
72
- finalX,
73
- finalY,
74
- puzzleEvents,
75
- submitWindowMs,
76
- signature.user.timestamp,
77
- util.getIPAddress(req.ip || ""),
78
- util.flatten(req.headers),
79
- behavioralData,
80
- salt,
81
- simdReadings,
82
- clientMetaData
83
- );
84
- const response = {
85
- status: "ok",
86
- verified
87
- };
88
- return res.json(response);
89
- } catch (err) {
90
- req.logger.error(() => ({
91
- err,
92
- body: req.body,
93
- msg: "Error in puzzle captcha solution submission"
94
- }));
95
- return next(
96
- new common.ProsopoApiError("API.BAD_REQUEST", {
97
- context: {
98
- code: 500,
99
- siteKey: req.body.dapp,
100
- error: err
101
- },
102
- i18n: req.i18n,
103
- logger: req.logger
104
- })
105
- );
106
- }
1
+ const require_validateAddress = require("../validateAddress.cjs");
2
+ const require_tasks = require("../../tasks/tasks.cjs");
3
+ const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
4
+ const require_testSiteKey = require("../testSiteKey.cjs");
5
+ let _prosopo_common = require("@prosopo/common");
6
+ let _prosopo_types = require("@prosopo/types");
7
+ let _prosopo_util = require("@prosopo/util");
8
+ //#region src/api/captcha/submitPuzzleCaptchaSolution.ts
9
+ var submitPuzzleCaptchaSolution_default = (env) => async (req, res, next) => {
10
+ if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
11
+ req.logger.info(() => ({ msg: "Maintenance mode active - returning verified" }));
12
+ return res.json({
13
+ status: "ok",
14
+ verified: true
15
+ });
16
+ }
17
+ let parsed;
18
+ const tasks = new require_tasks.Tasks(env, req.logger);
19
+ try {
20
+ parsed = _prosopo_types.SubmitPuzzleCaptchaSolutionBody.parse(req.body);
21
+ } catch (err) {
22
+ return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
23
+ context: {
24
+ code: 400,
25
+ error: err,
26
+ body: req.body
27
+ },
28
+ i18n: req.i18n,
29
+ logger: req.logger
30
+ }));
31
+ }
32
+ const { challenge, signature, finalX, finalY, puzzleEvents, dapp, user, behavioralData, salt, simdReadings, clientMetaData } = parsed;
33
+ require_validateAddress.validateSiteKey(dapp);
34
+ require_validateAddress.validateAddr(user);
35
+ const testVerdict = require_testSiteKey.resolveTestSiteKeyVerdict(dapp, req.logger);
36
+ if (testVerdict !== null) {
37
+ const response = {
38
+ status: "ok",
39
+ verified: testVerdict
40
+ };
41
+ return res.json(response);
42
+ }
43
+ try {
44
+ const clientRecord = await tasks.db.getClientRecord(dapp);
45
+ if (!clientRecord) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
46
+ context: {
47
+ code: 400,
48
+ siteKey: dapp
49
+ },
50
+ i18n: req.i18n,
51
+ logger: req.logger
52
+ }));
53
+ const submitWindowMs = clientRecord.settings.solutionTimeout ?? clientRecord.settings.verifiedTimeout;
54
+ const response = {
55
+ status: "ok",
56
+ verified: await tasks.puzzleCaptchaManager.verifyPuzzleCaptchaSolution(challenge, signature.provider.challenge, finalX, finalY, puzzleEvents, submitWindowMs, signature.user.timestamp, (0, _prosopo_util.getIPAddress)(req.ip || ""), (0, _prosopo_util.flatten)(req.headers), behavioralData, salt, simdReadings, clientMetaData)
57
+ };
58
+ return res.json(response);
59
+ } catch (err) {
60
+ req.logger.error(() => ({
61
+ err,
62
+ body: req.body,
63
+ msg: "Error in puzzle captcha solution submission"
64
+ }));
65
+ return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
66
+ context: {
67
+ code: 500,
68
+ siteKey: req.body.dapp,
69
+ error: err
70
+ },
71
+ i18n: req.i18n,
72
+ logger: req.logger
73
+ }));
74
+ }
107
75
  };
108
- module.exports = submitPuzzleCaptchaSolution;
76
+ //#endregion
77
+ exports.default = submitPuzzleCaptchaSolution_default;