@prosopo/provider 5.15.0 → 5.17.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 (236) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +52 -34
  2. package/.turbo/turbo-build$colon$tsc.log +36 -30
  3. package/.turbo/turbo-build.log +53 -35
  4. package/CHANGELOG.md +94 -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/constants.d.ts +1 -0
  15. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.d.ts.map +1 -1
  16. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js +7 -2
  17. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js.map +1 -1
  18. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +1 -1
  19. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
  20. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +17 -12
  21. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
  22. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.d.ts +7 -2
  23. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.d.ts.map +1 -1
  24. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.js +14 -4
  25. package/dist/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.js.map +1 -1
  26. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.d.ts.map +1 -1
  27. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +1 -0
  28. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js.map +1 -1
  29. package/dist/api/captcha/getIconOrderCaptchaChallenge.d.ts +5 -0
  30. package/dist/api/captcha/getIconOrderCaptchaChallenge.d.ts.map +1 -0
  31. package/dist/api/captcha/getIconOrderCaptchaChallenge.js +37 -0
  32. package/dist/api/captcha/getIconOrderCaptchaChallenge.js.map +1 -0
  33. package/dist/api/captcha/getImageCaptchaChallenge.js +2 -2
  34. package/dist/api/captcha/getPoWCaptchaChallenge.js +4 -4
  35. package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts +1 -3
  36. package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts.map +1 -1
  37. package/dist/api/captcha/getPuzzleCaptchaChallenge.js +55 -170
  38. package/dist/api/captcha/getPuzzleCaptchaChallenge.js.map +1 -1
  39. package/dist/api/captcha/interactiveCaptchaChallenge.d.ts +42 -0
  40. package/dist/api/captcha/interactiveCaptchaChallenge.d.ts.map +1 -0
  41. package/dist/api/captcha/interactiveCaptchaChallenge.js +154 -0
  42. package/dist/api/captcha/interactiveCaptchaChallenge.js.map +1 -0
  43. package/dist/api/captcha/interactiveCaptchaSolution.d.ts +14 -0
  44. package/dist/api/captcha/interactiveCaptchaSolution.d.ts.map +1 -0
  45. package/dist/api/captcha/interactiveCaptchaSolution.js +77 -0
  46. package/dist/api/captcha/interactiveCaptchaSolution.js.map +1 -0
  47. package/dist/api/captcha/maintenanceModeResponses.d.ts +4 -2
  48. package/dist/api/captcha/maintenanceModeResponses.d.ts.map +1 -1
  49. package/dist/api/captcha/maintenanceModeResponses.js +28 -1
  50. package/dist/api/captcha/maintenanceModeResponses.js.map +1 -1
  51. package/dist/api/captcha/submitAudioCaptchaSolution.d.ts +4 -0
  52. package/dist/api/captcha/submitAudioCaptchaSolution.d.ts.map +1 -0
  53. package/dist/api/captcha/submitAudioCaptchaSolution.js +11 -0
  54. package/dist/api/captcha/submitAudioCaptchaSolution.js.map +1 -0
  55. package/dist/api/captcha/submitIconOrderCaptchaSolution.d.ts +4 -0
  56. package/dist/api/captcha/submitIconOrderCaptchaSolution.d.ts.map +1 -0
  57. package/dist/api/captcha/submitIconOrderCaptchaSolution.js +11 -0
  58. package/dist/api/captcha/submitIconOrderCaptchaSolution.js.map +1 -0
  59. package/dist/api/captcha/submitPoWCaptchaSolution.js +2 -2
  60. package/dist/api/captcha/submitPuzzleCaptchaSolution.d.ts +1 -3
  61. package/dist/api/captcha/submitPuzzleCaptchaSolution.d.ts.map +1 -1
  62. package/dist/api/captcha/submitPuzzleCaptchaSolution.js +6 -73
  63. package/dist/api/captcha/submitPuzzleCaptchaSolution.js.map +1 -1
  64. package/dist/api/captcha/trafficFilterRequestTime.d.ts +4 -1
  65. package/dist/api/captcha/trafficFilterRequestTime.d.ts.map +1 -1
  66. package/dist/api/captcha/trafficFilterRequestTime.js +3 -0
  67. package/dist/api/captcha/trafficFilterRequestTime.js.map +1 -1
  68. package/dist/api/captcha.d.ts.map +1 -1
  69. package/dist/api/captcha.js +8 -0
  70. package/dist/api/captcha.js.map +1 -1
  71. package/dist/api/domainMiddleware.js +1 -1
  72. package/dist/api/ja4Middleware.js +1 -1
  73. package/dist/api/startProviderApi.js +1 -1
  74. package/dist/api/verify.d.ts.map +1 -1
  75. package/dist/api/verify.js +153 -96
  76. package/dist/api/verify.js.map +1 -1
  77. package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +65 -2
  78. package/dist/cjs/api/blacklistRequestInspector.cjs +2 -2
  79. package/dist/cjs/api/captcha/getAudioCaptchaChallenge.cjs +37 -0
  80. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/constants.cjs +6 -0
  81. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +1 -1
  82. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +15 -10
  83. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.cjs +14 -3
  84. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +1 -0
  85. package/dist/cjs/api/captcha/getIconOrderCaptchaChallenge.cjs +37 -0
  86. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +2 -2
  87. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +4 -4
  88. package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +54 -169
  89. package/dist/cjs/api/captcha/interactiveCaptchaChallenge.cjs +154 -0
  90. package/dist/cjs/api/captcha/interactiveCaptchaSolution.cjs +77 -0
  91. package/dist/cjs/api/captcha/maintenanceModeResponses.cjs +29 -0
  92. package/dist/cjs/api/captcha/submitAudioCaptchaSolution.cjs +11 -0
  93. package/dist/cjs/api/captcha/submitIconOrderCaptchaSolution.cjs +11 -0
  94. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +2 -2
  95. package/dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs +6 -73
  96. package/dist/cjs/api/captcha/trafficFilterRequestTime.cjs +3 -0
  97. package/dist/cjs/api/captcha.cjs +8 -0
  98. package/dist/cjs/api/domainMiddleware.cjs +1 -1
  99. package/dist/cjs/api/ja4Middleware.cjs +1 -1
  100. package/dist/cjs/api/startProviderApi.cjs +1 -1
  101. package/dist/cjs/api/verify.cjs +152 -95
  102. package/dist/cjs/index.cjs +1 -1
  103. package/dist/cjs/tasks/audio/audioBuffer.cjs +72 -0
  104. package/dist/cjs/tasks/audio/audioRenderer.cjs +32 -0
  105. package/dist/cjs/tasks/audioAlternative.cjs +23 -0
  106. package/dist/cjs/tasks/audioCaptcha/audioTasks.cjs +65 -0
  107. package/dist/cjs/tasks/audioCaptcha/audioTasksUtils.cjs +19 -0
  108. package/dist/cjs/tasks/captchaManager.cjs +14 -2
  109. package/dist/cjs/tasks/captchaTypeSelection.cjs +20 -3
  110. package/dist/cjs/tasks/client/clientTasks.cjs +2 -2
  111. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +40 -9
  112. package/dist/cjs/tasks/iconOrder/iconOrderRenderer.cjs +42 -0
  113. package/dist/cjs/tasks/iconOrderCaptcha/iconOrderTasks.cjs +69 -0
  114. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +8 -8
  115. package/dist/cjs/tasks/interactiveCaptcha/interactiveCaptchaManager.cjs +423 -0
  116. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +8 -8
  117. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +1 -1
  118. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +40 -486
  119. package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +18 -1
  120. package/dist/cjs/tasks/tasks.cjs +6 -0
  121. package/dist/cjs/util.cjs +1 -1
  122. package/dist/index.js +2 -2
  123. package/dist/tasks/audio/audioBuffer.d.ts +23 -0
  124. package/dist/tasks/audio/audioBuffer.d.ts.map +1 -0
  125. package/dist/tasks/audio/audioBuffer.js +70 -0
  126. package/dist/tasks/audio/audioBuffer.js.map +1 -0
  127. package/dist/tasks/audio/audioRenderer.d.ts +11 -0
  128. package/dist/tasks/audio/audioRenderer.d.ts.map +1 -0
  129. package/dist/tasks/audio/audioRenderer.js +31 -0
  130. package/dist/tasks/audio/audioRenderer.js.map +1 -0
  131. package/dist/tasks/audioAlternative.d.ts +8 -0
  132. package/dist/tasks/audioAlternative.d.ts.map +1 -0
  133. package/dist/tasks/audioAlternative.js +20 -0
  134. package/dist/tasks/audioAlternative.js.map +1 -0
  135. package/dist/tasks/audioCaptcha/audioTasks.d.ts +19 -0
  136. package/dist/tasks/audioCaptcha/audioTasks.d.ts.map +1 -0
  137. package/dist/tasks/audioCaptcha/audioTasks.js +65 -0
  138. package/dist/tasks/audioCaptcha/audioTasks.js.map +1 -0
  139. package/dist/tasks/audioCaptcha/audioTasksUtils.d.ts +3 -0
  140. package/dist/tasks/audioCaptcha/audioTasksUtils.d.ts.map +1 -0
  141. package/dist/tasks/audioCaptcha/audioTasksUtils.js +18 -0
  142. package/dist/tasks/audioCaptcha/audioTasksUtils.js.map +1 -0
  143. package/dist/tasks/captchaManager.d.ts +9 -3
  144. package/dist/tasks/captchaManager.d.ts.map +1 -1
  145. package/dist/tasks/captchaManager.js +15 -3
  146. package/dist/tasks/captchaManager.js.map +1 -1
  147. package/dist/tasks/captchaTypeSelection.d.ts +2 -1
  148. package/dist/tasks/captchaTypeSelection.d.ts.map +1 -1
  149. package/dist/tasks/captchaTypeSelection.js +21 -5
  150. package/dist/tasks/captchaTypeSelection.js.map +1 -1
  151. package/dist/tasks/client/clientTasks.js +2 -2
  152. package/dist/tasks/frictionless/frictionlessTasks.d.ts +5 -0
  153. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
  154. package/dist/tasks/frictionless/frictionlessTasks.js +41 -10
  155. package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
  156. package/dist/tasks/iconOrder/iconOrderRenderer.d.ts +12 -0
  157. package/dist/tasks/iconOrder/iconOrderRenderer.d.ts.map +1 -0
  158. package/dist/tasks/iconOrder/iconOrderRenderer.js +40 -0
  159. package/dist/tasks/iconOrder/iconOrderRenderer.js.map +1 -0
  160. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.d.ts +22 -0
  161. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.d.ts.map +1 -0
  162. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.js +69 -0
  163. package/dist/tasks/iconOrderCaptcha/iconOrderTasks.js.map +1 -0
  164. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +8 -8
  165. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts +52 -0
  166. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.d.ts.map +1 -0
  167. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js +423 -0
  168. package/dist/tasks/interactiveCaptcha/interactiveCaptchaManager.js.map +1 -0
  169. package/dist/tasks/powCaptcha/powTasks.js +8 -8
  170. package/dist/tasks/powCaptcha/powTasksUtils.js +1 -1
  171. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts +14 -16
  172. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
  173. package/dist/tasks/puzzleCaptcha/puzzleTasks.js +41 -487
  174. package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
  175. package/dist/tasks/spam/checkTrafficFilter.d.ts +4 -1
  176. package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
  177. package/dist/tasks/spam/checkTrafficFilter.js +18 -1
  178. package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
  179. package/dist/tasks/tasks.d.ts +4 -0
  180. package/dist/tasks/tasks.d.ts.map +1 -1
  181. package/dist/tasks/tasks.js +6 -0
  182. package/dist/tasks/tasks.js.map +1 -1
  183. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +7 -3
  184. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +1 -1
  185. package/dist/tests/integration/clientSettingsPersistence.integration.test.js +45 -3
  186. package/dist/tests/integration/clientSettingsPersistence.integration.test.js.map +1 -1
  187. package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js +4 -2
  188. package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js.map +1 -1
  189. package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js +76 -1
  190. package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js.map +1 -1
  191. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/constants.unit.test.js +27 -8
  192. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/constants.unit.test.js.map +1 -1
  193. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.js +29 -3
  194. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.unit.test.js.map +1 -1
  195. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js +20 -0
  196. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js.map +1 -1
  197. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +81 -2
  198. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
  199. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.d.ts +2 -0
  200. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.d.ts.map +1 -0
  201. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.js +105 -0
  202. package/dist/tests/unit/tasks/audio/audioBuffer.unit.test.js.map +1 -0
  203. package/dist/tests/unit/tasks/audioAlternative.unit.test.d.ts +2 -0
  204. package/dist/tests/unit/tasks/audioAlternative.unit.test.d.ts.map +1 -0
  205. package/dist/tests/unit/tasks/audioAlternative.unit.test.js +76 -0
  206. package/dist/tests/unit/tasks/audioAlternative.unit.test.js.map +1 -0
  207. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.d.ts +2 -0
  208. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.d.ts.map +1 -0
  209. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.js +259 -0
  210. package/dist/tests/unit/tasks/audioCaptcha/audioTasks.unit.test.js.map +1 -0
  211. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.d.ts +2 -0
  212. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.d.ts.map +1 -0
  213. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.js +52 -0
  214. package/dist/tests/unit/tasks/audioCaptcha/audioTasksUtils.unit.test.js.map +1 -0
  215. package/dist/tests/unit/tasks/captchaManager.unit.test.js +120 -2
  216. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
  217. package/dist/tests/unit/tasks/captchaTypeSelection.unit.test.js +65 -6
  218. package/dist/tests/unit/tasks/captchaTypeSelection.unit.test.js.map +1 -1
  219. package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.js +29 -0
  220. package/dist/tests/unit/tasks/frictionless/allowedCaptchaTypes.unit.test.js.map +1 -1
  221. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +31 -0
  222. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
  223. package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.js +27 -2
  224. package/dist/tests/unit/tasks/frictionless/refreshSwitch.unit.test.js.map +1 -1
  225. package/dist/tests/unit/tasks/frictionless/routerPuzzleOverrides.unit.test.js +28 -0
  226. package/dist/tests/unit/tasks/frictionless/routerPuzzleOverrides.unit.test.js.map +1 -1
  227. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.d.ts +2 -0
  228. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.d.ts.map +1 -0
  229. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.js +60 -0
  230. package/dist/tests/unit/tasks/iconOrder/iconOrderRenderer.unit.test.js.map +1 -0
  231. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.d.ts +2 -0
  232. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.d.ts.map +1 -0
  233. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.js +225 -0
  234. package/dist/tests/unit/tasks/iconOrderCaptcha/iconOrderTasks.unit.test.js.map +1 -0
  235. package/dist/util.js +1 -1
  236. package/package.json +19 -17
