@prosopo/provider 5.14.0 → 5.16.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 (303) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +62 -46
  2. package/.turbo/turbo-build$colon$tsc.log +37 -34
  3. package/.turbo/turbo-build.log +63 -50
  4. package/CHANGELOG.md +193 -0
  5. package/LICENSE +201 -0
  6. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts +4 -0
  7. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts.map +1 -1
  8. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +63 -3
  9. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js.map +1 -1
  10. package/dist/api/blacklistRequestInspector.js +2 -2
  11. package/dist/api/captcha/getAudioCaptchaChallenge.d.ts +5 -0
  12. package/dist/api/captcha/getAudioCaptchaChallenge.d.ts.map +1 -0
  13. package/dist/api/captcha/getAudioCaptchaChallenge.js +37 -0
  14. package/dist/api/captcha/getAudioCaptchaChallenge.js.map +1 -0
  15. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.d.ts +2 -1
  16. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.d.ts.map +1 -1
  17. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js +11 -2
  18. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js.map +1 -1
  19. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +1 -1
  20. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
  21. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +26 -15
  22. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
  23. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.d.ts +5 -0
  24. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.d.ts.map +1 -0
  25. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.js +20 -0
  26. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.js.map +1 -0
  27. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.d.ts.map +1 -1
  28. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +1 -0
  29. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js.map +1 -1
  30. package/dist/api/captcha/getIconOrderCaptchaChallenge.d.ts +5 -0
  31. package/dist/api/captcha/getIconOrderCaptchaChallenge.d.ts.map +1 -0
  32. package/dist/api/captcha/getIconOrderCaptchaChallenge.js +37 -0
  33. package/dist/api/captcha/getIconOrderCaptchaChallenge.js.map +1 -0
  34. package/dist/api/captcha/getImageCaptchaChallenge.js +2 -2
  35. package/dist/api/captcha/getPoWCaptchaChallenge.js +4 -4
  36. package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts +1 -3
  37. package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts.map +1 -1
  38. package/dist/api/captcha/getPuzzleCaptchaChallenge.js +53 -146
  39. package/dist/api/captcha/getPuzzleCaptchaChallenge.js.map +1 -1
  40. package/dist/api/captcha/interactiveCaptchaChallenge.d.ts +42 -0
  41. package/dist/api/captcha/interactiveCaptchaChallenge.d.ts.map +1 -0
  42. package/dist/api/captcha/interactiveCaptchaChallenge.js +154 -0
  43. package/dist/api/captcha/interactiveCaptchaChallenge.js.map +1 -0
  44. package/dist/api/captcha/interactiveCaptchaSolution.d.ts +14 -0
  45. package/dist/api/captcha/interactiveCaptchaSolution.d.ts.map +1 -0
  46. package/dist/api/captcha/interactiveCaptchaSolution.js +77 -0
  47. package/dist/api/captcha/interactiveCaptchaSolution.js.map +1 -0
  48. package/dist/api/captcha/maintenanceModeResponses.d.ts +4 -2
  49. package/dist/api/captcha/maintenanceModeResponses.d.ts.map +1 -1
  50. package/dist/api/captcha/maintenanceModeResponses.js +28 -1
  51. package/dist/api/captcha/maintenanceModeResponses.js.map +1 -1
  52. package/dist/api/captcha/submitAudioCaptchaSolution.d.ts +4 -0
  53. package/dist/api/captcha/submitAudioCaptchaSolution.d.ts.map +1 -0
  54. package/dist/api/captcha/submitAudioCaptchaSolution.js +11 -0
  55. package/dist/api/captcha/submitAudioCaptchaSolution.js.map +1 -0
  56. package/dist/api/captcha/submitIconOrderCaptchaSolution.d.ts +4 -0
  57. package/dist/api/captcha/submitIconOrderCaptchaSolution.d.ts.map +1 -0
  58. package/dist/api/captcha/submitIconOrderCaptchaSolution.js +11 -0
  59. package/dist/api/captcha/submitIconOrderCaptchaSolution.js.map +1 -0
  60. package/dist/api/captcha/submitPoWCaptchaSolution.d.ts +4 -11
  61. package/dist/api/captcha/submitPoWCaptchaSolution.d.ts.map +1 -1
  62. package/dist/api/captcha/submitPoWCaptchaSolution.js +13 -18
  63. package/dist/api/captcha/submitPoWCaptchaSolution.js.map +1 -1
  64. package/dist/api/captcha/submitPuzzleCaptchaSolution.d.ts +1 -3
  65. package/dist/api/captcha/submitPuzzleCaptchaSolution.d.ts.map +1 -1
  66. package/dist/api/captcha/submitPuzzleCaptchaSolution.js +6 -73
  67. package/dist/api/captcha/submitPuzzleCaptchaSolution.js.map +1 -1
  68. package/dist/api/captcha/trafficFilterRequestTime.d.ts +4 -1
  69. package/dist/api/captcha/trafficFilterRequestTime.d.ts.map +1 -1
  70. package/dist/api/captcha/trafficFilterRequestTime.js +3 -0
  71. package/dist/api/captcha/trafficFilterRequestTime.js.map +1 -1
  72. package/dist/api/captcha.d.ts.map +1 -1
  73. package/dist/api/captcha.js +8 -0
  74. package/dist/api/captcha.js.map +1 -1
  75. package/dist/api/domainMiddleware.js +1 -1
  76. package/dist/api/ja4Middleware.js +1 -1
  77. package/dist/api/rawTlsSignalsMiddleware.d.ts +14 -1
  78. package/dist/api/rawTlsSignalsMiddleware.d.ts.map +1 -1
  79. package/dist/api/rawTlsSignalsMiddleware.js +111 -23
  80. package/dist/api/rawTlsSignalsMiddleware.js.map +1 -1
  81. package/dist/api/startProviderApi.js +2 -2
  82. package/dist/api/verify.d.ts.map +1 -1
  83. package/dist/api/verify.js +153 -96
  84. package/dist/api/verify.js.map +1 -1
  85. package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +65 -2
  86. package/dist/cjs/api/blacklistRequestInspector.cjs +2 -2
  87. package/dist/cjs/api/captcha/getAudioCaptchaChallenge.cjs +37 -0
  88. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/constants.cjs +10 -0
  89. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +1 -1
  90. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +25 -14
  91. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.cjs +20 -0
  92. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +1 -0
  93. package/dist/cjs/api/captcha/getIconOrderCaptchaChallenge.cjs +37 -0
  94. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +2 -2
  95. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +4 -4
  96. package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +52 -145
  97. package/dist/cjs/api/captcha/interactiveCaptchaChallenge.cjs +154 -0
  98. package/dist/cjs/api/captcha/interactiveCaptchaSolution.cjs +77 -0
  99. package/dist/cjs/api/captcha/maintenanceModeResponses.cjs +29 -0
  100. package/dist/cjs/api/captcha/submitAudioCaptchaSolution.cjs +11 -0
  101. package/dist/cjs/api/captcha/submitIconOrderCaptchaSolution.cjs +11 -0
  102. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +11 -16
  103. package/dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs +6 -73
  104. package/dist/cjs/api/captcha/trafficFilterRequestTime.cjs +3 -0
  105. package/dist/cjs/api/captcha.cjs +8 -0
  106. package/dist/cjs/api/domainMiddleware.cjs +1 -1
  107. package/dist/cjs/api/ja4Middleware.cjs +1 -1
  108. package/dist/cjs/api/rawTlsSignalsMiddleware.cjs +111 -22
  109. package/dist/cjs/api/startProviderApi.cjs +2 -2
  110. package/dist/cjs/api/verify.cjs +152 -95
  111. package/dist/cjs/compositeIpAddress.cjs +21 -7
  112. package/dist/cjs/index.cjs +1 -1
  113. package/dist/cjs/tasks/audio/audioBuffer.cjs +72 -0
  114. package/dist/cjs/tasks/audio/audioRenderer.cjs +32 -0
  115. package/dist/cjs/tasks/audioAlternative.cjs +23 -0
  116. package/dist/cjs/tasks/audioCaptcha/audioTasks.cjs +65 -0
  117. package/dist/cjs/tasks/audioCaptcha/audioTasksUtils.cjs +19 -0
  118. package/dist/cjs/tasks/captchaManager.cjs +28 -1
  119. package/dist/cjs/tasks/captchaTypeSelection.cjs +31 -3
  120. package/dist/cjs/tasks/client/clientTasks.cjs +2 -2
  121. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +49 -26
  122. package/dist/cjs/tasks/iconOrder/iconOrderRenderer.cjs +42 -0
  123. package/dist/cjs/tasks/iconOrderCaptcha/iconOrderTasks.cjs +69 -0
  124. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +10 -17
  125. package/dist/cjs/tasks/interactiveCaptcha/interactiveCaptchaManager.cjs +423 -0
  126. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +15 -19
  127. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +3 -1
  128. package/dist/cjs/tasks/puzzle/backgroundBuffer.cjs +3 -3
  129. package/dist/cjs/tasks/puzzle/nativeBackground.cjs +12 -5
  130. package/dist/cjs/tasks/puzzle/puzzleRenderer.cjs +4 -3
  131. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +40 -493
  132. package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +18 -1
  133. package/dist/cjs/tasks/tasks.cjs +6 -0
  134. package/dist/cjs/util.cjs +1 -1
  135. package/dist/compositeIpAddress.d.ts.map +1 -1
  136. package/dist/compositeIpAddress.js +21 -7
  137. package/dist/compositeIpAddress.js.map +1 -1
  138. package/dist/index.js +2 -2
  139. package/dist/tasks/audio/audioBuffer.d.ts +23 -0
  140. package/dist/tasks/audio/audioBuffer.d.ts.map +1 -0
  141. package/dist/tasks/audio/audioBuffer.js +70 -0
  142. package/dist/tasks/audio/audioBuffer.js.map +1 -0
  143. package/dist/tasks/audio/audioRenderer.d.ts +11 -0
  144. package/dist/tasks/audio/audioRenderer.d.ts.map +1 -0
  145. package/dist/tasks/audio/audioRenderer.js +31 -0
  146. package/dist/tasks/audio/audioRenderer.js.map +1 -0
  147. package/dist/tasks/audioAlternative.d.ts +8 -0
  148. package/dist/tasks/audioAlternative.d.ts.map +1 -0
  149. package/dist/tasks/audioAlternative.js +20 -0
  150. package/dist/tasks/audioAlternative.js.map +1 -0
  151. package/dist/tasks/audioCaptcha/audioTasks.d.ts +19 -0
  152. package/dist/tasks/audioCaptcha/audioTasks.d.ts.map +1 -0
  153. package/dist/tasks/audioCaptcha/audioTasks.js +65 -0
  154. package/dist/tasks/audioCaptcha/audioTasks.js.map +1 -0
  155. package/dist/tasks/audioCaptcha/audioTasksUtils.d.ts +3 -0
  156. package/dist/tasks/audioCaptcha/audioTasksUtils.d.ts.map +1 -0
  157. package/dist/tasks/audioCaptcha/audioTasksUtils.js +18 -0
  158. package/dist/tasks/audioCaptcha/audioTasksUtils.js.map +1 -0
  159. package/dist/tasks/captchaManager.d.ts +9 -3
  160. package/dist/tasks/captchaManager.d.ts.map +1 -1
  161. package/dist/tasks/captchaManager.js +29 -2
  162. package/dist/tasks/captchaManager.js.map +1 -1
  163. package/dist/tasks/captchaTypeSelection.d.ts +4 -2
  164. package/dist/tasks/captchaTypeSelection.d.ts.map +1 -1
  165. package/dist/tasks/captchaTypeSelection.js +32 -5
  166. package/dist/tasks/captchaTypeSelection.js.map +1 -1
  167. package/dist/tasks/client/clientTasks.js +2 -2
  168. package/dist/tasks/frictionless/frictionlessTasks.d.ts +6 -1
  169. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
  170. package/dist/tasks/frictionless/frictionlessTasks.js +51 -28
  171. package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
  172. package/dist/tasks/frictionless/routingMachine.d.ts +1 -2
  173. package/dist/tasks/frictionless/routingMachine.d.ts.map +1 -1
  174. package/dist/tasks/frictionless/routingMachine.js.map +1 -1
  175. package/dist/tasks/iconOrder/iconOrderRenderer.d.ts +12 -0
  176. package/dist/tasks/iconOrder/iconOrderRenderer.d.ts.map +1 -0
  177. package/dist/tasks/iconOrder/iconOrderRenderer.js +40 -0
  178. package/dist/tasks/iconOrder/iconOrderRenderer.js.map +1 -0
  179. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.d.ts +22 -0
  180. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.d.ts.map +1 -0
  181. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.js +69 -0
  182. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.js.map +1 -0
  183. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
  184. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +10 -17
  185. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
  186. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts +52 -0
  187. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts.map +1 -0
  188. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js +423 -0
  189. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js.map +1 -0
  190. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  191. package/dist/tasks/powCaptcha/powTasks.js +15 -19
  192. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  193. package/dist/tasks/powCaptcha/powTasksUtils.d.ts +1 -0
  194. package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -1
  195. package/dist/tasks/powCaptcha/powTasksUtils.js +3 -2
  196. package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -1
  197. package/dist/tasks/puzzle/backgroundBuffer.d.ts +3 -2
  198. package/dist/tasks/puzzle/backgroundBuffer.d.ts.map +1 -1
  199. package/dist/tasks/puzzle/backgroundBuffer.js +3 -3
  200. package/dist/tasks/puzzle/backgroundBuffer.js.map +1 -1
  201. package/dist/tasks/puzzle/nativeBackground.d.ts +5 -1
  202. package/dist/tasks/puzzle/nativeBackground.d.ts.map +1 -1
  203. package/dist/tasks/puzzle/nativeBackground.js +12 -5
  204. package/dist/tasks/puzzle/nativeBackground.js.map +1 -1
  205. package/dist/tasks/puzzle/puzzleRenderer.d.ts +2 -0
  206. package/dist/tasks/puzzle/puzzleRenderer.d.ts.map +1 -1
  207. package/dist/tasks/puzzle/puzzleRenderer.js +4 -3
  208. package/dist/tasks/puzzle/puzzleRenderer.js.map +1 -1
  209. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts +14 -16
  210. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
  211. package/dist/tasks/puzzleCaptcha/puzzleTasks.js +41 -494
  212. package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
  213. package/dist/tasks/spam/checkTrafficFilter.d.ts +4 -1
  214. package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
  215. package/dist/tasks/spam/checkTrafficFilter.js +18 -1
  216. package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
  217. package/dist/tasks/tasks.d.ts +4 -0
  218. package/dist/tasks/tasks.d.ts.map +1 -1
  219. package/dist/tasks/tasks.js +6 -0
  220. package/dist/tasks/tasks.js.map +1 -1
  221. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +7 -3
  222. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +1 -1
  223. package/dist/tests/integration/clientSettingsPersistence.integration.test.js +44 -2
  224. package/dist/tests/integration/clientSettingsPersistence.integration.test.js.map +1 -1
  225. package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js +4 -2
  226. package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js.map +1 -1
  227. package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js +76 -1
  228. package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js.map +1 -1
  229. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/constants.unit.test.js +54 -2
  230. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/constants.unit.test.js.map +1 -1
  231. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.d.ts +2 -0
  232. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.d.ts.map +1 -0
  233. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.js +45 -0
  234. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.js.map +1 -0
  235. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js +20 -0
  236. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js.map +1 -1
  237. package/dist/tests/unit/api/captcha/submitPoWCaptchaSolution.escalation.unit.test.js +15 -1
  238. package/dist/tests/unit/api/captcha/submitPoWCaptchaSolution.escalation.unit.test.js.map +1 -1
  239. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +174 -0
  240. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
  241. package/dist/tests/unit/api/rawTlsSignalsMiddleware.unit.test.js +96 -1
  242. package/dist/tests/unit/api/rawTlsSignalsMiddleware.unit.test.js.map +1 -1
  243. package/dist/tests/unit/compositeIpAddress.unit.test.js +12 -3
  244. package/dist/tests/unit/compositeIpAddress.unit.test.js.map +1 -1
  245. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.d.ts +2 -0
  246. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.d.ts.map +1 -0
  247. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.js +105 -0
  248. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.js.map +1 -0
  249. package/dist/tests/unit/tasks/audioAlternative.unit.test.d.ts +2 -0
  250. package/dist/tests/unit/tasks/audioAlternative.unit.test.d.ts.map +1 -0
  251. package/dist/tests/unit/tasks/audioAlternative.unit.test.js +76 -0
  252. package/dist/tests/unit/tasks/audioAlternative.unit.test.js.map +1 -0
  253. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.d.ts +2 -0
  254. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.d.ts.map +1 -0
  255. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.js +259 -0
  256. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.js.map +1 -0
  257. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.d.ts +2 -0
  258. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.d.ts.map +1 -0
  259. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.js +52 -0
  260. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.js.map +1 -0
  261. package/dist/tests/unit/tasks/captchaManager.unit.test.js +171 -2
  262. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
  263. package/dist/tests/unit/tasks/captchaTypeSelection.unit.test.js +68 -6
  264. package/dist/tests/unit/tasks/captchaTypeSelection.unit.test.js.map +1 -1
  265. package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.d.ts +2 -0
  266. package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.d.ts.map +1 -0
  267. package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.js +123 -0
  268. package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.js.map +1 -0
  269. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +31 -0
  270. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
  271. package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.d.ts +2 -0
  272. package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.d.ts.map +1 -0
  273. package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.js +103 -0
  274. package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.js.map +1 -0
  275. package/dist/tests/unit/tasks/frictionless/routerPuzzleOverrides.unit.test.js +28 -0
  276. package/dist/tests/unit/tasks/frictionless/routerPuzzleOverrides.unit.test.js.map +1 -1
  277. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.d.ts +2 -0
  278. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.d.ts.map +1 -0
  279. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.js +60 -0
  280. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.js.map +1 -0
  281. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.d.ts +2 -0
  282. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.d.ts.map +1 -0
  283. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.js +225 -0
  284. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.js.map +1 -0
  285. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +23 -1
  286. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +1 -1
  287. package/dist/tests/unit/tasks/puzzle/backgroundBuffer.unit.test.js +1 -4
  288. package/dist/tests/unit/tasks/puzzle/backgroundBuffer.unit.test.js.map +1 -1
  289. package/dist/tests/unit/tasks/puzzle/nativeBackground.unit.test.js +10 -3
  290. package/dist/tests/unit/tasks/puzzle/nativeBackground.unit.test.js.map +1 -1
  291. package/dist/tests/unit/tasks/puzzle/puzzleRenderer.unit.test.d.ts +2 -0
  292. package/dist/tests/unit/tasks/puzzle/puzzleRenderer.unit.test.d.ts.map +1 -0
  293. package/dist/tests/unit/tasks/puzzle/puzzleRenderer.unit.test.js +35 -0
  294. package/dist/tests/unit/tasks/puzzle/puzzleRenderer.unit.test.js.map +1 -0
  295. package/dist/tests/unit/tasks/puzzleDifficultyDeviceCap.unit.test.d.ts +2 -0
  296. package/dist/tests/unit/tasks/puzzleDifficultyDeviceCap.unit.test.d.ts.map +1 -0
  297. package/dist/tests/unit/tasks/puzzleDifficultyDeviceCap.unit.test.js +49 -0
  298. package/dist/tests/unit/tasks/puzzleDifficultyDeviceCap.unit.test.js.map +1 -0
  299. package/dist/tests/unit/testUtils/mockProviderEnv.d.ts +17 -14
  300. package/dist/tests/unit/testUtils/mockProviderEnv.d.ts.map +1 -1
  301. package/dist/tests/unit/testUtils/mockProviderEnv.js.map +1 -1
  302. package/dist/util.js +1 -1
  303. package/package.json +107 -103
