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