@@ -1,3 +1,4 @@
1
+ let _prosopo_types = require("@prosopo/types");
1
2
  //#region src/api/captcha/getFrictionlessCaptchaChallenge/refreshLineage.ts
2
3
  /**
3
4
  * Work out where a refresh sits in its chain from the session it replaced.
@@ -11,10 +12,20 @@ var resolveRefreshLineage = async (db, refreshOf, siteKey, now) => {
11
12
  const replaced = await db.getSessionRecordBySessionId(refreshOf);
12
13
  if (!replaced || replaced.siteKey !== siteKey) return void 0;
13
14
  return {
14
- refreshOf,
15
- refreshCount: (replaced.refreshCount ?? 0) + 1,
16
- refreshedAfterMs: Math.max(0, now.getTime() - new Date(replaced.createdAt).getTime())
15
+ lineage: {
16
+ refreshOf,
17
+ refreshCount: (replaced.refreshCount ?? 0) + 1,
18
+ refreshedAfterMs: Math.max(0, now.getTime() - new Date(replaced.createdAt).getTime())
19
+ },
20
+ replacedCaptchaType: replaced.captchaType
17
21
  };
18
22
  };
23
+ /**
24
+ * Whether to honour the user's request to swap their puzzle for an image
25
+ * challenge: the request must be a genuine refresh of a puzzle session on
26
+ * this site, and the site must have the switch enabled.
27
+ */
28
+ var isImageSwitchRequestValid = (switchToImage, refresh, switchEnabled) => true === switchToImage && switchEnabled && _prosopo_types.CaptchaType.puzzle === refresh?.replacedCaptchaType;
19
29
  //#endregion