@@ -1,27 +1,30 @@
1
- const require_usageCounters = require("../../util/usageCounters.cjs");
2
- const require_decisionMachineRunner = require("../decisionMachine/decisionMachineRunner.cjs");
3
- const require_clientMetaData = require("../../utils/clientMetaData.cjs");
4
- const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
5
- const require_enrichDnsEvent = require("../dnsEvent/enrichDnsEvent.cjs");
6
- const require_captchaManager = require("../captchaManager.cjs");
7
- const require_util = require("../../util.cjs");
8
- const require_devicePlatform = require("../../utils/devicePlatform.cjs");
9
- const require_frictionlessTasksUtils = require("../frictionless/frictionlessTasksUtils.cjs");
10
- const require_evaluateEmailSpamRules = require("../spam/evaluateEmailSpamRules.cjs");
11
- const require_powTasksUtils = require("../powCaptcha/powTasksUtils.cjs");
1
+ const require_interactiveCaptchaManager = require("../interactiveCaptcha/interactiveCaptchaManager.cjs");
12
2
  const require_puzzleTasksUtils = require("./puzzleTasksUtils.cjs");
13
- let _prosopo_common = require("@prosopo/common");
14
3
  let _prosopo_types = require("@prosopo/types");
15
- let _prosopo_util = require("@prosopo/util");
16
- let _prosopo_user_access_policy = require("@prosopo/user-access-policy");
17
- let _polkadot_util = require("@polkadot/util");
18
4
  //#region src/tasks/puzzleCaptcha/puzzleTasks.ts
