@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,488 +1,350 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
4
- const uuid = require("uuid");
5
- const dnsEventUrl = require("../../api/dnsEventUrl.cjs");
6
- const lang = require("../../rules/lang.cjs");
7
- const usageCounters = require("../../util/usageCounters.cjs");
8
- const captchaManager = require("../captchaManager.cjs");
9
- const decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
10
- const getBotScore = require("../detection/getBotScore.cjs");
11
- const routingMachine = require("./routingMachine.cjs");
12
- const DEFAULT_MAX_TIMESTAMP_AGE = 60 * 10 * 1e3;
13
- const getSessionIDPrefix = (host) => {
14
- return host ? host.replace(".prosopo.io", "") : "local";
1
+ const require_usageCounters = require("../../util/usageCounters.cjs");
2
+ const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
3
+ const require_dnsEventUrl = require("../../api/dnsEventUrl.cjs");
4
+ const require_lang = require("../../rules/lang.cjs");
5
+ const require_captchaManager = require("../captchaManager.cjs");
6
+ const require_getBotScore = require("../detection/getBotScore.cjs");
7
+ const require_routingMachine = require("./routingMachine.cjs");
8
+ let _prosopo_types = require("@prosopo/types");
9
+ let uuid = require("uuid");
10
+ //#region src/tasks/frictionless/frictionlessTasks.ts
11
+ var DEFAULT_MAX_TIMESTAMP_AGE = 600 * 1e3;
12
+ var getSessionIDPrefix = (host) => {
13
+ return host ? host.replace(".prosopo.io", "") : "local";
15
14
  };
16
- class FrictionlessManager extends captchaManager.CaptchaManager {
17
- constructor(db, pair, config, logger, writeQueue, decisionMachineRunner$1, usageCounters2) {
18
- super(db, pair, config, logger, writeQueue);
19
- this.config = config;
20
- this.decisionMachineRunner = decisionMachineRunner$1 ?? new decisionMachineRunner.DecisionMachineRunner(db);
21
- this.usageCounters = usageCounters2 ?? null;
22
- }
23
- /**
24
- * Provide the routing-machine context for this request. When set, the
25
- * frictionless flow's send*Captcha calls will (a) invoke the routing
26
- * machine to potentially override the baseline captcha type, and (b) emit
27
- * fire-and-forget served-counter writes after the session is created.
28
- *
29
- * Not called on maintenance-mode or configured-captchaType short-circuit
30
- * paths — those skip routing entirely.
31
- */
32
- setRoutingContext(ctx) {
33
- this.routingContext = ctx;
34
- }
35
- /**
36
- * Evaluate the configured routing machine against an arbitrary baseline +
37
- * context, without going through `sendCaptcha`. Used by the dedup
38
- * short-circuit to ask "if we reused this cached session, would the
39
- * current routing machine still pick the same captchaType?" — if not,
40
- * the cached session is evicted and the request falls through into the
41
- * normal decision-machine flow (which will run the router again with
42
- * fully-derived inputs).
43
- *
44
- * Returns the supplied baseline on any failure (no machine, machine
45
- * throws, counter fetch failure, etc.), matching applyRouter's contract.
46
- */
47
- async applyRoutingMachine(baseline, ctx) {
48
- return routingMachine.applyRouter(
49
- this.decisionMachineRunner,
50
- this.usageCounters,
51
- baseline,
52
- ctx,
53
- this.logger
54
- );
55
- }
56
- setSessionParams(params) {
57
- this.sessionParams = {
58
- token: params.token,
59
- score: params.score,
60
- threshold: params.threshold,
61
- scoreComponents: params.scoreComponents,
62
- ipAddress: params.ipAddress,
63
- webView: params.webView ?? false,
64
- iFrame: params.iFrame ?? false,
65
- decryptedHeadHash: params.decryptedHeadHash,
66
- siteKey: params.siteKey,
67
- currentUrl: params.currentUrl,
68
- iframeUrl: params.iframeUrl,
69
- isProtect: params.isProtect,
70
- ipInfo: params.ipInfo,
71
- headers: params.headers,
72
- mode: params.mode,
73
- simdReadings: params.simdReadings,
74
- entropyMathRandomFingerprint: params.entropyMathRandomFingerprint,
75
- entropyCryptoFingerprint: params.entropyCryptoFingerprint,
76
- entropyWallClockOffsetMs: params.entropyWallClockOffsetMs,
77
- entropyMathRandomFirst: params.entropyMathRandomFirst,
78
- tcpToChelloUs: params.tcpToChelloUs,
79
- chelloToHandshakeUs: params.chelloToHandshakeUs
80
- };
81
- }
82
- updateScore(score, scoreComponents) {
83
- if (this.sessionParams) {
84
- this.sessionParams.score = score;
85
- this.sessionParams.scoreComponents = scoreComponents;
86
- }
87
- }
88
- checkLangRules(acceptLanguage) {
89
- return lang.checkLangRules(this.config, acceptLanguage);
90
- }
91
- async createSession(token, score, threshold, scoreComponents, ipAddress, captchaType, siteKey, solvedImagesCount, powDifficulty, userSitekeyIpHash, webView = false, iFrame = false, decryptedHeadHash = "", reason, blocked, deleted, ipInfo, headers, mode, simdReadings, entropyMathRandomFingerprint, entropyCryptoFingerprint, entropyWallClockOffsetMs, entropyMathRandomFirst, currentUrl, tcpToChelloUs, chelloToHandshakeUs, isEscalation, iframeUrl, isProtect) {
92
- const sessionRecord = {
93
- sessionId: `${getSessionIDPrefix(this.config.host)}-${uuid.v4()}`,
94
- createdAt: /* @__PURE__ */ new Date(),
95
- token,
96
- score,
97
- threshold,
98
- scoreComponents,
99
- ipAddress,
100
- captchaType,
101
- mode,
102
- solvedImagesCount,
103
- powDifficulty,
104
- userSitekeyIpHash,
105
- webView,
106
- iFrame,
107
- // Only persist the escalation flag when it's actually true —
108
- // avoids polluting analytics with `false` on every plain
109
- // frictionless session.
110
- ...isEscalation && { isEscalation: true },
111
- decryptedHeadHash,
112
- reason,
113
- siteKey,
114
- currentUrl,
115
- iframeUrl,
116
- // Same rationale as isEscalation above: only persist the flag
117
- // when it's actually true so non-Protect sessions stay slim and
118
- // the sparse index on {isProtect, createdAt} carries only the
119
- // Protect subset.
120
- ...isProtect && { isProtect: true },
121
- blocked,
122
- deleted,
123
- ipInfo,
124
- headers,
125
- simdReadings,
126
- // Tag the arrival stage when the readings actually came in on
127
- // this hop. Absence of readings → absence of stage.
128
- ...simdReadings && {
129
- simdReadingsStage: types.SimdReadingsStage.frictionless
130
- },
131
- entropyMathRandomFingerprint,
132
- entropyCryptoFingerprint,
133
- entropyWallClockOffsetMs,
134
- entropyMathRandomFirst,
135
- tcpToChelloUs,
136
- chelloToHandshakeUs
137
- };
138
- await this.db.storeSessionRecord(sessionRecord);
139
- if (this.writeQueue) {
140
- const cacheData = sessionRecord;
141
- const cachePromises = [
142
- this.writeQueue.cacheSession(sessionRecord.sessionId, cacheData)
143
- ];
144
- if (userSitekeyIpHash) {
145
- cachePromises.push(
146
- this.writeQueue.cacheSessionByHash(
147
- userSitekeyIpHash,
148
- sessionRecord.sessionId
149
- )
150
- );
151
- }
152
- await Promise.all(cachePromises).catch(() => {
153
- });
154
- }
155
- return sessionRecord;
156
- }
157
- async sendImageCaptcha(params) {
158
- return this.sendCaptcha(types.CaptchaType.image, params);
159
- }
160
- async sendPowCaptcha(params) {
161
- return this.sendCaptcha(types.CaptchaType.pow, params);
162
- }
163
- async sendPuzzleCaptcha(params) {
164
- return this.sendCaptcha(types.CaptchaType.puzzle, params);
165
- }
166
- // Shared body for the three concrete `send*Captcha` helpers. Each helper is
167
- // kept as its own thin wrapper so call-sites read clearly, but session
168
- // validation and the createSession invocation only live in one place.
169
- async sendCaptcha(captchaType, params) {
170
- const effectiveParams = { ...this.sessionParams, ...params };
171
- if (!effectiveParams.token || effectiveParams.score === void 0 || effectiveParams.threshold === void 0 || !effectiveParams.scoreComponents || !effectiveParams.ipAddress || effectiveParams.siteKey === void 0) {
172
- throw new Error(
173
- `Session parameters must be set before sending a ${captchaType} captcha`
174
- );
175
- }
176
- const baseline = {
177
- captchaType,
178
- solvedImagesCount: captchaType === types.CaptchaType.image ? effectiveParams.solvedImagesCount : void 0,
179
- powDifficulty: captchaType === types.CaptchaType.pow ? effectiveParams.powDifficulty : void 0
180
- };
181
- const routed = this.routingContext ? await routingMachine.applyRouter(
182
- this.decisionMachineRunner,
183
- this.usageCounters,
184
- baseline,
185
- this.routingContext,
186
- this.logger
187
- ) : baseline;
188
- const finalCaptchaType = routed.captchaType;
189
- const finalSolvedImagesCount = finalCaptchaType === types.CaptchaType.image ? routed.solvedImagesCount ?? effectiveParams.solvedImagesCount : void 0;
190
- const finalPowDifficulty = finalCaptchaType === types.CaptchaType.pow ? routed.powDifficulty ?? effectiveParams.powDifficulty : void 0;
191
- const blocked = finalCaptchaType === types.CaptchaType.image ? effectiveParams.blocked : void 0;
192
- const sessionRecord = await this.createSession(
193
- effectiveParams.token,
194
- effectiveParams.score,
195
- effectiveParams.threshold,
196
- effectiveParams.scoreComponents,
197
- effectiveParams.ipAddress,
198
- finalCaptchaType,
199
- effectiveParams.siteKey,
200
- finalSolvedImagesCount,
201
- finalPowDifficulty,
202
- effectiveParams.userSitekeyIpHash,
203
- effectiveParams.webView ?? false,
204
- effectiveParams.iFrame ?? false,
205
- effectiveParams.decryptedHeadHash,
206
- effectiveParams.reason,
207
- blocked,
208
- void 0,
209
- effectiveParams.ipInfo,
210
- effectiveParams.headers,
211
- effectiveParams.mode,
212
- effectiveParams.simdReadings,
213
- effectiveParams.entropyMathRandomFingerprint,
214
- effectiveParams.entropyCryptoFingerprint,
215
- effectiveParams.entropyWallClockOffsetMs,
216
- effectiveParams.entropyMathRandomFirst,
217
- effectiveParams.currentUrl,
218
- effectiveParams.tcpToChelloUs,
219
- effectiveParams.chelloToHandshakeUs,
220
- void 0,
221
- effectiveParams.iframeUrl,
222
- effectiveParams.isProtect
223
- );
224
- if (this.routingContext && this.usageCounters) {
225
- this.usageCounters.incrManyAsync(
226
- this.routingContext.dappAccount,
227
- usageCounters.buildAllWindowIncrements(
228
- "served",
229
- finalCaptchaType,
230
- this.routingContext.ip,
231
- this.routingContext.userAccount
232
- )
233
- );
234
- }
235
- return {
236
- [types.ApiParams.captchaType]: finalCaptchaType,
237
- [types.ApiParams.sessionId]: sessionRecord.sessionId,
238
- [types.ApiParams.status]: "ok",
239
- dns_url: dnsEventUrl.buildDnsEventUrl(sessionRecord.sessionId)
240
- };
241
- }
242
- async registerBlockedSession(params) {
243
- const effectiveParams = { ...this.sessionParams, ...params };
244
- if (!effectiveParams.token || effectiveParams.score === void 0 || effectiveParams.threshold === void 0 || !effectiveParams.scoreComponents || !effectiveParams.ipAddress || effectiveParams.siteKey === void 0) {
245
- throw new Error(
246
- "Session parameters must be set before calling registerBlockedSession"
247
- );
248
- }
249
- await this.createSession(
250
- effectiveParams.token,
251
- effectiveParams.score,
252
- effectiveParams.threshold,
253
- effectiveParams.scoreComponents,
254
- effectiveParams.ipAddress,
255
- types.CaptchaType.image,
256
- effectiveParams.siteKey,
257
- effectiveParams.solvedImagesCount,
258
- void 0,
259
- effectiveParams.userSitekeyIpHash,
260
- effectiveParams.webView ?? false,
261
- effectiveParams.iFrame ?? false,
262
- effectiveParams.decryptedHeadHash,
263
- effectiveParams.reason,
264
- true,
265
- true,
266
- effectiveParams.ipInfo,
267
- effectiveParams.headers,
268
- effectiveParams.mode,
269
- effectiveParams.simdReadings,
270
- effectiveParams.entropyMathRandomFingerprint,
271
- effectiveParams.entropyCryptoFingerprint,
272
- effectiveParams.entropyWallClockOffsetMs,
273
- effectiveParams.entropyMathRandomFirst,
274
- effectiveParams.currentUrl,
275
- effectiveParams.tcpToChelloUs,
276
- effectiveParams.chelloToHandshakeUs,
277
- void 0,
278
- effectiveParams.iframeUrl,
279
- effectiveParams.isProtect
280
- );
281
- }
282
- scoreIncreaseAccessPolicy(accessPolicy, baseBotScore, botScore, scoreComponents) {
283
- const accessPolicyPenalty = accessPolicy?.frictionlessScore || this.config.penalties.PENALTY_ACCESS_RULE;
284
- botScore += accessPolicyPenalty;
285
- return {
286
- score: botScore,
287
- scoreComponents: {
288
- ...scoreComponents,
289
- accessPolicy: accessPolicyPenalty
290
- }
291
- };
292
- }
293
- scoreIncreaseWebView(baseBotScore, botScore, scoreComponents) {
294
- this.logger.debug(() => ({
295
- msg: "WebView detected"
296
- }));
297
- botScore += this.config.penalties.PENALTY_WEBVIEW;
298
- return {
299
- score: botScore,
300
- scoreComponents: {
301
- ...scoreComponents,
302
- webView: this.config.penalties.PENALTY_WEBVIEW
303
- }
304
- };
305
- }
306
- scoreIncreaseTimestamp(timestamp, baseBotScore, botScore, scoreComponents) {
307
- this.logger.info(() => ({
308
- msg: "Timestamp is older than 10 minutes",
309
- data: { timestamp: new Date(timestamp) }
310
- }));
311
- botScore += this.config.penalties.PENALTY_OLD_TIMESTAMP;
312
- return {
313
- score: botScore,
314
- scoreComponents: {
315
- ...scoreComponents,
316
- timeout: this.config.penalties.PENALTY_OLD_TIMESTAMP
317
- }
318
- };
319
- }
320
- static timestampTooOld(timestamp) {
321
- const now = Date.now();
322
- const diff = now - timestamp;
323
- return diff > DEFAULT_MAX_TIMESTAMP_AGE;
324
- }
325
- /**
326
- * Redacts a key for logging purposes by showing only the first 5, middle 10, and last 5 characters
327
- * @param key - The key to redact
328
- * @returns Redacted key string or empty string if key is falsy
329
- */
330
- redactKeyForLogging(key) {
331
- if (!key) return "";
332
- const start = key.slice(0, 5);
333
- const middle = key.slice(
334
- Math.floor(key.length / 2) - 5,
335
- Math.floor(key.length / 2) + 5
336
- );
337
- const end = key.slice(-5);
338
- return `${start}...${middle}...${end}`;
339
- }
340
- async decryptPayload(token, headHash) {
341
- const decryptKeys = [
342
- // Process DB keys first, then env var key last as env key will likely be invalid
343
- ...await this.getDetectorKeys(),
344
- process.env.BOT_DECRYPTION_KEY
345
- ].filter((k) => k);
346
- this.logger.debug(() => {
347
- const loggedKeys = decryptKeys.map(
348
- (key) => this.redactKeyForLogging(key)
349
- );
350
- return {
351
- msg: "Decrypting score",
352
- data: {
353
- keysLength: decryptKeys.length,
354
- keys: loggedKeys
355
- }
356
- };
357
- });
358
- let baseBotScore;
359
- let timestamp;
360
- let userId;
361
- let userAgent;
362
- let webView;
363
- let iFrame;
364
- let decryptedHeadHash = "";
365
- let decryptionFailed = false;
366
- let triggeredDetectors;
367
- let shadowDomPenalty;
368
- let entropyMathRandomFingerprint;
369
- let entropyCryptoFingerprint;
370
- let entropyWallClockOffsetMs;
371
- let entropyMathRandomFirst;
372
- for (const [keyIndex, key] of decryptKeys.entries()) {
373
- try {
374
- this.logger.info(() => ({
375
- msg: "Attempting to decrypt score",
376
- data: {
377
- key: this.redactKeyForLogging(key)
378
- }
379
- }));
380
- const decrypted = await getBotScore.getBotScore(token, headHash, key);
381
- decryptedHeadHash = decrypted.decryptedHeadHash || "";
382
- const s = decrypted.baseBotScore;
383
- const t = decrypted.timestamp;
384
- const a = decrypted.userId;
385
- const u = decrypted.userAgent;
386
- const w = decrypted.isWebView;
387
- const i = decrypted.isIframe;
388
- const td = decrypted.triggeredDetectors;
389
- const sd = decrypted.shadowDomPenalty;
390
- const ef = decrypted.entropyMathRandomFingerprint;
391
- const ec = decrypted.entropyCryptoFingerprint;
392
- const eo = decrypted.entropyWallClockOffsetMs;
393
- const em = decrypted.entropyMathRandomFirst;
394
- this.logger.debug(() => ({
395
- msg: "Successfully decrypted score",
396
- data: {
397
- key: this.redactKeyForLogging(key),
398
- baseBotScore: s,
399
- timestamp: t,
400
- userId: a,
401
- userAgent: u,
402
- webView: w,
403
- iFrame: i,
404
- triggeredDetectors: td,
405
- shadowDomPenalty: sd,
406
- entropyMathRandomFingerprint: ef,
407
- entropyCryptoFingerprint: ec,
408
- entropyWallClockOffsetMs: eo,
409
- entropyMathRandomFirst: em
410
- }
411
- }));
412
- baseBotScore = s;
413
- timestamp = t;
414
- userId = a;
415
- userAgent = u;
416
- webView = w;
417
- iFrame = i;
418
- triggeredDetectors = td;
419
- shadowDomPenalty = sd;
420
- entropyMathRandomFingerprint = ef;
421
- entropyCryptoFingerprint = ec;
422
- entropyWallClockOffsetMs = eo;
423
- entropyMathRandomFirst = em;
424
- break;
425
- } catch (err) {
426
- if (keyIndex === decryptKeys.length - 1) {
427
- this.logger.warn(() => ({
428
- msg: "Error decrypting score: no more keys to try"
429
- }));
430
- baseBotScore = 1;
431
- timestamp = 0;
432
- decryptedHeadHash = "";
433
- decryptionFailed = true;
434
- }
435
- }
436
- }
437
- const baseBotScoreUndefined = baseBotScore === void 0 || Number.isNaN(baseBotScore);
438
- const timestampUndefined = timestamp === void 0 || Number.isNaN(timestamp);
439
- const undefinedCount = Number(baseBotScoreUndefined) + Number(timestampUndefined);
440
- if (undefinedCount > 0) {
441
- this.logger.error(() => ({
442
- msg: "Error decrypting score: baseBotScore or timestamp is undefined"
443
- }));
444
- baseBotScore = 1;
445
- timestamp = 0;
446
- decryptedHeadHash = "";
447
- decryptionFailed = true;
448
- }
449
- this.logger.info(() => ({
450
- msg: "decryptPayload result",
451
- data: {
452
- baseBotScore,
453
- timestamp,
454
- userId,
455
- userAgent,
456
- webView,
457
- iFrame,
458
- decryptedHeadHash,
459
- decryptionFailed,
460
- shadowDomPenalty
461
- }
462
- }));
463
- return {
464
- baseBotScore: Number(baseBotScore),
465
- timestamp: Number(timestamp),
466
- userId,
467
- userAgent,
468
- webView: webView || false,
469
- iFrame: iFrame || false,
470
- decryptedHeadHash,
471
- decryptionFailed,
472
- triggeredDetectors,
473
- shadowDomPenalty,
474
- entropyMathRandomFingerprint,
475
- entropyCryptoFingerprint,
476
- entropyWallClockOffsetMs,
477
- entropyMathRandomFirst
478
- };
479
- }
480
- async getClientContextEntropy(siteKey, contextType) {
481
- return this.db.getClientContextEntropy(siteKey, contextType);
482
- }
483
- }
484
- Object.defineProperty(exports, "FrictionlessReason", {
485
- enumerable: true,
486
- get: () => types.FrictionlessReason
487
- });
15
+ var FrictionlessManager = class extends require_captchaManager.CaptchaManager {
16
+ constructor(db, pair, config, logger, writeQueue, decisionMachineRunner, usageCounters) {
17
+ super(db, pair, config, logger, writeQueue);
18
+ this.config = config;
19
+ this.decisionMachineRunner = decisionMachineRunner ?? new require_decisionMachineRunner.DecisionMachineRunner(db);
20
+ this.usageCounters = usageCounters ?? null;
21
+ }
22
+ /**
23
+ * Provide the routing-machine context for this request. When set, the
24
+ * frictionless flow's send*Captcha calls will (a) invoke the routing
25
+ * machine to potentially override the baseline captcha type, and (b) emit
26
+ * fire-and-forget served-counter writes after the session is created.
27
+ *
28
+ * Not called on maintenance-mode or configured-captchaType short-circuit
29
+ * paths — those skip routing entirely.
30
+ */
31
+ setRoutingContext(ctx) {
32
+ this.routingContext = ctx;
33
+ }
34
+ /**
35
+ * Evaluate the configured routing machine against an arbitrary baseline +
36
+ * context, without going through `sendCaptcha`. Used by the dedup
37
+ * short-circuit to ask "if we reused this cached session, would the
38
+ * current routing machine still pick the same captchaType?" — if not,
39
+ * the cached session is evicted and the request falls through into the
40
+ * normal decision-machine flow (which will run the router again with
41
+ * fully-derived inputs).
42
+ *
43
+ * Returns the supplied baseline on any failure (no machine, machine
44
+ * throws, counter fetch failure, etc.), matching applyRouter's contract.
45
+ */
46
+ async applyRoutingMachine(baseline, ctx) {
47
+ return require_routingMachine.applyRouter(this.decisionMachineRunner, this.usageCounters, baseline, ctx, this.logger);
48
+ }
49
+ setSessionParams(params) {
50
+ this.sessionParams = {
51
+ token: params.token,
52
+ score: params.score,
53
+ threshold: params.threshold,
54
+ scoreComponents: params.scoreComponents,
55
+ ipAddress: params.ipAddress,
56
+ webView: params.webView ?? false,
57
+ iFrame: params.iFrame ?? false,
58
+ decryptedHeadHash: params.decryptedHeadHash,
59
+ siteKey: params.siteKey,
60
+ currentUrl: params.currentUrl,
61
+ iframeUrl: params.iframeUrl,
62
+ isProtect: params.isProtect,
63
+ ipInfo: params.ipInfo,
64
+ headers: params.headers,
65
+ mode: params.mode,
66
+ simdReadings: params.simdReadings,
67
+ entropyMathRandomFingerprint: params.entropyMathRandomFingerprint,
68
+ entropyCryptoFingerprint: params.entropyCryptoFingerprint,
69
+ entropyWallClockOffsetMs: params.entropyWallClockOffsetMs,
70
+ entropyMathRandomFirst: params.entropyMathRandomFirst,
71
+ tcpToChelloUs: params.tcpToChelloUs,
72
+ chelloToHandshakeUs: params.chelloToHandshakeUs
73
+ };
74
+ }
75
+ updateScore(score, scoreComponents) {
76
+ if (this.sessionParams) {
77
+ this.sessionParams.score = score;
78
+ this.sessionParams.scoreComponents = scoreComponents;
79
+ }
80
+ }
81
+ checkLangRules(acceptLanguage) {
82
+ return require_lang.checkLangRules(this.config, acceptLanguage);
83
+ }
84
+ async createSession(token, score, threshold, scoreComponents, ipAddress, captchaType, siteKey, solvedImagesCount, powDifficulty, userSitekeyIpHash, webView = false, iFrame = false, decryptedHeadHash = "", reason, blocked, deleted, ipInfo, headers, mode, simdReadings, entropyMathRandomFingerprint, entropyCryptoFingerprint, entropyWallClockOffsetMs, entropyMathRandomFirst, currentUrl, tcpToChelloUs, chelloToHandshakeUs, isEscalation, iframeUrl, isProtect) {
85
+ const sessionRecord = {
86
+ sessionId: `${getSessionIDPrefix(this.config.host)}-${(0, uuid.v4)()}`,
87
+ createdAt: /* @__PURE__ */ new Date(),
88
+ token,
89
+ score,
90
+ threshold,
91
+ scoreComponents,
92
+ ipAddress,
93
+ captchaType,
94
+ mode,
95
+ solvedImagesCount,
96
+ powDifficulty,
97
+ userSitekeyIpHash,
98
+ webView,
99
+ iFrame,
100
+ ...isEscalation && { isEscalation: true },
101
+ decryptedHeadHash,
102
+ reason,
103
+ siteKey,
104
+ currentUrl,
105
+ iframeUrl,
106
+ ...isProtect && { isProtect: true },
107
+ blocked,
108
+ deleted,
109
+ ipInfo,
110
+ headers,
111
+ simdReadings,
112
+ ...simdReadings && { simdReadingsStage: _prosopo_types.SimdReadingsStage.frictionless },
113
+ entropyMathRandomFingerprint,
114
+ entropyCryptoFingerprint,
115
+ entropyWallClockOffsetMs,
116
+ entropyMathRandomFirst,
117
+ tcpToChelloUs,
118
+ chelloToHandshakeUs
119
+ };
120
+ await this.db.storeSessionRecord(sessionRecord);
121
+ if (this.writeQueue) {
122
+ const cacheData = sessionRecord;
123
+ const cachePromises = [this.writeQueue.cacheSession(sessionRecord.sessionId, cacheData)];
124
+ if (userSitekeyIpHash) cachePromises.push(this.writeQueue.cacheSessionByHash(userSitekeyIpHash, sessionRecord.sessionId));
125
+ await Promise.all(cachePromises).catch(() => {});
126
+ }
127
+ return sessionRecord;
128
+ }
129
+ async sendImageCaptcha(params) {
130
+ return this.sendCaptcha(_prosopo_types.CaptchaType.image, params);
131
+ }
132
+ async sendPowCaptcha(params) {
133
+ return this.sendCaptcha(_prosopo_types.CaptchaType.pow, params);
134
+ }
135
+ async sendPuzzleCaptcha(params) {
136
+ return this.sendCaptcha(_prosopo_types.CaptchaType.puzzle, params);
137
+ }
138
+ async sendCaptcha(captchaType, params) {
139
+ const effectiveParams = {
140
+ ...this.sessionParams,
141
+ ...params
142
+ };
143
+ if (!effectiveParams.token || effectiveParams.score === void 0 || effectiveParams.threshold === void 0 || !effectiveParams.scoreComponents || !effectiveParams.ipAddress || effectiveParams.siteKey === void 0) throw new Error(`Session parameters must be set before sending a ${captchaType} captcha`);
144
+ const baseline = {
145
+ captchaType,
146
+ solvedImagesCount: captchaType === _prosopo_types.CaptchaType.image ? effectiveParams.solvedImagesCount : void 0,
147
+ powDifficulty: captchaType === _prosopo_types.CaptchaType.pow ? effectiveParams.powDifficulty : void 0
148
+ };
149
+ const routed = this.routingContext ? await require_routingMachine.applyRouter(this.decisionMachineRunner, this.usageCounters, baseline, this.routingContext, this.logger) : baseline;
150
+ const finalCaptchaType = routed.captchaType;
151
+ const finalSolvedImagesCount = finalCaptchaType === _prosopo_types.CaptchaType.image ? routed.solvedImagesCount ?? effectiveParams.solvedImagesCount : void 0;
152
+ const finalPowDifficulty = finalCaptchaType === _prosopo_types.CaptchaType.pow ? routed.powDifficulty ?? effectiveParams.powDifficulty : void 0;
153
+ const blocked = finalCaptchaType === _prosopo_types.CaptchaType.image ? effectiveParams.blocked : void 0;
154
+ const sessionRecord = await this.createSession(effectiveParams.token, effectiveParams.score, effectiveParams.threshold, effectiveParams.scoreComponents, effectiveParams.ipAddress, finalCaptchaType, effectiveParams.siteKey, finalSolvedImagesCount, finalPowDifficulty, effectiveParams.userSitekeyIpHash, effectiveParams.webView ?? false, effectiveParams.iFrame ?? false, effectiveParams.decryptedHeadHash, effectiveParams.reason, blocked, void 0, effectiveParams.ipInfo, effectiveParams.headers, effectiveParams.mode, effectiveParams.simdReadings, effectiveParams.entropyMathRandomFingerprint, effectiveParams.entropyCryptoFingerprint, effectiveParams.entropyWallClockOffsetMs, effectiveParams.entropyMathRandomFirst, effectiveParams.currentUrl, effectiveParams.tcpToChelloUs, effectiveParams.chelloToHandshakeUs, void 0, effectiveParams.iframeUrl, effectiveParams.isProtect);
155
+ if (this.routingContext && this.usageCounters) this.usageCounters.incrManyAsync(this.routingContext.dappAccount, require_usageCounters.buildAllWindowIncrements("served", finalCaptchaType, this.routingContext.ip, this.routingContext.userAccount));
156
+ return {
157
+ [_prosopo_types.ApiParams.captchaType]: finalCaptchaType,
158
+ [_prosopo_types.ApiParams.sessionId]: sessionRecord.sessionId,
159
+ [_prosopo_types.ApiParams.status]: "ok",
160
+ dns_url: require_dnsEventUrl.buildDnsEventUrl(sessionRecord.sessionId)
161
+ };
162
+ }
163
+ async registerBlockedSession(params) {
164
+ const effectiveParams = {
165
+ ...this.sessionParams,
166
+ ...params
167
+ };
168
+ if (!effectiveParams.token || effectiveParams.score === void 0 || effectiveParams.threshold === void 0 || !effectiveParams.scoreComponents || !effectiveParams.ipAddress || effectiveParams.siteKey === void 0) throw new Error("Session parameters must be set before calling registerBlockedSession");
169
+ await this.createSession(effectiveParams.token, effectiveParams.score, effectiveParams.threshold, effectiveParams.scoreComponents, effectiveParams.ipAddress, _prosopo_types.CaptchaType.image, effectiveParams.siteKey, effectiveParams.solvedImagesCount, void 0, effectiveParams.userSitekeyIpHash, effectiveParams.webView ?? false, effectiveParams.iFrame ?? false, effectiveParams.decryptedHeadHash, effectiveParams.reason, true, true, effectiveParams.ipInfo, effectiveParams.headers, effectiveParams.mode, effectiveParams.simdReadings, effectiveParams.entropyMathRandomFingerprint, effectiveParams.entropyCryptoFingerprint, effectiveParams.entropyWallClockOffsetMs, effectiveParams.entropyMathRandomFirst, effectiveParams.currentUrl, effectiveParams.tcpToChelloUs, effectiveParams.chelloToHandshakeUs, void 0, effectiveParams.iframeUrl, effectiveParams.isProtect);
170
+ }
171
+ scoreIncreaseAccessPolicy(accessPolicy, baseBotScore, botScore, scoreComponents) {
172
+ const accessPolicyPenalty = accessPolicy?.frictionlessScore || this.config.penalties.PENALTY_ACCESS_RULE;
173
+ botScore += accessPolicyPenalty;
174
+ return {
175
+ score: botScore,
176
+ scoreComponents: {
177
+ ...scoreComponents,
178
+ accessPolicy: accessPolicyPenalty
179
+ }
180
+ };
181
+ }
182
+ scoreIncreaseWebView(baseBotScore, botScore, scoreComponents) {
183
+ this.logger.debug(() => ({ msg: "WebView detected" }));
184
+ botScore += this.config.penalties.PENALTY_WEBVIEW;
185
+ return {
186
+ score: botScore,
187
+ scoreComponents: {
188
+ ...scoreComponents,
189
+ webView: this.config.penalties.PENALTY_WEBVIEW
190
+ }
191
+ };
192
+ }
193
+ scoreIncreaseTimestamp(timestamp, baseBotScore, botScore, scoreComponents) {
194
+ this.logger.info(() => ({
195
+ msg: "Timestamp is older than 10 minutes",
196
+ data: { timestamp: new Date(timestamp) }
197
+ }));
198
+ botScore += this.config.penalties.PENALTY_OLD_TIMESTAMP;
199
+ return {
200
+ score: botScore,
201
+ scoreComponents: {
202
+ ...scoreComponents,
203
+ timeout: this.config.penalties.PENALTY_OLD_TIMESTAMP
204
+ }
205
+ };
206
+ }
207
+ static timestampTooOld(timestamp) {
208
+ return Date.now() - timestamp > DEFAULT_MAX_TIMESTAMP_AGE;
209
+ }
210
+ /**
211
+ * Redacts a key for logging purposes by showing only the first 5, middle 10, and last 5 characters
212
+ * @param key - The key to redact
213
+ * @returns Redacted key string or empty string if key is falsy
214
+ */
215
+ redactKeyForLogging(key) {
216
+ if (!key) return "";
217
+ return `${key.slice(0, 5)}...${key.slice(Math.floor(key.length / 2) - 5, Math.floor(key.length / 2) + 5)}...${key.slice(-5)}`;
218
+ }
219
+ async decryptPayload(token, headHash) {
220
+ const decryptKeys = [...await this.getDetectorKeys(), process.env.BOT_DECRYPTION_KEY].filter((k) => k);
221
+ this.logger.debug(() => {
222
+ const loggedKeys = decryptKeys.map((key) => this.redactKeyForLogging(key));
223
+ return {
224
+ msg: "Decrypting score",
225
+ data: {
226
+ keysLength: decryptKeys.length,
227
+ keys: loggedKeys
228
+ }
229
+ };
230
+ });
231
+ let baseBotScore;
232
+ let timestamp;
233
+ let userId;
234
+ let userAgent;
235
+ let webView;
236
+ let iFrame;
237
+ let decryptedHeadHash = "";
238
+ let decryptionFailed = false;
239
+ let triggeredDetectors;
240
+ let shadowDomPenalty;
241
+ let entropyMathRandomFingerprint;
242
+ let entropyCryptoFingerprint;
243
+ let entropyWallClockOffsetMs;
244
+ let entropyMathRandomFirst;
245
+ for (const [keyIndex, key] of decryptKeys.entries()) try {
246
+ this.logger.info(() => ({
247
+ msg: "Attempting to decrypt score",
248
+ data: { key: this.redactKeyForLogging(key) }
249
+ }));
250
+ const decrypted = await require_getBotScore.getBotScore(token, headHash, key);
251
+ decryptedHeadHash = decrypted.decryptedHeadHash || "";
252
+ const s = decrypted.baseBotScore;
253
+ const t = decrypted.timestamp;
254
+ const a = decrypted.userId;
255
+ const u = decrypted.userAgent;
256
+ const w = decrypted.isWebView;
257
+ const i = decrypted.isIframe;
258
+ const td = decrypted.triggeredDetectors;
259
+ const sd = decrypted.shadowDomPenalty;
260
+ const ef = decrypted.entropyMathRandomFingerprint;
261
+ const ec = decrypted.entropyCryptoFingerprint;
262
+ const eo = decrypted.entropyWallClockOffsetMs;
263
+ const em = decrypted.entropyMathRandomFirst;
264
+ this.logger.debug(() => ({
265
+ msg: "Successfully decrypted score",
266
+ data: {
267
+ key: this.redactKeyForLogging(key),
268
+ baseBotScore: s,
269
+ timestamp: t,
270
+ userId: a,
271
+ userAgent: u,
272
+ webView: w,
273
+ iFrame: i,
274
+ triggeredDetectors: td,
275
+ shadowDomPenalty: sd,
276
+ entropyMathRandomFingerprint: ef,
277
+ entropyCryptoFingerprint: ec,
278
+ entropyWallClockOffsetMs: eo,
279
+ entropyMathRandomFirst: em
280
+ }
281
+ }));
282
+ baseBotScore = s;
283
+ timestamp = t;
284
+ userId = a;
285
+ userAgent = u;
286
+ webView = w;
287
+ iFrame = i;
288
+ triggeredDetectors = td;
289
+ shadowDomPenalty = sd;
290
+ entropyMathRandomFingerprint = ef;
291
+ entropyCryptoFingerprint = ec;
292
+ entropyWallClockOffsetMs = eo;
293
+ entropyMathRandomFirst = em;
294
+ break;
295
+ } catch (err) {
296
+ if (keyIndex === decryptKeys.length - 1) {
297
+ this.logger.warn(() => ({ msg: "Error decrypting score: no more keys to try" }));
298
+ baseBotScore = 1;
299
+ timestamp = 0;
300
+ decryptedHeadHash = "";
301
+ decryptionFailed = true;
302
+ }
303
+ }
304
+ const baseBotScoreUndefined = baseBotScore === void 0 || Number.isNaN(baseBotScore);
305
+ const timestampUndefined = timestamp === void 0 || Number.isNaN(timestamp);
306
+ if (Number(baseBotScoreUndefined) + Number(timestampUndefined) > 0) {
307
+ this.logger.error(() => ({ msg: "Error decrypting score: baseBotScore or timestamp is undefined" }));
308
+ baseBotScore = 1;
309
+ timestamp = 0;
310
+ decryptedHeadHash = "";
311
+ decryptionFailed = true;
312
+ }
313
+ this.logger.info(() => ({
314
+ msg: "decryptPayload result",
315
+ data: {
316
+ baseBotScore,
317
+ timestamp,
318
+ userId,
319
+ userAgent,
320
+ webView,
321
+ iFrame,
322
+ decryptedHeadHash,
323
+ decryptionFailed,
324
+ shadowDomPenalty
325
+ }
326
+ }));
327
+ return {
328
+ baseBotScore: Number(baseBotScore),
329
+ timestamp: Number(timestamp),
330
+ userId,
331
+ userAgent,
332
+ webView: webView || false,
333
+ iFrame: iFrame || false,
334
+ decryptedHeadHash,
335
+ decryptionFailed,
336
+ triggeredDetectors,
337
+ shadowDomPenalty,
338
+ entropyMathRandomFingerprint,
339
+ entropyCryptoFingerprint,
340
+ entropyWallClockOffsetMs,
341
+ entropyMathRandomFirst
342
+ };
343
+ }
344
+ async getClientContextEntropy(siteKey, contextType) {
345
+ return this.db.getClientContextEntropy(siteKey, contextType);
346
+ }
347
+ };
348
+ //#endregion
488
349
  exports.FrictionlessManager = FrictionlessManager;
350
+ exports.FrictionlessReason = _prosopo_types.FrictionlessReason;