30
+ exports.isImageSwitchRequestValid = isImageSwitchRequestValid;
20
31
  exports.resolveRefreshLineage = resolveRefreshLineage;
@@ -68,6 +68,7 @@ var runConfiguredCaptchaTypeShortCircuit = async (input, res) => {
68
68
  }));
69
69
  case _prosopo_types.CaptchaType.pow: return res.json(await input.tasks.frictionlessManager.sendPowCaptcha(sessionParams));
70
70
  case _prosopo_types.CaptchaType.puzzle: return res.json(await input.tasks.frictionlessManager.sendPuzzleCaptcha(sessionParams));
71
+ case _prosopo_types.CaptchaType.iconOrder: return res.json(await input.tasks.frictionlessManager.sendIconOrderCaptcha(sessionParams));
71
72
  default: throw new Error(`Unhandled configured captchaType in /frictionless short-circuit: ${configuredType}`);
72
73
  }
73
74
  };
@@ -0,0 +1,37 @@
1
+ const require_iconOrderRenderer = require("../../tasks/iconOrder/iconOrderRenderer.cjs");
2
+ const require_interactiveCaptchaChallenge = require("./interactiveCaptchaChallenge.cjs");
3
+ const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
4
+ let _prosopo_types = require("@prosopo/types");
5
+ //#region src/api/captcha/getIconOrderCaptchaChallenge.ts
6
+ var issueIconOrderChallenge = async ({ tasks, user, dapp, clientSettings, sessionRecord, trafficVerdict, provenance }) => {
7
+ const challengeVerdict = trafficVerdict.kind === "challenge" ? trafficVerdict : void 0;
8
+ const tolerance = challengeVerdict?.iconOrderTolerance ?? sessionRecord?.iconOrderTolerance ?? clientSettings?.settings?.iconOrderTolerance;
9
+ const renderSettings = require_iconOrderRenderer.resolveIconOrderRenderSettings(clientSettings?.settings?.iconOrder, challengeVerdict?.iconOrderSettings ?? sessionRecord?.iconOrder);
10
+ const challenge = await tasks.iconOrderCaptchaManager.getIconOrderCaptchaChallenge(user, dapp, tolerance, () => require_iconOrderRenderer.renderIconOrderImages(renderSettings));
11
+ await tasks.db.storeIconOrderCaptchaRecord(challenge.challenge, {
12
+ requestedAtTimestamp: challenge.requestedAtTimestamp,
13
+ userAccount: user,
14
+ dappAccount: dapp
15
+ }, challenge.targets, challenge.tolerance, challenge.providerSignature, provenance.ipAddress, provenance.headers, provenance.ja4, provenance.sessionId, provenance.ipInfo);
16
+ return {
17
+ logData: { tolerance: challenge.tolerance },
18
+ response: {
19
+ [_prosopo_types.ApiParams.status]: "ok",
20
+ [_prosopo_types.ApiParams.challenge]: challenge.challenge,
21
+ [_prosopo_types.ApiParams.background]: challenge.images.background,
22
+ [_prosopo_types.ApiParams.legend]: challenge.images.legend,
23
+ [_prosopo_types.ApiParams.legendIconSize]: challenge.images.legendIconSize,
24
+ [_prosopo_types.ApiParams.timestamp]: challenge.requestedAtTimestamp.toString(),
25
+ [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: challenge.providerSignature } }
26
+ }
27
+ };
28
+ };
29
+ var getIconOrderCaptchaChallenge_default = (env, userAccessRulesStorage) => require_interactiveCaptchaChallenge.interactiveChallengeHandler(env, userAccessRulesStorage, {
30
+ captchaType: _prosopo_types.CaptchaType.iconOrder,
31
+ label: "icon-order",
32
+ manager: (tasks) => tasks.iconOrderCaptchaManager,
33
+ maintenanceResponse: require_maintenanceModeResponses.buildIconOrderMaintenanceResponse,
34
+ issue: issueIconOrderChallenge
35
+ });
36
+ //#endregion
37
+ exports.default = getIconOrderCaptchaChallenge_default;
@@ -1,12 +1,12 @@
1
- const require_validateAddress = require("../validateAddress.cjs");
2
1
  const require_metrics = require("../metrics.cjs");