19
- var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
20
- constructor(db, pair, config, logger, usageCounters) {
21
- super(db, pair, config, logger);
22
- this.POW_SEPARATOR = _prosopo_types.POW_SEPARATOR;
23
- this.decisionMachineRunner = new require_decisionMachineRunner.DecisionMachineRunner(db);
24
- this.usageCounters = usageCounters ?? null;
5
+ var PuzzleCaptchaManager = class extends require_interactiveCaptchaManager.InteractiveCaptchaManager {
6
+ constructor(..._args) {
7
+ super(..._args);
8
+ this.captchaType = _prosopo_types.CaptchaType.puzzle;
9
+ this.logLabel = "puzzle";
10
+ }
11
+ getRecordByChallenge(challenge) {
12
+ return this.db.getPuzzleCaptchaRecordByChallenge(challenge);
13
+ }
14
+ updateRecord(challenge, updates) {
15
+ return this.db.updatePuzzleCaptchaRecord(challenge, updates);
16
+ }
17
+ updateSubmissionResult(challenge, result, userSignature, coords) {
18
+ return this.db.updatePuzzleCaptchaRecordResult(challenge, result, false, true, userSignature, coords);
19
+ }
20
+ async claimSubmission(record) {
21
+ return !record.userSubmitted;
22
+ }
23
+ markRecordChecked(challenge) {
24
+ return this.db.markPuzzleCaptchaRecordChecked(challenge);
25
+ }
26
+ decisionMachineEventFields(record) {
27
+ return { puzzleEvents: record.puzzleEvents };
25
28
  }
26
29
  /**
27
30
  * @description Generates a Puzzle Captcha challenge for a given user and dapp
@@ -32,18 +35,15 @@ var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
32
35
  * @param tolerance
33
36
  */
34
37
  async getPuzzleCaptchaChallenge(userAccount, dappAccount, origin, tolerance) {
35
- const resolvedTolerance = tolerance ?? _prosopo_types.puzzleToleranceDefault;
36
- const requestedAtTimestamp = Date.now();
37
- const challenge = `${requestedAtTimestamp}___${userAccount}___${dappAccount}___${Math.floor(Math.random() * 1e6)}`;
38
- const challengeSignature = (0, _polkadot_util.u8aToHex)(this.pair.sign((0, _polkadot_util.stringToHex)(challenge)));
38
+ const { challenge, providerSignature, requestedAtTimestamp } = this.mintChallenge(userAccount, dappAccount);
39
39
  return {
40
40
  challenge,
41
41
  targetX: Math.floor(Math.random() * 131) + 150,
42
42
  targetY: Math.floor(Math.random() * 141) + 30,
43
43
  originX: Math.floor(Math.random() * 111) + 20,
44
44
  originY: Math.floor(Math.random() * 141) + 30,
45
- tolerance: resolvedTolerance,
46
- providerSignature: challengeSignature,
45
+ tolerance: tolerance ?? _prosopo_types.puzzleToleranceDefault,
46
+ providerSignature,
47
47
  requestedAtTimestamp
48
48
  };
49
49
  }
@@ -62,475 +62,22 @@ var PuzzleCaptchaManager = class extends require_captchaManager.CaptchaManager {
62
62
  * @param behavioralData
63
63
  */
64
64
  async verifyPuzzleCaptchaSolution(challenge, providerChallengeSignature, finalX, finalY, puzzleEvents, timeout, userTimestampSignature, ipAddress, headers, behavioralData, salt, simdReadings, clientMetaData) {
65
- require_powTasksUtils.checkPowSignature(challenge, providerChallengeSignature, this.pair.address, _prosopo_types.ApiParams.challenge);
66
- const challengeSplit = challenge.split(this.POW_SEPARATOR);
67
- const timestamp = Number.parseInt((0, _prosopo_util.at)(challengeSplit, 0));
68
- const userAccount = (0, _prosopo_util.at)(challengeSplit, 1);
69
- require_powTasksUtils.checkPowSignature(timestamp.toString(), userTimestampSignature, userAccount, _prosopo_types.ApiParams.timestamp);
70
- const challengeRecord = await this.db.getPuzzleCaptchaRecordByChallenge(challenge);
71
- if (!challengeRecord) {
72
- this.logger.debug(() => ({ msg: `No record of this challenge: ${challenge}` }));
73
- return false;
74
- }
75
- let coords;
76
- let saltDecodeError;
77
- if (salt) try {
78
- const extractedData = (0, _prosopo_util.extractData)(salt);
79
- if (extractedData.length >= 2) {
80
- const built = [[[extractedData[0], extractedData[1]]]];
81
- (0, _prosopo_util.assertCoordsSafe)(built, "coords");
82
- coords = built;
83
- }
84
- } catch (error) {
85
- saltDecodeError = error;
86
- this.logger.warn(() => ({
87
- msg: "Failed to extract coordinates from salt",
88
- error,
89
- salt
90
- }));
91
- }
92
- if (challengeRecord.userSubmitted) {
93
- this.logger.debug(() => ({ msg: `Challenge already submitted: ${challenge}` }));
94
- return false;
95
- }
96
- if (saltDecodeError) {
97
- const badSaltResult = {
98
- status: _prosopo_types.CaptchaStatus.disapproved,
99
- reason: _prosopo_types.ResultReason.CAPTCHA_INVALID_SALT
100
- };
101
- await this.db.updatePuzzleCaptchaRecordResult(challenge, badSaltResult, false, true, userTimestampSignature, void 0);
102
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
103
- userSubmitted: true,
104
- result: badSaltResult,
105
- ...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, badSaltResult) && { blocked: true }
106
- });
107
- return false;
108
- }
109
- if (!(0, _prosopo_util.verifyRecency)(challenge, timeout)) {
110
- const timeoutResult = {
111
- status: _prosopo_types.CaptchaStatus.disapproved,
112
- reason: _prosopo_types.ResultReason.CAPTCHA_INVALID_TIMESTAMP
113
- };
114
- await this.db.updatePuzzleCaptchaRecordResult(challenge, timeoutResult, false, true, userTimestampSignature, coords);
115
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
116
- userSubmitted: true,
117
- result: timeoutResult,
118
- ...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, timeoutResult) && { blocked: true }
119
- });
120
- return false;
121
- }
122
- const correct = require_puzzleTasksUtils.validatePuzzleSolution(finalX, finalY, challengeRecord.targetX, challengeRecord.targetY, challengeRecord.tolerance);
123
- let result = { status: _prosopo_types.CaptchaStatus.approved };
124
- if (!correct) result = {
125
- status: _prosopo_types.CaptchaStatus.disapproved,
126
- reason: _prosopo_types.ResultReason.CAPTCHA_INVALID_SOLUTION
127
- };
128
- if (correct && this.usageCounters) {
129
- const dappAccount = (0, _prosopo_util.at)(challengeSplit, 2);
130
- this.usageCounters.incrManyAsync(dappAccount, require_usageCounters.buildAllWindowIncrements("solved", _prosopo_types.CaptchaType.puzzle, ipAddress.address, userAccount));
131
- }
132
- await this.db.updatePuzzleCaptchaRecord(challenge, { puzzleEvents });
133
- const decodedPayloads = await this.decodeSubmissionPayloads(challengeRecord.sessionId, {
134
- behavioural: behavioralData,
135
- simd: simdReadings
65
+ return this.submitInteractiveCaptchaSolution({
66
+ challenge,
67
+ providerChallengeSignature,
68
+ timeout,
69
+ userTimestampSignature,
70
+ ipAddress,
71
+ behavioralData,
72
+ salt,
73
+ simdReadings,
74
+ clientMetaData,
75
+ isCorrect: (record) => require_puzzleTasksUtils.validatePuzzleSolution(finalX, finalY, record.targetX, record.targetY, record.tolerance),
76
+ persistInteraction: () => this.db.updatePuzzleCaptchaRecord(challenge, { puzzleEvents })
136
77
  });
137
- if (behavioralData) try {
138
- const decryptedData = decodedPayloads.behavioural;
139
- if (decryptedData) {
140
- const dappAccount = (0, _prosopo_util.at)(challengeSplit, 2);
141
- this.logger?.info(() => ({
142
- msg: "Behavioral analysis completed",
143
- data: {
144
- userAccount,
145
- dappAccount,
146
- challenge,
147
- mouseEventsCount: decryptedData.collector1?.length || 0,
148
- touchEventsCount: decryptedData.collector2?.length || 0,
149
- clickEventsCount: decryptedData.collector3?.length || 0,
150
- scrollEventsCount: decryptedData.collector4?.length || 0,
151
- deviceCapability: decryptedData.deviceCapability,
152
- captchaResult: correct ? "passed" : "failed"
153
- }
154
- }));
155
- const packedData = {
156
- c1: decryptedData.collector1 || [],
157
- c2: decryptedData.collector2 || [],
158
- c3: decryptedData.collector3 || [],
159
- c4: decryptedData.collector4 || [],
160
- d: decryptedData.deviceCapability
161
- };
162
- await this.db.updatePuzzleCaptchaRecord(challenge, {
163
- behavioralDataPacked: packedData,
164
- deviceCapability: decryptedData.deviceCapability
165
- });
166
- }
167
- } catch (error) {
168
- this.logger?.error(() => ({
169
- msg: "Failed to process behavioral data",
170
- err: error
171
- }));
172
- }
173
- const storedClientMetaData = require_clientMetaData.toStoredClientMetaData(clientMetaData);
174
- if (storedClientMetaData) await this.db.updatePuzzleCaptchaRecord(challenge, { clientMetaData: storedClientMetaData });
175
- await this.db.updatePuzzleCaptchaRecordResult(challenge, result, false, true, userTimestampSignature, coords);
176
- if (challengeRecord.sessionId) {
177
- const linkedSessionId = challengeRecord.sessionId;
178
- await this.updateSessionRecordWithCache(linkedSessionId, {
179
- userSubmitted: true,
180
- result,
181
- ...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, result) && { blocked: true },
182
- ...storedClientMetaData && { clientMetaData: storedClientMetaData }
183
- });
184
- if (decodedPayloads.simd) await this.recordSessionSimdReadingsIfAbsentWithCache(linkedSessionId, decodedPayloads.simd, _prosopo_types.SimdReadingsStage.submit);
185
- }
186
- return correct;
187
78
  }