3
2
  const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
3
+ const require_validateAddress = require("../validateAddress.cjs");
4
4
  const require_tasks = require("../../tasks/tasks.cjs");
5
5
  const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
6
6
  const require_testSiteKey = require("../testSiteKey.cjs");
7
7
  const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
8
- const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
9
8
  const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
9
+ const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
10
10
  const require_sealedAssetsResolver = require("./sealedAssetsResolver.cjs");
11
11
  const require_signedAssetsResolver = require("./signedAssetsResolver.cjs");
12
12
  let _prosopo_common = require("@prosopo/common");
@@ -1,14 +1,14 @@
1
- const require_validateAddress = require("../validateAddress.cjs");
2
- const require_metrics = require("../metrics.cjs");
3
1
  const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
2
+ const require_metrics = require("../metrics.cjs");
4
3
  const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
4
+ const require_validateAddress = require("../validateAddress.cjs");
5
5
  const require_tasks = require("../../tasks/tasks.cjs");
6
6
  const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
7
7
  const require_testSiteKey = require("../testSiteKey.cjs");
8
8
  const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
9
- const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
10
- const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
11
9
  const require_requestBodySummary = require("../requestBodySummary.cjs");
10
+ const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
11
+ const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
12
12
  let _prosopo_common = require("@prosopo/common");
13
13
  let _prosopo_types = require("@prosopo/types");
14
14
  let _prosopo_util = require("@prosopo/util");
@@ -1,144 +1,52 @@
1
- const require_validateAddress = require("../validateAddress.cjs");
2
- const require_metrics = require("../metrics.cjs");
3
- const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
4
- const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
5
1
  const require_puzzleRenderer = require("../../tasks/puzzle/puzzleRenderer.cjs");
6
- const require_tasks = require("../../tasks/tasks.cjs");
7
- const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
8
- const require_testSiteKey = require("../testSiteKey.cjs");
9
- const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
2
+ const require_interactiveCaptchaChallenge = require("./interactiveCaptchaChallenge.cjs");
10
3
  const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
11
- const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
12
- const require_requestBodySummary = require("../requestBodySummary.cjs");
13
- let _prosopo_common = require("@prosopo/common");
4
+ const require_constants = require("./getFrictionlessCaptchaChallenge/constants.cjs");
14
5
  let _prosopo_types = require("@prosopo/types");
15
- let _prosopo_util = require("@prosopo/util");
16
6
  let _prosopo_puzzle_assets = require("@prosopo/puzzle-assets");
17
7
  //#region src/api/captcha/getPuzzleCaptchaChallenge.ts
18
- var getPuzzleCaptchaChallenge_default = (env, userAccessRulesStorage) => async (req, res, next) => {
19
- let parsed;
20
- try {
21
- parsed = _prosopo_types.GetPuzzleCaptchaChallengeRequestBody.parse(req.body);
22
- } catch (err) {
23
- return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
24
- context: {
25
- code: 400,
26
- error: err
27
- },
28
- i18n: req.i18n,
29
- logger: req.logger
8
+ var issuePuzzleChallenge = async ({ tasks, user, dapp, origin, clientSettings, sessionRecord, trafficVerdict, provenance }) => {
9
+ const challengeVerdict = trafficVerdict.kind === "challenge" ? trafficVerdict : void 0;
10
+ const tolerance = challengeVerdict?.puzzleTolerance ?? sessionRecord?.puzzleTolerance ?? clientSettings?.settings?.puzzleTolerance;
11
+ const routedPuzzleSettings = challengeVerdict?.puzzleSettings ?? sessionRecord?.puzzle;
12
+ const effectivePuzzleSettings = require_puzzleRenderer.resolvePuzzleRenderSettings(clientSettings?.settings?.puzzle, routedPuzzleSettings);
13
+ const effectivePieceSize = require_puzzleRenderer.resolvePuzzlePieceSize(clientSettings?.settings?.puzzle, routedPuzzleSettings);
14
+ const challenge = await tasks.puzzleCaptchaManager.getPuzzleCaptchaChallenge(user, dapp, origin, tolerance);
15
+ await tasks.db.storePuzzleCaptchaRecord(challenge.challenge, {
16
+ requestedAtTimestamp: challenge.requestedAtTimestamp,
17
+ userAccount: user,
18
+ dappAccount: dapp
19
+ }, challenge.targetX, challenge.targetY, challenge.originX, challenge.originY, challenge.tolerance, challenge.providerSignature, provenance.ipAddress, provenance.headers, provenance.ja4, provenance.sessionId, provenance.ipInfo);
20
+ const images = await require_puzzleRenderer.renderPuzzleImages({
21
+ targetX: challenge.targetX,
22
+ targetY: challenge.targetY
23
+ }, effectivePuzzleSettings, effectivePieceSize);
24
+ await tasks.db.updatePuzzleCaptchaRecord(challenge.challenge, { render: {
25
+ ...sessionRecord?.puzzleLevel !== void 0 && { level: sessionRecord.puzzleLevel },
26
+ pieceSize: images.pieceSize,
27
+ geometry: {
28
+ width: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.width,
29
+ height: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.height,
30
+ notchSize: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.notchSize
31
+ },
32
+ settings: {
33
+ decoyCount: effectivePuzzleSettings.decoyCount,
34
+ decoyEdgeDarkness: effectivePuzzleSettings.decoyEdgeDarkness,
35
+ decoyBodyBrightness: effectivePuzzleSettings.decoyBodyBrightness,
36
+ holeDarken: effectivePuzzleSettings.holeDarken,
37
+ decoyHoleDarken: effectivePuzzleSettings.decoyHoleDarken
38
+ },
39
+ backgroundSeed: images.backgroundSeed,
40
+ renderSeed: images.renderSeed
41
+ } }).catch((updateErr) => {
42
+ tasks.logger.warn(() => ({
43
+ err: updateErr,
44
+ msg: "Failed to patch puzzle render inputs onto the challenge record"
30
45
  }));
31
- }
32
- const { user, dapp, sessionId, simdReadings } = parsed;
33
- require_validateAddress.validateSiteKey(dapp);
34
- require_validateAddress.validateAddr(user);
35
- if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
36
- req.logger.info(() => ({
37
- msg: "Maintenance mode active - returning dummy puzzle challenge",
38
- data: {
39
- dapp,
40
- user,
41
- sessionId
42
- }
43
- }));
44
- return res.json(await require_maintenanceModeResponses.buildPuzzleMaintenanceResponse(user, dapp));
45
- }
46
- if (require_testSiteKey.isReservedTestSiteKey(dapp)) {
47
- req.logger.warn(() => ({
48
- msg: "Reserved TEST site key - returning dummy puzzle challenge",
49
- data: {
50
- dapp,
51
- user,
52
- sessionId
53
- }
54
- }));
55
- return res.json(await require_maintenanceModeResponses.buildPuzzleMaintenanceResponse(user, dapp));
56
- }
57
- const tasks = new require_tasks.Tasks(env, req.logger);
58
- try {
59
- const clientSettings = await tasks.db.getClientRecord(dapp);
60
- if (!clientSettings) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
61
- context: {
62
- code: 400,
63
- siteKey: dapp
64
- },
65
- i18n: req.i18n,
66
- logger: req.logger
67
- }));
68
- const normalizedIp = require_normalizeRequestIp.normalizeRequestIp(req.ip, req.logger);
69
- if (!normalizedIp) req.logger.warn(() => ({ msg: "Request missing IP; geoblocking will be skipped" }));
70
- const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
71
- const asn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
72
- const sessionRecord = sessionId ? await tasks.db.getSessionRecordBySessionId(sessionId) : void 0;
73
- const userScope = require_blacklistRequestInspector.getRequestUserScope((0, _prosopo_util.flatten)(req.headers), req.ja4, normalizedIp, user, sessionRecord?.decryptedHeadHash, void 0, countryCode, asn);
74
- const userAccessPolicy = (await tasks.puzzleCaptchaManager.getPrioritisedAccessPolicies(userAccessRulesStorage, dapp, userScope, require_blacklistRequestInspector.normalizeHeadersForMatching(req.headers))).find((p) => !p.deferToVerify);
75
- const { valid, reason, sessionId: validSessionId } = await tasks.puzzleCaptchaManager.isValidRequest(clientSettings, _prosopo_types.CaptchaType.puzzle, env, sessionId, userAccessPolicy, normalizedIp);
76
- if (!valid) return next(new _prosopo_common.ProsopoApiError(reason || "API.BAD_REQUEST", {
77
- context: {
78
- code: 400,
79
- siteKey: dapp,
80
- user
81
- },
82
- i18n: req.i18n,
83
- logger: req.logger
84
- }));
85
- const origin = req.headers.origin;
86
- if (!origin) return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
87
- context: {
88
- error: "Origin header not found",
89
- code: 400,
90
- siteKey: dapp,
91
- user
92
- },
93
- i18n: req.i18n,
94
- logger: req.logger
95
- }));
96
- const trafficVerdict = require_trafficFilterRequestTime.applyTrafficFilterAtRequestTime(req.ipInfo, clientSettings.settings?.trafficFilter, req.logger);
97
- const tolerance = (trafficVerdict.kind === "challenge" ? trafficVerdict.puzzleTolerance : void 0) ?? sessionRecord?.puzzleTolerance ?? clientSettings?.settings?.puzzleTolerance;
98
- const routedPuzzleSettings = (trafficVerdict.kind === "challenge" ? trafficVerdict.puzzleSettings : void 0) ?? sessionRecord?.puzzle;
99
- const effectivePuzzleSettings = require_puzzleRenderer.resolvePuzzleRenderSettings(clientSettings?.settings?.puzzle, routedPuzzleSettings);
100
- const effectivePieceSize = require_puzzleRenderer.resolvePuzzlePieceSize(clientSettings?.settings?.puzzle, routedPuzzleSettings);
101
- const challenge = await tasks.puzzleCaptchaManager.getPuzzleCaptchaChallenge(user, dapp, origin, tolerance);
102
- if (validSessionId && simdReadings) await tasks.frictionlessManager.decryptAndAttachSimdReadingsIfAbsent(validSessionId, simdReadings, _prosopo_types.SimdReadingsStage.challenge).catch((updateErr) => {
103
- req.logger.warn(() => ({
104
- err: updateErr,
105
- msg: "Failed to patch session with SIMD readings on puzzle challenge"
106
- }));
107
- });
108
- await tasks.db.storePuzzleCaptchaRecord(challenge.challenge, {
109
- requestedAtTimestamp: challenge.requestedAtTimestamp,
110
- userAccount: user,
111
- dappAccount: dapp
112
- }, challenge.targetX, challenge.targetY, challenge.originX, challenge.originY, challenge.tolerance, challenge.providerSignature, require_compositeIpAddress.getCompositeIpAddress(normalizedIp), (0, _prosopo_util.flatten)(req.headers), req.ja4, validSessionId, req.ipInfo);
113
- const images = await require_puzzleRenderer.renderPuzzleImages({
114
- targetX: challenge.targetX,
115
- targetY: challenge.targetY
116
- }, effectivePuzzleSettings, effectivePieceSize);
117
- await tasks.db.updatePuzzleCaptchaRecord(challenge.challenge, { render: {
118
- ...sessionRecord?.puzzleLevel !== void 0 && { level: sessionRecord.puzzleLevel },
119
- pieceSize: images.pieceSize,
120
- geometry: {
121
- width: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.width,
122
- height: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.height,
123
- notchSize: _prosopo_puzzle_assets.DEFAULT_GEOMETRY.notchSize
124
- },
125
- settings: {
126
- decoyCount: effectivePuzzleSettings.decoyCount,
127
- decoyEdgeDarkness: effectivePuzzleSettings.decoyEdgeDarkness,
128
- decoyBodyBrightness: effectivePuzzleSettings.decoyBodyBrightness,
129
- holeDarken: effectivePuzzleSettings.holeDarken,
130
- decoyHoleDarken: effectivePuzzleSettings.decoyHoleDarken
131
- },
132
- backgroundSeed: images.backgroundSeed,
133
- renderSeed: images.renderSeed
134
- } }).catch((updateErr) => {
135
- req.logger.warn(() => ({
136
- err: updateErr,
137
- msg: "Failed to patch puzzle render inputs onto the challenge record"
138
- }));
139
- });
140
- const padBytes = trafficVerdict.padBytes;
141
- const getPuzzleCaptchaResponse = {
46
+ });
47
+ return {
48
+ logData: { tolerance: challenge.tolerance },
49
+ response: {
142
50
  [_prosopo_types.ApiParams.status]: "ok",
143
51
  [_prosopo_types.ApiParams.challenge]: challenge.challenge,
144
52
  [_prosopo_types.ApiParams.background]: images.background,
@@ -147,40 +55,17 @@ var getPuzzleCaptchaChallenge_default = (env, userAccessRulesStorage) => async (
147
55
  [_prosopo_types.ApiParams.originX]: challenge.originX,
148
56
  [_prosopo_types.ApiParams.originY]: challenge.originY,
149
57
  [_prosopo_types.ApiParams.timestamp]: challenge.requestedAtTimestamp.toString(),
150
- [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: challenge.providerSignature } }
151
- };
152
- req.logger.info(() => ({
153
- msg: "Puzzle captcha challenge issued",
154
- data: {
155
- captchaType: _prosopo_types.CaptchaType.puzzle,
156
- challenge: challenge.challenge,
157
- tolerance: challenge.tolerance,
158
- user,
159
- dapp,
160
- session: sessionId
161
- }
162
- }));
163
- res.locals.padBytes = padBytes;
164
- require_metrics.recordCaptchaIssued(_prosopo_types.CaptchaType.puzzle);
165
- return res.json(getPuzzleCaptchaResponse);
166
- } catch (err) {
167
- require_metrics.recordCaptchaIssueError(_prosopo_types.CaptchaType.puzzle);
168
- req.logger.error(() => ({
169
- err,
170
- body: require_requestBodySummary.summariseRequestBody(req),
171
- msg: "Error in puzzle captcha challenge request"
172
- }));
173
- return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
174
- context: {
175
- code: 500,
176
- siteKey: req.body.dapp,
177
- user: req.body.user,
178
- error: err
179
- },
180
- i18n: req.i18n,
181
- logger: req.logger
182
- }));
183
- }
58
+ [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: challenge.providerSignature } },
59
+ ...require_constants.isPuzzleImageSwitchAvailable(clientSettings?.settings ?? {}) && { [_prosopo_types.ApiParams.imageSwitchAvailable]: true }
60
+ }
61
+ };
184
62
  };