188
- /**
189
- * @description Verifies a Puzzle Captcha for a given user and dapp. This is called by the server to verify the user's solution
190
- * and update the record in the database to show that the user has solved the captcha
191
- *
192
- * @param {string} dappAccount - the dapp that is requesting the captcha
193
- * @param {string} challenge - the challenge string
194
- * @param {number} timeout - the time in milliseconds since the Provider was selected to provide the captcha
195
- * @param env - provider environment
196
- * @param ip - optional IP address for validation
197
- * @param userAccessRulesStorage - storage for querying user access policies
198
- * @param email
199
- * @param spamEmailDomainCheckingEnabled
200
- * @param spamFilter
201
- * @param trafficFilter
202
- * @param storeMetadata - when true, persists the dapp-server-provided
203
- * `email` on the captcha record for spam-rate analysis.
204
- * @param clientSessionId - the session id the site rendered the widget
205
- * with. When supplied, the solve must carry the same value in its
206
- * `clientMetaData` or it is disapproved.
207
- */
208
79
  async serverVerifyPuzzleCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled = false, spamFilter, trafficFilter, storeMetadata = false, clientSessionId) {
209
- const notVerifiedResponse = { verified: false };
210
- const logger = this.logger.with({
211
- challenge,
212
- dappAccount
213
- });
214
- const challengeRecord = await this.db.getPuzzleCaptchaRecordByChallenge(challenge);
215
- if (!challengeRecord) {
216
- logger.debug(() => ({ msg: `No record of this challenge: ${challenge}` }));
217
- return notVerifiedResponse;
218
- }
219
- notVerifiedResponse.sessionId = challengeRecord.sessionId;
220
- if (challengeRecord.result.status !== _prosopo_types.CaptchaStatus.approved) throw new _prosopo_common.ProsopoApiError("CAPTCHA.INVALID_SOLUTION", { context: {
221
- code: 400,
222
- failedFuncName: this.serverVerifyPuzzleCaptchaSolution.name,
223
- challenge
224
- } });
225
- if (challengeRecord.serverChecked) return notVerifiedResponse;
226
- const challengeDappAccount = challengeRecord.dappAccount;
227
- if (dappAccount !== challengeDappAccount) throw new _prosopo_common.ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", { context: {
228
- failedFuncName: this.serverVerifyPuzzleCaptchaSolution.name,
229
- dappAccount,
230
- challengeDappAccount
231
- } });
232
- if (!await this.db.markPuzzleCaptchaRecordChecked(challengeRecord.challenge)) return notVerifiedResponse;
233
- const submittedAt = challengeRecord.submittedAtTimestamp;
234
- if ((submittedAt instanceof Date ? Date.now() - submittedAt.getTime() : Number.POSITIVE_INFINITY) > timeout) {
235
- const disapprovedResult = {
236
- status: _prosopo_types.CaptchaStatus.disapproved,
237
- reason: _prosopo_types.ResultReason.TIMESTAMP_TOO_OLD
238
- };
239
- const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, disapprovedResult);
240
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
241
- result: disapprovedResult,
242
- ...isBlocked && { blocked: true }
243
- });
244
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
245
- serverChecked: true,
246
- result: disapprovedResult,
247
- ...isBlocked && { blocked: true }
248
- });
249
- return notVerifiedResponse;
250
- }
251
- if (require_clientMetaData.isClientSessionMismatch(clientSessionId, challengeRecord.clientMetaData?.clientSessionId)) {
252
- logger.info(() => ({
253
- msg: "Client session mismatch in server puzzle verification",
254
- data: { hasRecordedClientSessionId: Boolean(challengeRecord.clientMetaData?.clientSessionId) }
255
- }));
256
- const mismatchResult = {
257
- status: _prosopo_types.CaptchaStatus.disapproved,
258
- reason: _prosopo_types.ResultReason.CLIENT_SESSION_MISMATCH
259
- };
260
- const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, mismatchResult);
261
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
262
- result: mismatchResult,
263
- ...isBlocked && { blocked: true }
264
- });
265
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
266
- serverChecked: true,
267
- result: mismatchResult,
268
- ...isBlocked && { blocked: true }
269
- });
270
- return notVerifiedResponse;
271
- }
272
- if (userAccessRulesStorage) try {
273
- const blockPolicy = await this.checkForHardBlock(userAccessRulesStorage, challengeRecord, challengeRecord.userAccount, challengeRecord.headers, challengeRecord.coords, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0, challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.asnNumber : void 0);
274
- if (blockPolicy) {
275
- logger.info(() => ({
276
- msg: "User blocked by access policy in server puzzle verification",
277
- data: {
278
- userAccount: challengeRecord.userAccount,
279
- policy: blockPolicy
280
- }
281
- }));
282
- const blockedResult = {
283
- status: _prosopo_types.CaptchaStatus.disapproved,
284
- reason: _prosopo_types.ResultReason.ACCESS_POLICY_BLOCK
285
- };
286
- const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, blockedResult);
287
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
288
- result: blockedResult,
289
- ...isBlocked && { blocked: true }
290
- });
291
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
292
- serverChecked: true,
293
- result: blockedResult,
294
- ...isBlocked && { blocked: true },
295
- matchedRule: (0, _prosopo_user_access_policy.describeMatchedRule)(blockPolicy)
296
- });
297
- return notVerifiedResponse;
298
- }
299
- } catch (error) {
300
- logger.warn(() => ({
301
- msg: "Failed to check user access policies in server puzzle verification",
302
- error
303
- }));
304
- }
305
- if (email && spamEmailDomainCheckingEnabled) try {
306
- if (await this.checkSpamEmail(email)) {
307
- const emailDomain = email.split("@")[1] || "unknown";
308
- logger.info(() => ({
309
- msg: "Spam email domain detected in server puzzle verification",
310
- data: { emailDomain }
311
- }));
312
- const spamResult = {
313
- status: _prosopo_types.CaptchaStatus.disapproved,
314
- reason: _prosopo_types.ResultReason.SPAM_EMAIL_DOMAIN
315
- };
316
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
317
- result: spamResult,
318
- ...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, spamResult) && { blocked: true }
319
- });
320
- return notVerifiedResponse;
321
- }
322
- } catch (error) {
323
- logger.warn(() => ({
324
- msg: "Failed to check spam email domain in server puzzle verification",
325
- error
326
- }));
327
- }
328
- const maxEmailSubmissionCount = spamFilter?.enabled && spamFilter.emailRules?.enabled ? spamFilter.emailRules.maxEmailSubmissionCount : void 0;
329
- let emailNormalised;
330
- if (maxEmailSubmissionCount !== void 0 && email && storeMetadata) {
331
- emailNormalised = require_evaluateEmailSpamRules.normaliseEmailForMatching(email);
332
- if (emailNormalised) try {
333
- const priorCount = await this.db.countCommitmentsByNormalisedEmail(dappAccount, emailNormalised);
334
- if (priorCount >= maxEmailSubmissionCount) {
335
- logger.info(() => ({
336
- msg: "Email submission count exceeded in server puzzle verification",
337
- data: {
338
- priorCount,
339
- maxEmailSubmissionCount
340
- }
341
- }));
342
- const spamCountResult = {
343
- status: _prosopo_types.CaptchaStatus.disapproved,
344
- reason: _prosopo_types.ResultReason.SPAM_EMAIL_COUNT_EXCEEDED
345
- };
346
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
347
- result: spamCountResult,
348
- ...(0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, spamCountResult) && { blocked: true }
349
- });
350
- return notVerifiedResponse;
351
- }
352
- } catch (error) {
353
- logger.warn(() => ({
354
- msg: "Failed to check email submission count in server puzzle verification",
355
- error
356
- }));
357
- }
358
- }
359
- const sessionRecord = challengeRecord.sessionId ? await this.getSessionRecordWithOriginFallback(challengeRecord.sessionId) : void 0;
360
- const enrichedDnsEvent = await require_enrichDnsEvent.enrichDnsEvent(sessionRecord?.dnsEvent, env.ipInfoService, ip ?? challengeRecord.ipInfo?.ip);
361
- {
362
- const check = await this.resolveTrafficFilterCheck(env, challengeRecord.ipInfo, trafficFilter, ip, enrichedDnsEvent);
363
- if (check.isBlocked) {
364
- logger.info(() => ({
365
- msg: "Traffic filter rejected request in puzzle verification",
366
- data: {
367
- ip,
368
- reason: check.reason,
369
- dnsPeerIp: enrichedDnsEvent?.peerIp,
370
- dnsResolverIp: enrichedDnsEvent?.resolverIp,
371
- dnsPeerAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.peerIpInfo),
372
- dnsResolverAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.resolverIpInfo),
373
- dnsPathValid: enrichedDnsEvent?.pathValid
374
- }
375
- }));
376
- const blockedResult = {
377
- status: _prosopo_types.CaptchaStatus.disapproved,
378
- reason: check.reason
379
- };
380
- const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, blockedResult);
381
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
382
- result: blockedResult,
383
- ...isBlocked && { blocked: true }
384
- });
385
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
386
- serverChecked: true,
387
- result: blockedResult,
388
- ...isBlocked && { blocked: true }
389
- });
390
- return notVerifiedResponse;
391
- }
392
- }
393
- if (storeMetadata && email) await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, { metadata: {
394
- email,
395
- emailNormalised: emailNormalised ?? require_evaluateEmailSpamRules.normaliseEmailForMatching(email)
396
- } });
397
- if (ip) {
398
- const challengeIpAddress = require_compositeIpAddress.getIpAddressFromComposite(challengeRecord.ipAddress);
399
- const ipValidationRules = (await this.db.getClientRecord(dappAccount))?.settings?.ipValidationRules;
400
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, { providedIp: require_compositeIpAddress.getCompositeIpAddress(ip) });
401
- if (ipValidationRules?.enabled === true) {
402
- const ipValidation = await require_util.deepValidateIpAddress(ip, challengeIpAddress, logger, env.ipInfoService, ipValidationRules, enrichedDnsEvent?.peerIp);
403
- if (!ipValidation.isValid) {
404
- logger.error(() => ({
405
- msg: "IP validation failed for puzzle captcha",
406
- data: {
407
- ip,
408
- challengeIp: challengeIpAddress.address,
409
- error: ipValidation.errorMessage,
410
- distanceKm: ipValidation.distanceKm
411
- }
412
- }));
413
- const ipFailResult = {
414
- status: _prosopo_types.CaptchaStatus.disapproved,
415
- reason: _prosopo_types.ResultReason.FAILED_IP_VALIDATION
416
- };
417
- const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, ipFailResult);
418
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
419
- result: ipFailResult,
420
- ...isBlocked && { blocked: true }
421
- });
422
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
423
- serverChecked: true,
424
- result: ipFailResult,
425
- ...isBlocked && { blocked: true }
426
- });
427
- return notVerifiedResponse;
428
- }
429
- }
430
- }
431
- let score;
432
- if (sessionRecord) {
433
- const dnsAsymmetry = require_enrichDnsEvent.computeDnsAsymmetry(enrichedDnsEvent, challengeRecord.ipInfo, trafficFilter);
434
- if (dnsAsymmetry > 0) sessionRecord.scoreComponents = {
435
- ...sessionRecord.scoreComponents,
436
- dnsAsymmetry
437
- };
438
- score = require_frictionlessTasksUtils.computeFrictionlessScore(sessionRecord?.scoreComponents);
439
- logger.info(() => ({ data: {
440
- scoreComponents: { ...sessionRecord?.scoreComponents || {} },
441
- score,
442
- dnsPeerAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.peerIpInfo),
443
- dnsResolverAsn: require_enrichDnsEvent.getIpInfoAsn(enrichedDnsEvent?.resolverIpInfo)
444
- } }));
445
- }
446
- try {
447
- const decisionInput = {
448
- userAccount: challengeRecord.userAccount,
449
- dappAccount: challengeRecord.dappAccount,
450
- captchaResult: "passed",
451
- headers: challengeRecord.headers,
452
- captchaType: _prosopo_types.CaptchaType.puzzle,
453
- behavioralDataPacked: challengeRecord.behavioralDataPacked,
454
- deviceCapability: challengeRecord.deviceCapability,
455
- countryCode: challengeRecord.ipInfo?.isValid ? challengeRecord.ipInfo.countryCode : void 0,
456
- ipInfo: challengeRecord.ipInfo,
457
- dnsEvent: enrichedDnsEvent,
458
- score,
459
- threshold: sessionRecord?.threshold,
460
- scoreComponents: sessionRecord?.scoreComponents,
461
- decryptedHeadHash: sessionRecord?.decryptedHeadHash,
462
- userSitekeyIpHash: sessionRecord?.userSitekeyIpHash,
463
- simdReadings: sessionRecord?.simdReadings,
464
- d: sessionRecord?.d,
465
- frictionlessReason: sessionRecord?.reason,
466
- ruleType: sessionRecord?.ruleType,
467
- webView: sessionRecord?.webView,
468
- iFrame: sessionRecord?.iFrame,
469
- currentUrl: sessionRecord?.currentUrl,
470
- iframeUrl: sessionRecord?.iframeUrl,
471
- coords: challengeRecord.coords,
472
- puzzleEvents: challengeRecord.puzzleEvents,
473
- synNs: sessionRecord?.synNs,
474
- synackNs: sessionRecord?.synackNs,
475
- ackNs: sessionRecord?.ackNs,
476
- observedTtl: sessionRecord?.observedTtl,
477
- tcpMss: sessionRecord?.tcpMss,
478
- tcpWscale: sessionRecord?.tcpWscale,
479
- tcpOptsFlags: sessionRecord?.tcpOptsFlags,
480
- tcpOptsOrder: sessionRecord?.tcpOptsOrder,
481
- tcpWindow: sessionRecord?.tcpWindow,
482
- trafficPolicies: require_devicePlatform.deriveTrafficPolicies(trafficFilter)
483
- };
484
- const decision = await this.decisionMachineRunner.decide(decisionInput, logger);
485
- if (decision.decision === _prosopo_types.DecisionMachineDecision.Deny) {
486
- logger.info(() => ({
487
- msg: "Decision machine denied puzzle captcha in server verification",
488
- data: {
489
- userAccount: challengeRecord.userAccount,
490
- reason: decision.reason,
491
- score: decision.score,
492
- tags: decision.tags
493
- }
494
- }));
495
- const dmResult = {
496
- status: _prosopo_types.CaptchaStatus.disapproved,
497
- reason: decision.reason || _prosopo_types.ResultReason.CAPTCHA_DECISION_MACHINE_DENIED
498
- };
499
- const isBlocked = (0, _prosopo_types.isBlockingCaptchaResult)(_prosopo_types.CaptchaType.puzzle, dmResult);
500
- await this.db.updatePuzzleCaptchaRecord(challengeRecord.challenge, {
501
- result: dmResult,
502
- ...isBlocked && { blocked: true }
503
- });
504
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
505
- serverChecked: true,
506
- result: dmResult,
507
- ...isBlocked && { blocked: true }
508
- });
509
- return notVerifiedResponse;
510
- }
511
- logger.debug(() => ({
512
- msg: "Decision machine allowed puzzle captcha",
513
- data: {
514
- reason: decision.reason,
515
- score: decision.score,
516
- tags: decision.tags
517
- }
518
- }));
519
- } catch (error) {
520
- logger.error(() => ({
521
- msg: "Failed to run decision machine in server puzzle verification",
522
- err: error
523
- }));
524
- }
525
- if (challengeRecord.sessionId) await this.updateSessionRecordWithCache(challengeRecord.sessionId, {
526
- serverChecked: true,
527
- result: { status: _prosopo_types.CaptchaStatus.approved }
528
- });
529
- return {
530
- verified: true,
531
- ...score ? { score } : {},
532
- ...challengeRecord.sessionId && { sessionId: challengeRecord.sessionId }
533
- };
80
+ return this.serverVerifyInteractiveCaptchaSolution(dappAccount, challenge, timeout, env, ip, userAccessRulesStorage, email, spamEmailDomainCheckingEnabled, spamFilter, trafficFilter, storeMetadata, clientSessionId);
534
81
  }