63
+ var getPuzzleCaptchaChallenge_default = (env, userAccessRulesStorage) => require_interactiveCaptchaChallenge.interactiveChallengeHandler(env, userAccessRulesStorage, {
64
+ captchaType: _prosopo_types.CaptchaType.puzzle,
65
+ label: "puzzle",
66
+ manager: (tasks) => tasks.puzzleCaptchaManager,
67
+ maintenanceResponse: require_maintenanceModeResponses.buildPuzzleMaintenanceResponse,
68
+ issue: issuePuzzleChallenge
69
+ });
185
70
  //#endregion
186
71
  exports.default = getPuzzleCaptchaChallenge_default;
@@ -0,0 +1,154 @@
1
+ const require_compositeIpAddress = require("../../compositeIpAddress.cjs");
2
+ const require_metrics = require("../metrics.cjs");
3
+ const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
4
+ const require_validateAddress = require("../validateAddress.cjs");
5
+ const require_tasks = require("../../tasks/tasks.cjs");
6
+ const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
7
+ const require_testSiteKey = require("../testSiteKey.cjs");
8
+ const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
9
+ const require_requestBodySummary = require("../requestBodySummary.cjs");
10
+ const require_trafficFilterRequestTime = require("./trafficFilterRequestTime.cjs");
11
+ let _prosopo_common = require("@prosopo/common");
12
+ let _prosopo_types = require("@prosopo/types");
13
+ let _prosopo_util = require("@prosopo/util");
14
+ //#region src/api/captcha/interactiveCaptchaChallenge.ts
15
+ var capitalise = (text) => text.charAt(0).toUpperCase() + text.slice(1);
16
+ /** Request handling shared by the challenge endpoints of the interactive types. */
17
+ var interactiveChallengeHandler = (env, userAccessRulesStorage, spec) => async (req, res, next) => {
18
+ const { captchaType, label } = spec;
19
+ let parsed;
20
+ try {
21
+ parsed = _prosopo_types.GetPuzzleCaptchaChallengeRequestBody.parse(req.body);
22
+ } catch (err) {
23
+ return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
24
+ context: {
25
+ code: 400,
26
+ error: err
27
+ },
28
+ i18n: req.i18n,
29
+ logger: req.logger
30
+ }));
31
+ }
32
+ const { user, dapp, sessionId, simdReadings } = parsed;
33
+ require_validateAddress.validateSiteKey(dapp);
34
+ require_validateAddress.validateAddr(user);
35
+ if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
36
+ req.logger.info(() => ({
37
+ msg: `Maintenance mode active - returning dummy ${label} challenge`,
38
+ data: {
39
+ dapp,
40
+ user,
41
+ sessionId
42
+ }
43
+ }));
44
+ return res.json(await spec.maintenanceResponse(user, dapp));
45
+ }
46
+ if (require_testSiteKey.isReservedTestSiteKey(dapp)) {
47
+ req.logger.warn(() => ({
48
+ msg: `Reserved TEST site key - returning dummy ${label} challenge`,
49
+ data: {
50
+ dapp,
51
+ user,
52
+ sessionId
53
+ }
54
+ }));
55
+ return res.json(await spec.maintenanceResponse(user, dapp));
56
+ }
57
+ const tasks = new require_tasks.Tasks(env, req.logger);
58
+ const manager = spec.manager(tasks);
59
+ try {
60
+ const clientSettings = await tasks.db.getClientRecord(dapp);
61
+ if (!clientSettings) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
62
+ context: {
63
+ code: 400,
64
+ siteKey: dapp
65
+ },
66
+ i18n: req.i18n,
67
+ logger: req.logger
68
+ }));
69
+ const normalizedIp = require_normalizeRequestIp.normalizeRequestIp(req.ip, req.logger);
70
+ if (!normalizedIp) req.logger.warn(() => ({ msg: "Request missing IP; geoblocking will be skipped" }));
71
+ const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
72
+ const asn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
73
+ const sessionRecord = sessionId ? await tasks.db.getSessionRecordBySessionId(sessionId) : void 0;
74
+ const userScope = require_blacklistRequestInspector.getRequestUserScope((0, _prosopo_util.flatten)(req.headers), req.ja4, normalizedIp, user, sessionRecord?.decryptedHeadHash, void 0, countryCode, asn);
75
+ const userAccessPolicy = (await manager.getPrioritisedAccessPolicies(userAccessRulesStorage, dapp, userScope, require_blacklistRequestInspector.normalizeHeadersForMatching(req.headers))).find((p) => !p.deferToVerify);
76
+ const { valid, reason, sessionId: validSessionId } = await manager.isValidRequest(clientSettings, captchaType, env, sessionId, userAccessPolicy, normalizedIp);
77
+ if (!valid) return next(new _prosopo_common.ProsopoApiError(reason || "API.BAD_REQUEST", {
78
+ context: {
79
+ code: 400,
80
+ siteKey: dapp,
81
+ user
82
+ },
83
+ i18n: req.i18n,
84
+ logger: req.logger
85
+ }));
86
+ const origin = req.headers.origin;
87
+ if (!origin) return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
88
+ context: {
89
+ error: "Origin header not found",
90
+ code: 400,
91
+ siteKey: dapp,
92
+ user
93
+ },
94
+ i18n: req.i18n,
95
+ logger: req.logger
96
+ }));
97
+ const trafficVerdict = require_trafficFilterRequestTime.applyTrafficFilterAtRequestTime(req.ipInfo, clientSettings.settings?.trafficFilter, req.logger);
98
+ if (validSessionId && simdReadings) await tasks.frictionlessManager.decryptAndAttachSimdReadingsIfAbsent(validSessionId, simdReadings, _prosopo_types.SimdReadingsStage.challenge).catch((updateErr) => {
99
+ req.logger.warn(() => ({
100
+ err: updateErr,
101
+ msg: `Failed to patch session with SIMD readings on ${label} challenge`
102
+ }));
103
+ });
104
+ const { response, logData } = await spec.issue({
105
+ tasks,
106
+ user,
107
+ dapp,
108
+ origin,
109
+ clientSettings,
110
+ sessionRecord,
111
+ trafficVerdict,
112
+ provenance: {
113
+ ipAddress: require_compositeIpAddress.getCompositeIpAddress(normalizedIp),
114
+ headers: (0, _prosopo_util.flatten)(req.headers),
115
+ ja4: req.ja4,
116
+ sessionId: validSessionId,
117
+ ipInfo: req.ipInfo
118
+ }
119
+ });
120
+ req.logger.info(() => ({
121
+ msg: `${capitalise(label)} captcha challenge issued`,
122
+ data: {
123
+ captchaType,
124
+ challenge: response.challenge,
125
+ ...logData,
126
+ user,
127
+ dapp,
128
+ session: sessionId
129
+ }
130
+ }));
131
+ res.locals.padBytes = trafficVerdict.padBytes;
132
+ require_metrics.recordCaptchaIssued(captchaType);
133
+ return res.json(response);
134
+ } catch (err) {
135
+ require_metrics.recordCaptchaIssueError(captchaType);
136
+ req.logger.error(() => ({
137
+ err,
138
+ body: require_requestBodySummary.summariseRequestBody(req),
139
+ msg: `Error in ${label} captcha challenge request`
140
+ }));
141
+ return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
142
+ context: {
143
+ code: 500,
144
+ siteKey: req.body.dapp,
145
+ user: req.body.user,
146
+ error: err
147
+ },
148
+ i18n: req.i18n,
149
+ logger: req.logger
150
+ }));
151
+ }
152
+ };
153
+ //#endregion
154
+ exports.interactiveChallengeHandler = interactiveChallengeHandler;
@@ -0,0 +1,77 @@
1
+ const require_validateAddress = require("../validateAddress.cjs");
2
+ const require_tasks = require("../../tasks/tasks.cjs");
3
+ const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
4
+ const require_testSiteKey = require("../testSiteKey.cjs");
5
+ const require_requestBodySummary = require("../requestBodySummary.cjs");
6
+ let _prosopo_common = require("@prosopo/common");
7
+ //#region src/api/captcha/interactiveCaptchaSolution.ts
8
+ /** Request handling shared by the solution endpoints of the interactive types. */
9
+ var interactiveSolutionHandler = (env, spec) => async (req, res, next) => {
10
+ if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
11
+ req.logger.info(() => ({ msg: "Maintenance mode active - returning verified" }));
12
+ return res.json({
13
+ status: "ok",
14
+ verified: true
15
+ });
16
+ }
17
+ let parsed;
18
+ const tasks = new require_tasks.Tasks(env, req.logger);
19
+ try {
20
+ parsed = spec.parse(req.body);
21
+ } catch (err) {
22
+ return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
23
+ context: {
24
+ code: 400,
25
+ error: err,
26
+ body: require_requestBodySummary.summariseRequestBody(req)
27
+ },
28
+ i18n: req.i18n,
29
+ logger: req.logger
30
+ }));
31
+ }
32
+ const { dapp, user } = parsed;
33
+ require_validateAddress.validateSiteKey(dapp);
34
+ require_validateAddress.validateAddr(user);
35
+ const testVerdict = require_testSiteKey.resolveTestSiteKeyVerdict(dapp, req.logger);
36
+ if (testVerdict !== null) {
37
+ const response = {
38
+ status: "ok",
39
+ verified: testVerdict
40
+ };
41
+ return res.json(response);
42
+ }
43
+ try {
44
+ const clientRecord = await tasks.db.getClientRecord(dapp);
45
+ if (!clientRecord) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
46
+ context: {
47
+ code: 400,
48
+ siteKey: dapp
49
+ },
50
+ i18n: req.i18n,
51
+ logger: req.logger
52
+ }));
53
+ const submitWindowMs = clientRecord.settings.solutionTimeout ?? clientRecord.settings.verifiedTimeout;
54
+ const response = {
55
+ status: "ok",
56
+ verified: await spec.verify(tasks, parsed, submitWindowMs, req)
57
+ };
58
+ return res.json(response);
59
+ } catch (err) {
60
+ req.logger.error(() => ({
61
+ err,
62
+ body: require_requestBodySummary.summariseRequestBody(req),
63
+ msg: `Error in ${spec.label} captcha solution submission`
64
+ }));
65
+ return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
66
+ context: {
67
+ code: 500,
68
+ siteKey: req.body.dapp,
69
+ error: err
70
+ },
71
+ i18n: req.i18n,
72
+ logger: req.logger
73
+ }));
74
+ }
75
+ };
76
+ //#endregion
77
+ exports.interactiveSolutionHandler = interactiveSolutionHandler;
@@ -1,4 +1,6 @@
1
+ const require_audioRenderer = require("../../tasks/audio/audioRenderer.cjs");
1
2
  const require_puzzleRenderer = require("../../tasks/puzzle/puzzleRenderer.cjs");
3
+ const require_iconOrderRenderer = require("../../tasks/iconOrder/iconOrderRenderer.cjs");
2
4
  let _prosopo_types = require("@prosopo/types");
3
5
  let node_crypto = require("node:crypto");
4
6
  //#region src/api/captcha/maintenanceModeResponses.ts
@@ -49,8 +51,35 @@ var buildPuzzleMaintenanceResponse = async (user, dapp) => {
49
51
  [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: "" } }
50
52
  };
51
53
  };
54
+ var buildAudioMaintenanceResponse = async (user, dapp) => {
55
+ const timestamp = Date.now();
56
+ const rendered = require_audioRenderer.renderAudioClip(require_audioRenderer.resolveAudioRenderSettings());
57
+ return {
58
+ [_prosopo_types.ApiParams.status]: "ok",
59
+ [_prosopo_types.ApiParams.challenge]: buildChallenge(user, dapp),
60
+ [_prosopo_types.ApiParams.clip]: rendered.clip,
61
+ [_prosopo_types.ApiParams.characterCount]: rendered.characterCount,
62
+ [_prosopo_types.ApiParams.timestamp]: timestamp.toString(),
63
+ [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: "" } }
64
+ };
65
+ };
66
+ var buildIconOrderMaintenanceResponse = async (user, dapp) => {
67
+ const timestamp = Date.now();
68
+ const images = await require_iconOrderRenderer.renderIconOrderImages();
69
+ return {
70
+ [_prosopo_types.ApiParams.status]: "ok",
71
+ [_prosopo_types.ApiParams.challenge]: buildChallenge(user, dapp),
72
+ [_prosopo_types.ApiParams.background]: images.background,
73
+ [_prosopo_types.ApiParams.legend]: images.legend,
74
+ [_prosopo_types.ApiParams.legendIconSize]: images.legendIconSize,
75
+ [_prosopo_types.ApiParams.timestamp]: timestamp.toString(),
76
+ [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.challenge]: "" } }
77
+ };
78
+ };
52
79
  //#endregion