535
82
  };
536
83
  //#endregion
@@ -131,6 +131,8 @@ var checkTrafficFilter = (ipInfo, trafficFilter, extraIpInfos, dnsPathValid) =>
131
131
  matches
132
132
  };
133
133
  };
134
+ /** A lower tolerance is a smaller hit radius, so the strictest is the minimum. */
135
+ var strictestTolerance = (current, next) => next === void 0 || current === void 0 ? next ?? current : Math.min(current, next);
134
136
  /**
135
137
  * Combine the `challenge` matches into a single effective policy: pick the
136
138
  * strictest captcha type, then take the hardest params (max difficulty,
@@ -147,14 +149,26 @@ var resolveChallengePolicy = (matches) => {
147
149
  let solvedImagesCount;
148
150
  let puzzleTolerance;
149
151
  let puzzleSettings;
152
+ let audioSettings;
153
+ let iconOrderTolerance;
154
+ let iconOrderSettings;
150
155
  for (const m of challenges) {
151
156
  if (m.policy.powDifficulty !== void 0) powDifficulty = powDifficulty === void 0 ? m.policy.powDifficulty : Math.max(powDifficulty, m.policy.powDifficulty);
152
157
  if (m.policy.solvedImagesCount !== void 0) solvedImagesCount = solvedImagesCount === void 0 ? m.policy.solvedImagesCount : Math.max(solvedImagesCount, m.policy.solvedImagesCount);
153
- if (m.policy.puzzleTolerance !== void 0) puzzleTolerance = puzzleTolerance === void 0 ? m.policy.puzzleTolerance : Math.min(puzzleTolerance, m.policy.puzzleTolerance);
158
+ puzzleTolerance = strictestTolerance(puzzleTolerance, m.policy.puzzleTolerance);
154
159
  if (m.policy.puzzle) puzzleSettings = {
155
160
  ...puzzleSettings ?? {},
156
161
  ...m.policy.puzzle
157
162
  };
163
+ if (m.policy.audio) audioSettings = {
164
+ ...audioSettings ?? {},
165
+ ...m.policy.audio
166
+ };
167
+ iconOrderTolerance = strictestTolerance(iconOrderTolerance, m.policy.iconOrderTolerance);
168
+ if (m.policy.iconOrder) iconOrderSettings = {
169
+ ...iconOrderSettings ?? {},
170
+ ...m.policy.iconOrder
171
+ };
158
172
  }
159
173
  return {
160
174
  captchaType: winningCaptchaType,
@@ -162,6 +176,9 @@ var resolveChallengePolicy = (matches) => {
162
176
  solvedImagesCount,
163
177
  puzzleTolerance,
164
178
  puzzleSettings,
179
+ audioSettings,
180
+ iconOrderTolerance,
181
+ iconOrderSettings,
165
182
  sourceCategories: challenges.map((m) => m.category)
166
183
  };
167
184
  };
@@ -1,8 +1,10 @@
1
1
  const require_usageCounters = require("../util/usageCounters.cjs");
2
2
  const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
3
+ const require_audioTasks = require("./audioCaptcha/audioTasks.cjs");
3
4
  const require_clientTasks = require("./client/clientTasks.cjs");
4
5
  const require_datasetTasks = require("./dataset/datasetTasks.cjs");
5
6
  const require_frictionlessTasks = require("./frictionless/frictionlessTasks.cjs");
7
+ const require_iconOrderTasks = require("./iconOrderCaptcha/iconOrderTasks.cjs");
6
8
  const require_imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
7
9
  const require_powTasks = require("./powCaptcha/powTasks.cjs");
8
10
  const require_puzzleTasks = require("./puzzleCaptcha/puzzleTasks.cjs");
@@ -33,6 +35,8 @@ var Tasks = class {
33
35
  this.usageCounters = this.initUsageCounters();
34
36
  this.powCaptchaManager = new require_powTasks.PowCaptchaManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.usageCounters);
35
37
  this.puzzleCaptchaManager = new require_puzzleTasks.PuzzleCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
38
+ this.audioCaptchaManager = new require_audioTasks.AudioCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
39
+ this.iconOrderCaptchaManager = new require_iconOrderTasks.IconOrderCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
36
40
  this.datasetManager = new require_datasetTasks.DatasetManager(this.config, this.logger, this.captchaConfig, this.db);
37
41
  this.imgCaptchaManager = new require_imgCaptchaTasks.ImgCaptchaManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.usageCounters);
38
42
  this.clientTaskManager = new require_clientTasks.ClientTaskManager(this.config, this.logger, this.db);
@@ -62,6 +66,8 @@ var Tasks = class {
62
66
  this.logger = logger;
63
67
  this.powCaptchaManager.logger = logger;
64
68
  this.puzzleCaptchaManager.logger = logger;
69
+ this.audioCaptchaManager.logger = logger;
70
+ this.iconOrderCaptchaManager.logger = logger;
65
71
  this.datasetManager.logger = logger;
66
72
  this.imgCaptchaManager.logger = logger;
67
73
  this.clientTaskManager.logger = logger;
package/dist/cjs/util.cjs CHANGED
@@ -2,10 +2,10 @@ const require_ipComparison = require("./services/ipComparison.cjs");
2
2
  let _prosopo_common = require("@prosopo/common");
3
3
  let _prosopo_types = require("@prosopo/types");
4
4
  let _prosopo_util = require("@prosopo/util");
5
- let _prosopo_util_crypto = require("@prosopo/util-crypto");
6
5
  let ip_address = require("ip-address");
7
6
  let _polkadot_util_hex = require("@polkadot/util/hex");
8
7
  let _polkadot_util_is = require("@polkadot/util/is");
8
+ let _prosopo_util_crypto = require("@prosopo/util-crypto");
9
9
  //#region src/util.ts
10
10
  function encodeStringAddress(address) {
11
11
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"compositeIpAddress.d.ts","sourceRoot":"","sources":["../src/compositeIpAddress.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;AAOxE,eAAO,MAAM,qBAAqB,OAC7B,MAAM,GAAG,SAAS,KACpB,kBAaF,CAAC;AAuBF,eAAO,MAAM,yBAAyB,uBACjB,kBAAkB,KACpC,SAaF,CAAC;AAuCF,eAAO,MAAM,cAAc,MACvB,kBAAkB,KAClB,kBAAkB,KACnB,OAiBF,CAAC"}
1
+ {"version":3,"file":"compositeIpAddress.d.ts","sourceRoot":"","sources":["../src/compositeIpAddress.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;AAaxE,eAAO,MAAM,qBAAqB,OAC7B,MAAM,GAAG,SAAS,KACpB,kBAaF,CAAC;AAuBF,eAAO,MAAM,yBAAyB,uBACjB,kBAAkB,KACpC,SAaF,CAAC;AAgDF,eAAO,MAAM,cAAc,MACvB,kBAAkB,KAClB,kBAAkB,KACnB,OAoBF,CAAC"}