80
+ exports.buildAudioMaintenanceResponse = buildAudioMaintenanceResponse;
53
81
  exports.buildFrictionlessMaintenanceResponse = buildFrictionlessMaintenanceResponse;
82
+ exports.buildIconOrderMaintenanceResponse = buildIconOrderMaintenanceResponse;
54
83
  exports.buildImageMaintenanceResponse = buildImageMaintenanceResponse;
55
84
  exports.buildMaintenanceVerificationResponse = buildMaintenanceVerificationResponse;
56
85
  exports.buildPowMaintenanceResponse = buildPowMaintenanceResponse;
@@ -0,0 +1,11 @@
1
+ const require_interactiveCaptchaSolution = require("./interactiveCaptchaSolution.cjs");
2
+ let _prosopo_types = require("@prosopo/types");
3
+ let _prosopo_util = require("@prosopo/util");
4
+ //#region src/api/captcha/submitAudioCaptchaSolution.ts
5
+ var submitAudioCaptchaSolution_default = (env) => require_interactiveCaptchaSolution.interactiveSolutionHandler(env, {
6
+ label: "audio",
7
+ parse: (body) => _prosopo_types.SubmitAudioCaptchaSolutionBody.parse(body),
8
+ verify: (tasks, body, submitWindowMs, req) => tasks.audioCaptchaManager.verifyAudioCaptchaSolution(body.challenge, body.signature.provider.challenge, body.answer, body.replays ?? 0, body.audioEvents ?? [], submitWindowMs, body.signature.user.timestamp, (0, _prosopo_util.getIPAddress)(req.ip || ""), body.behavioralData, body.salt, body.simdReadings, body.clientMetaData)
9
+ });
10
+ //#endregion
11
+ exports.default = submitAudioCaptchaSolution_default;
@@ -0,0 +1,11 @@
1
+ const require_interactiveCaptchaSolution = require("./interactiveCaptchaSolution.cjs");
2
+ let _prosopo_types = require("@prosopo/types");
3
+ let _prosopo_util = require("@prosopo/util");
4
+ //#region src/api/captcha/submitIconOrderCaptchaSolution.ts
5
+ var submitIconOrderCaptchaSolution_default = (env) => require_interactiveCaptchaSolution.interactiveSolutionHandler(env, {
6
+ label: "icon-order",
7
+ parse: (body) => _prosopo_types.SubmitIconOrderCaptchaSolutionBody.parse(body),
8
+ verify: (tasks, body, submitWindowMs, req) => tasks.iconOrderCaptchaManager.verifyIconOrderCaptchaSolution(body.challenge, body.signature.provider.challenge, body.clicks, body.iconOrderEvents, submitWindowMs, body.signature.user.timestamp, (0, _prosopo_util.getIPAddress)(req.ip || ""), body.behavioralData, body.salt, body.simdReadings, body.clientMetaData)
9
+ });
10
+ //#endregion
11
+ exports.default = submitIconOrderCaptchaSolution_default;