@prosopo/provider 4.11.6 → 4.13.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 (258) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +44 -41
  2. package/.turbo/turbo-build$colon$tsc.log +24 -24
  3. package/.turbo/turbo-build.log +45 -42
  4. package/CHANGELOG.md +148 -0
  5. package/dist/api/admin/apiClearAllCountersEndpoint.d.ts.map +1 -1
  6. package/dist/api/admin/apiClearAllCountersEndpoint.js +1 -1
  7. package/dist/api/admin/apiClearAllCountersEndpoint.js.map +1 -1
  8. package/dist/api/admin/apiDnsEventEndpoint.d.ts.map +1 -1
  9. package/dist/api/admin/apiDnsEventEndpoint.js +1 -1
  10. package/dist/api/admin/apiDnsEventEndpoint.js.map +1 -1
  11. package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.d.ts.map +1 -1
  12. package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js +1 -1
  13. package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js.map +1 -1
  14. package/dist/api/admin/apiGetDecisionMachineEndpoint.d.ts.map +1 -1
  15. package/dist/api/admin/apiGetDecisionMachineEndpoint.js +1 -1
  16. package/dist/api/admin/apiGetDecisionMachineEndpoint.js.map +1 -1
  17. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +1 -1
  18. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +1 -1
  19. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +1 -1
  20. package/dist/api/admin/apiRegisterSiteKeysEndpoint.d.ts.map +1 -1
  21. package/dist/api/admin/apiRegisterSiteKeysEndpoint.js +1 -1
  22. package/dist/api/admin/apiRegisterSiteKeysEndpoint.js.map +1 -1
  23. package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.d.ts.map +1 -1
  24. package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js +1 -1
  25. package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js.map +1 -1
  26. package/dist/api/admin/apiRemoveDecisionMachineEndpoint.d.ts.map +1 -1
  27. package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js +1 -1
  28. package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js.map +1 -1
  29. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +1 -1
  30. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js +1 -2
  31. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js.map +1 -1
  32. package/dist/api/admin/apiRemoveSiteKeyEndpoint.d.ts.map +1 -1
  33. package/dist/api/admin/apiRemoveSiteKeyEndpoint.js +1 -1
  34. package/dist/api/admin/apiRemoveSiteKeyEndpoint.js.map +1 -1
  35. package/dist/api/admin/apiRemoveSiteKeysEndpoint.d.ts.map +1 -1
  36. package/dist/api/admin/apiRemoveSiteKeysEndpoint.js +1 -1
  37. package/dist/api/admin/apiRemoveSiteKeysEndpoint.js.map +1 -1
  38. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts.map +1 -1
  39. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +3 -1
  40. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js.map +1 -1
  41. package/dist/api/admin/apiUpdateDecisionMachineEndpoint.d.ts.map +1 -1
  42. package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js +1 -1
  43. package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js.map +1 -1
  44. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js +1 -2
  45. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js.map +1 -1
  46. package/dist/api/blacklistRequestInspector.d.ts.map +1 -1
  47. package/dist/api/blacklistRequestInspector.js +7 -4
  48. package/dist/api/blacklistRequestInspector.js.map +1 -1
  49. package/dist/api/captcha/checkSpamEmail.d.ts.map +1 -1
  50. package/dist/api/captcha/checkSpamEmail.js +19 -4
  51. package/dist/api/captcha/checkSpamEmail.js.map +1 -1
  52. package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.d.ts +0 -1
  53. package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.d.ts.map +1 -1
  54. package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js +25 -6
  55. package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js.map +1 -1
  56. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.d.ts +0 -1
  57. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.d.ts.map +1 -1
  58. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +8 -21
  59. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js.map +1 -1
  60. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts +1 -1
  61. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.d.ts.map +1 -1
  62. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +68 -32
  63. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js.map +1 -1
  64. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.d.ts +0 -1
  65. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.d.ts.map +1 -1
  66. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +0 -2
  67. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js.map +1 -1
  68. package/dist/api/captcha/getImageCaptchaChallenge.d.ts.map +1 -1
  69. package/dist/api/captcha/getImageCaptchaChallenge.js +23 -1
  70. package/dist/api/captcha/getImageCaptchaChallenge.js.map +1 -1
  71. package/dist/api/captcha/getPoWCaptchaChallenge.d.ts.map +1 -1
  72. package/dist/api/captcha/getPoWCaptchaChallenge.js +3 -0
  73. package/dist/api/captcha/getPoWCaptchaChallenge.js.map +1 -1
  74. package/dist/api/captcha/getPuzzleCaptchaChallenge.d.ts.map +1 -1
  75. package/dist/api/captcha/getPuzzleCaptchaChallenge.js +3 -0
  76. package/dist/api/captcha/getPuzzleCaptchaChallenge.js.map +1 -1
  77. package/dist/api/captcha/submitPoWCaptchaSolution.js +0 -1
  78. package/dist/api/captcha/submitPoWCaptchaSolution.js.map +1 -1
  79. package/dist/api/captcha.d.ts +2 -1
  80. package/dist/api/captcha.d.ts.map +1 -1
  81. package/dist/api/captcha.js +12 -15
  82. package/dist/api/captcha.js.map +1 -1
  83. package/dist/api/domainMiddleware.d.ts.map +1 -1
  84. package/dist/api/domainMiddleware.js +4 -0
  85. package/dist/api/domainMiddleware.js.map +1 -1
  86. package/dist/api/forwardVerify.d.ts +14 -0
  87. package/dist/api/forwardVerify.d.ts.map +1 -0
  88. package/dist/api/forwardVerify.js +54 -0
  89. package/dist/api/forwardVerify.js.map +1 -0
  90. package/dist/api/headerCheckMiddleware.d.ts.map +1 -1
  91. package/dist/api/headerCheckMiddleware.js +7 -4
  92. package/dist/api/headerCheckMiddleware.js.map +1 -1
  93. package/dist/api/ja4.d.ts +5 -0
  94. package/dist/api/ja4.d.ts.map +1 -0
  95. package/dist/api/ja4.js +203 -0
  96. package/dist/api/ja4.js.map +1 -0
  97. package/dist/api/ja4Middleware.d.ts.map +1 -1
  98. package/dist/api/ja4Middleware.js +9 -18
  99. package/dist/api/ja4Middleware.js.map +1 -1
  100. package/dist/api/metrics.d.ts +40 -0
  101. package/dist/api/metrics.d.ts.map +1 -0
  102. package/dist/api/metrics.js +260 -0
  103. package/dist/api/metrics.js.map +1 -0
  104. package/dist/api/public.d.ts.map +1 -1
  105. package/dist/api/public.js +6 -1
  106. package/dist/api/public.js.map +1 -1
  107. package/dist/api/startProviderApi.d.ts.map +1 -1
  108. package/dist/api/startProviderApi.js +19 -22
  109. package/dist/api/startProviderApi.js.map +1 -1
  110. package/dist/api/verify.d.ts.map +1 -1
  111. package/dist/api/verify.js +85 -8
  112. package/dist/api/verify.js.map +1 -1
  113. package/dist/cjs/api/admin/apiClearAllCountersEndpoint.cjs +1 -1
  114. package/dist/cjs/api/admin/apiDnsEventEndpoint.cjs +1 -2
  115. package/dist/cjs/api/admin/apiGetAllDecisionMachinesEndpoint.cjs +1 -1
  116. package/dist/cjs/api/admin/apiGetDecisionMachineEndpoint.cjs +1 -1
  117. package/dist/cjs/api/admin/apiRegisterSiteKeyEndpoint.cjs +1 -2
  118. package/dist/cjs/api/admin/apiRegisterSiteKeysEndpoint.cjs +1 -2
  119. package/dist/cjs/api/admin/apiRemoveAllDecisionMachinesEndpoint.cjs +1 -1
  120. package/dist/cjs/api/admin/apiRemoveDecisionMachineEndpoint.cjs +1 -1
  121. package/dist/cjs/api/admin/apiRemoveDetectorKeyEndpoint.cjs +1 -3
  122. package/dist/cjs/api/admin/apiRemoveSiteKeyEndpoint.cjs +1 -2
  123. package/dist/cjs/api/admin/apiRemoveSiteKeysEndpoint.cjs +1 -2
  124. package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +3 -2
  125. package/dist/cjs/api/admin/apiUpdateDecisionMachineEndpoint.cjs +1 -1
  126. package/dist/cjs/api/admin/apiUpdateDetectorKeyEndpoint.cjs +1 -2
  127. package/dist/cjs/api/blacklistRequestInspector.cjs +7 -4
  128. package/dist/cjs/api/captcha/checkSpamEmail.cjs +18 -3
  129. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs +25 -6
  130. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +8 -21
  131. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +70 -34
  132. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +0 -2
  133. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +23 -1
  134. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +3 -0
  135. package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +3 -0
  136. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +0 -1
  137. package/dist/cjs/api/captcha.cjs +12 -15
  138. package/dist/cjs/api/domainMiddleware.cjs +4 -0
  139. package/dist/cjs/api/forwardVerify.cjs +54 -0
  140. package/dist/cjs/api/headerCheckMiddleware.cjs +7 -4
  141. package/dist/cjs/api/ja4.cjs +203 -0
  142. package/dist/cjs/api/ja4Middleware.cjs +11 -21
  143. package/dist/cjs/api/metrics.cjs +260 -0
  144. package/dist/cjs/api/public.cjs +6 -1
  145. package/dist/cjs/api/startProviderApi.cjs +19 -44
  146. package/dist/cjs/api/verify.cjs +83 -6
  147. package/dist/cjs/index.cjs +1 -0
  148. package/dist/cjs/tasks/captchaManager.cjs +1 -2
  149. package/dist/cjs/tasks/detection/getBotScore.cjs +1 -5
  150. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +5 -63
  151. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +20 -23
  152. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +17 -24
  153. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +15 -22
  154. package/dist/index.js +2 -1
  155. package/dist/tasks/captchaManager.js +1 -1
  156. package/dist/tasks/captchaManager.js.map +1 -1
  157. package/dist/tasks/detection/getBotScore.d.ts +0 -2
  158. package/dist/tasks/detection/getBotScore.d.ts.map +1 -1
  159. package/dist/tasks/detection/getBotScore.js +1 -5
  160. package/dist/tasks/detection/getBotScore.js.map +1 -1
  161. package/dist/tasks/frictionless/frictionlessTasks.d.ts +1 -11
  162. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
  163. package/dist/tasks/frictionless/frictionlessTasks.js +5 -63
  164. package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
  165. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +20 -23
  166. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
  167. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  168. package/dist/tasks/powCaptcha/powTasks.js +17 -24
  169. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  170. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
  171. package/dist/tasks/puzzleCaptcha/puzzleTasks.js +15 -22
  172. package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
  173. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +2 -2
  174. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +1 -1
  175. package/dist/tests/integration/clientSettingsPersistence.integration.test.js +1 -1
  176. package/dist/tests/integration/decisionMachines.integration.test.js +2 -2
  177. package/dist/tests/integration/decisionMachines.integration.test.js.map +1 -1
  178. package/dist/tests/integration/imgCaptcha.integration.test.js +2 -2
  179. package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -1
  180. package/dist/tests/integration/powCaptcha.integration.test.js +2 -2
  181. package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -1
  182. package/dist/tests/integration/routingDecisionMachines.integration.test.js +0 -1
  183. package/dist/tests/integration/routingDecisionMachines.integration.test.js.map +1 -1
  184. package/dist/tests/unit/api/admin/apiClearAllCountersEndpoint.unit.test.js +1 -0
  185. package/dist/tests/unit/api/admin/apiClearAllCountersEndpoint.unit.test.js.map +1 -1
  186. package/dist/tests/unit/api/admin/apiDnsEventEndpoint.unit.test.js +5 -1
  187. package/dist/tests/unit/api/admin/apiDnsEventEndpoint.unit.test.js.map +1 -1
  188. package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js +1 -0
  189. package/dist/tests/unit/api/admin/apiRegisterSiteKeyEndpoint.unit.test.js.map +1 -1
  190. package/dist/tests/unit/api/admin/apiRegisterSiteKeysEndpoint.unit.test.js +1 -0
  191. package/dist/tests/unit/api/admin/apiRegisterSiteKeysEndpoint.unit.test.js.map +1 -1
  192. package/dist/tests/unit/api/admin/apiRemoveDetectorKeyEndpoint.unit.test.js +1 -0
  193. package/dist/tests/unit/api/admin/apiRemoveDetectorKeyEndpoint.unit.test.js.map +1 -1
  194. package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js +1 -0
  195. package/dist/tests/unit/api/admin/apiToggleMaintenanceModeEndpoint.unit.test.js.map +1 -1
  196. package/dist/tests/unit/api/admin/apiUpdateDetectorKeyEndpoint.unit.test.js +1 -0
  197. package/dist/tests/unit/api/admin/apiUpdateDetectorKeyEndpoint.unit.test.js.map +1 -1
  198. package/dist/tests/unit/api/adminRoutes.unit.test.js +1 -0
  199. package/dist/tests/unit/api/adminRoutes.unit.test.js.map +1 -1
  200. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js +43 -1
  201. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js.map +1 -1
  202. package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.d.ts +2 -0
  203. package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.d.ts.map +1 -0
  204. package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.js +62 -0
  205. package/dist/tests/unit/api/captcha/checkSpamEmail.unit.test.js.map +1 -0
  206. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.unit.test.js +63 -1
  207. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.unit.test.js.map +1 -1
  208. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.unit.test.js +0 -75
  209. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.unit.test.js.map +1 -1
  210. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.unit.test.js +0 -1
  211. package/dist/tests/unit/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.unit.test.js.map +1 -1
  212. package/dist/tests/unit/api/captcha.unit.test.js +31 -1
  213. package/dist/tests/unit/api/captcha.unit.test.js.map +1 -1
  214. package/dist/tests/unit/api/forwardVerify.unit.test.d.ts +2 -0
  215. package/dist/tests/unit/api/forwardVerify.unit.test.d.ts.map +1 -0
  216. package/dist/tests/unit/api/forwardVerify.unit.test.js +151 -0
  217. package/dist/tests/unit/api/forwardVerify.unit.test.js.map +1 -0
  218. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +68 -20
  219. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
  220. package/dist/tests/unit/api/headerCheckMiddleware.unit.test.js +2 -2
  221. package/dist/tests/unit/api/headerCheckMiddleware.unit.test.js.map +1 -1
  222. package/dist/tests/unit/api/ja4.unit.test.d.ts +2 -0
  223. package/dist/tests/unit/api/ja4.unit.test.d.ts.map +1 -0
  224. package/dist/tests/unit/api/ja4.unit.test.js +233 -0
  225. package/dist/tests/unit/api/ja4.unit.test.js.map +1 -0
  226. package/dist/tests/unit/api/ja4Middleware.unit.test.js +11 -8
  227. package/dist/tests/unit/api/ja4Middleware.unit.test.js.map +1 -1
  228. package/dist/tests/unit/api/public.unit.test.js +72 -0
  229. package/dist/tests/unit/api/public.unit.test.js.map +1 -1
  230. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +1 -1
  231. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +1 -1
  232. package/dist/tests/unit/schedulers/getClientList.unit.test.js +1 -1
  233. package/dist/tests/unit/schedulers/getClientList.unit.test.js.map +1 -1
  234. package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js +1 -1
  235. package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js.map +1 -1
  236. package/dist/tests/unit/tasks/captchaManager.unit.test.js +1 -1
  237. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -1
  238. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +1 -1
  239. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
  240. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +1 -1
  241. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +1 -1
  242. package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js +0 -3
  243. package/dist/tests/unit/tasks/decisionMachine/decisionMachineRunner.unit.test.js.map +1 -1
  244. package/dist/tests/unit/tasks/detection/getBotScore.unit.test.js +0 -10
  245. package/dist/tests/unit/tasks/detection/getBotScore.unit.test.js.map +1 -1
  246. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js +0 -82
  247. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js.map +1 -1
  248. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +1 -13
  249. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
  250. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +4 -3
  251. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -1
  252. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +0 -4
  253. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
  254. package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js +0 -2
  255. package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js.map +1 -1
  256. package/dist/tests/unit/tasks/writeQueueIntegration.unit.test.js +0 -3
  257. package/dist/tests/unit/tasks/writeQueueIntegration.unit.test.js.map +1 -1
  258. package/package.json +23 -23
@@ -1,18 +1,32 @@
1
1
  "use strict";
2
2
  const common = require("@prosopo/common");
3
+ const types = require("@prosopo/types");
3
4
  const util = require("@prosopo/util");
4
5
  const zod = require("zod");
5
6
  require("../../tasks/index.cjs");
6
7
  const checkSpamEmail$1 = require("../../tasks/spam/checkSpamEmail.cjs");
7
8
  const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
9
+ const metrics = require("../metrics.cjs");
8
10
  const tasks = require("../../tasks/tasks.cjs");
9
11
  const CheckSpamEmailRequestBody = zod.object({
10
- email: zod.string(),
11
- dapp: zod.string()
12
+ email: types.safeLine(types.INPUT_LIMITS.EMAIL),
13
+ dapp: types.safeLine(types.INPUT_LIMITS.ID)
12
14
  });
13
15
  const checkSpamEmail = (env) => async (req, res, next) => {
16
+ let email;
17
+ let dapp;
18
+ try {
19
+ ({ email, dapp } = CheckSpamEmailRequestBody.parse(req.body));
20
+ } catch (err) {
21
+ return next(
22
+ new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
23
+ context: { code: 400, error: err },
24
+ i18n: req.i18n,
25
+ logger: req.logger
26
+ })
27
+ );
28
+ }
14
29
  try {
15
- const { email, dapp } = CheckSpamEmailRequestBody.parse(req.body);
16
30
  const emailDomain = util.extractDomainFromEmail(email);
17
31
  req.logger.info(() => ({
18
32
  msg: "Check spam email handler entry",
@@ -66,6 +80,7 @@ const checkSpamEmail = (env) => async (req, res, next) => {
66
80
  isSpam
67
81
  }
68
82
  }));
83
+ metrics.recordSpamEmail(isSpam ? "spam" : "ham");
69
84
  return res.json({
70
85
  isSpam,
71
86
  emailDomain
@@ -11,11 +11,10 @@ const handleAccessPolicy = async (input, res) => {
11
11
  scoreComponents: input.scoreComponents
12
12
  };
13
13
  }
14
- const { tasks, clientRecord, userAccessPolicy, logger, requestId } = input;
14
+ const { tasks, clientRecord, userAccessPolicy, logger } = input;
15
15
  logger.info(() => ({
16
16
  msg: "User access policy matched",
17
17
  data: {
18
- requestId,
19
18
  policy: userAccessPolicy,
20
19
  captchaType: userAccessPolicy.captchaType,
21
20
  userScope: input.userScope
@@ -34,7 +33,6 @@ const handleAccessPolicy = async (input, res) => {
34
33
  logger.info(() => ({
35
34
  msg: "Frictionless decision",
36
35
  data: {
37
- requestId,
38
36
  decision: "block",
39
37
  captchaType: types.CaptchaType.image
40
38
  }
@@ -52,6 +50,30 @@ const handleAccessPolicy = async (input, res) => {
52
50
  response: res.status(401).json({ error: "Unauthorized" })
53
51
  };
54
52
  }
53
+ const autoBanThreshold = clientRecord.settings.autoBanScoreThreshold;
54
+ if (autoBanThreshold !== void 0 && Number(botScore) >= autoBanThreshold) {
55
+ logger.info(() => ({
56
+ msg: "Frictionless decision",
57
+ data: {
58
+ decision: "auto_ban_score",
59
+ botScore,
60
+ autoBanThreshold,
61
+ captchaType: userAccessPolicy.captchaType
62
+ }
63
+ }));
64
+ await tasks.frictionlessManager.registerBlockedSession({
65
+ solvedImagesCount: clientRecord.settings.imageMaxRounds,
66
+ userSitekeyIpHash: input.userSitekeyIpHash,
67
+ reason: types.FrictionlessReason.AUTO_BAN_SCORE,
68
+ siteKey: input.dapp,
69
+ ipInfo: input.ipInfo,
70
+ headers: input.flatHeaders
71
+ });
72
+ return {
73
+ handled: true,
74
+ response: res.status(401).json({ error: "Unauthorized" })
75
+ };
76
+ }
55
77
  const captchaTypeBaseParams = {
56
78
  userSitekeyIpHash: input.userSitekeyIpHash,
57
79
  reason: types.FrictionlessReason.USER_ACCESS_POLICY,
@@ -63,7 +85,6 @@ const handleAccessPolicy = async (input, res) => {
63
85
  logger.info(() => ({
64
86
  msg: "Frictionless decision",
65
87
  data: {
66
- requestId,
67
88
  decision: "user_access_policy",
68
89
  captchaType: types.CaptchaType.image
69
90
  }
@@ -86,7 +107,6 @@ const handleAccessPolicy = async (input, res) => {
86
107
  logger.info(() => ({
87
108
  msg: "Frictionless decision",
88
109
  data: {
89
- requestId,
90
110
  decision: "user_access_policy",
91
111
  captchaType: types.CaptchaType.pow
92
112
  }
@@ -103,7 +123,6 @@ const handleAccessPolicy = async (input, res) => {
103
123
  logger.info(() => ({
104
124
  msg: "Frictionless decision",
105
125
  data: {
106
- requestId,
107
126
  decision: "user_access_policy",
108
127
  captchaType: types.CaptchaType.puzzle
109
128
  }
@@ -6,6 +6,7 @@ const util = require("@prosopo/util");
6
6
  const frictionlessTasks = require("../../../tasks/frictionless/frictionlessTasks.cjs");
7
7
  const frictionlessTasksUtils = require("../../../tasks/frictionless/frictionlessTasksUtils.cjs");
8
8
  const hashUserAgent = require("../../../utils/hashUserAgent.cjs");
9
+ const metrics = require("../../metrics.cjs");
9
10
  const contextAwareValidation = require("../contextAwareValidation.cjs");
10
11
  const constants = require("./constants.cjs");
11
12
  const honeypotResponse = require("./honeypotResponse.cjs");
@@ -52,32 +53,18 @@ const runDecisionMachine = async (input, handle) => {
52
53
  scoreComponents = scoreUpdate.scoreComponents;
53
54
  tasks.frictionlessManager.updateScore(botScore, scoreComponents);
54
55
  }
55
- const hostVerified = await tasks.frictionlessManager.hostVerified(
56
- input.providerSelectEntropy
57
- );
58
- if (!hostVerified.verified) {
59
- const scoreUpdate = tasks.frictionlessManager.scoreIncreaseUnverifiedHost(
60
- hostVerified.domain,
61
- input.baseBotScore,
62
- botScore,
63
- scoreComponents
64
- );
65
- botScore = scoreUpdate.score;
66
- scoreComponents = scoreUpdate.scoreComponents;
67
- tasks.frictionlessManager.updateScore(botScore, scoreComponents);
68
- }
69
56
  const autoBanThreshold = clientRecord.settings.autoBanScoreThreshold;
70
57
  if (autoBanThreshold !== void 0 && Number(botScore) >= autoBanThreshold) {
71
58
  req.logger.info(() => ({
72
59
  msg: "Frictionless decision",
73
60
  data: {
74
- requestId: req.requestId,
75
61
  decision: "auto_ban_score",
76
62
  botScore,
77
63
  autoBanThreshold,
78
64
  token: input.token
79
65
  }
80
66
  }));
67
+ metrics.recordFrictionlessDecision("auto_ban_score");
81
68
  await tasks.frictionlessManager.registerBlockedSession({
82
69
  solvedImagesCount: clientRecord.settings.imageMaxRounds,
83
70
  userSitekeyIpHash,
@@ -92,11 +79,11 @@ const runDecisionMachine = async (input, handle) => {
92
79
  req.logger.info(() => ({
93
80
  msg: "Frictionless decision",
94
81
  data: {
95
- requestId: req.requestId,
96
82
  decision: "webview_detected",
97
83
  captchaType: types.CaptchaType.image
98
84
  }
99
85
  }));
86
+ metrics.recordFrictionlessDecision("webview_detected");
100
87
  honeypotResponse.attachHoneypot(res, clientRecord);
101
88
  return res.json(
102
89
  await tasks.frictionlessManager.sendImageCaptcha({
@@ -116,11 +103,11 @@ const runDecisionMachine = async (input, handle) => {
116
103
  req.logger.info(() => ({
117
104
  msg: "Frictionless decision",
118
105
  data: {
119
- requestId: req.requestId,
120
106
  decision: "timestamp_too_old",
121
107
  captchaType: types.CaptchaType.image
122
108
  }
123
109
  }));
110
+ metrics.recordFrictionlessDecision("timestamp_too_old");
124
111
  honeypotResponse.attachHoneypot(res, clientRecord);
125
112
  return res.json(
126
113
  await tasks.frictionlessManager.sendImageCaptcha({
@@ -149,11 +136,11 @@ const runDecisionMachine = async (input, handle) => {
149
136
  req.logger.info(() => ({
150
137
  msg: "Frictionless decision",
151
138
  data: {
152
- requestId: req.requestId,
153
139
  decision: "bot_score_above_threshold",
154
140
  captchaType: types.CaptchaType.image
155
141
  }
156
142
  }));
143
+ metrics.recordFrictionlessDecision("bot_score_above_threshold");
157
144
  honeypotResponse.attachHoneypot(res, clientRecord);
158
145
  return res.json(
159
146
  await tasks.frictionlessManager.sendImageCaptcha({
@@ -172,11 +159,11 @@ const runDecisionMachine = async (input, handle) => {
172
159
  req.logger.info(() => ({
173
160
  msg: "Frictionless decision",
174
161
  data: {
175
- requestId: req.requestId,
176
162
  decision: "default_pow",
177
163
  captchaType: types.CaptchaType.pow
178
164
  }
179
165
  }));
166
+ metrics.recordFrictionlessDecision("default_pow");
180
167
  honeypotResponse.attachHoneypot(res, clientRecord);
181
168
  return res.json(
182
169
  await tasks.frictionlessManager.sendPowCaptcha({
@@ -208,11 +195,11 @@ const runUserAgentMismatchCheck = async (input, handle) => {
208
195
  req.logger.info(() => ({
209
196
  msg: "Frictionless decision",
210
197
  data: {
211
- requestId: req.requestId,
212
198
  decision: "user_agent_mismatch",
213
199
  captchaType: types.CaptchaType.image
214
200
  }
215
201
  }));
202
+ metrics.recordFrictionlessDecision("user_agent_mismatch");
216
203
  honeypotResponse.attachHoneypot(res, input.clientRecord);
217
204
  return res.json(
218
205
  await input.tasks.frictionlessManager.sendImageCaptcha({
@@ -268,13 +255,13 @@ const runContextAwareValidation = async (input, handle) => {
268
255
  req.logger.info(() => ({
269
256
  msg: "Frictionless decision",
270
257
  data: {
271
- requestId: req.requestId,
272
258
  decision: "context_aware_failed",
273
259
  captchaType: types.CaptchaType.image,
274
260
  sim,
275
261
  threshold
276
262
  }
277
263
  }));
264
+ metrics.recordFrictionlessDecision("context_aware_failed");
278
265
  honeypotResponse.attachHoneypot(res, clientRecord);
279
266
  return res.json(
280
267
  await tasks.frictionlessManager.sendImageCaptcha({
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  const common = require("@prosopo/common");
3
3
  const types = require("@prosopo/types");
4
+ const userAccessPolicy = require("@prosopo/user-access-policy");
4
5
  const util = require("@prosopo/util");
5
6
  const compositeIpAddress = require("../../../compositeIpAddress.cjs");
6
7
  require("../../../tasks/index.cjs");
@@ -10,6 +11,7 @@ const normalizeRequestIp = require("../../../utils/normalizeRequestIp.cjs");
10
11
  const apiToggleMaintenanceModeEndpoint = require("../../admin/apiToggleMaintenanceModeEndpoint.cjs");
11
12
  const blacklistRequestInspector = require("../../blacklistRequestInspector.cjs");
12
13
  const dnsEventUrl = require("../../dnsEventUrl.cjs");
14
+ const metrics = require("../../metrics.cjs");
13
15
  const testSiteKey = require("../../testSiteKey.cjs");
14
16
  const maintenanceModeResponses = require("../maintenanceModeResponses.cjs");
15
17
  const accessPolicy = require("./accessPolicy.cjs");
@@ -26,7 +28,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
26
28
  req.logger.info(() => ({
27
29
  msg: "Frictionless response finished",
28
30
  data: {
29
- requestId: req.requestId,
30
31
  status: res.statusCode,
31
32
  path: req.path,
32
33
  method: req.method
@@ -39,7 +40,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
39
40
  req.logger.info(() => ({
40
41
  msg: "Frictionless handler entry",
41
42
  data: {
42
- requestId: req.requestId,
43
43
  token,
44
44
  user,
45
45
  dapp,
@@ -104,30 +104,68 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
104
104
  );
105
105
  }
106
106
  if (dedup) {
107
- req.logger.info(() => ({
108
- msg: "Reusing existing session for user-IP-sitekey combination",
109
- data: {
110
- userSitekeyIpHash,
111
- sessionId: dedup.sessionId,
112
- captchaType: dedup.captchaType
113
- }
114
- }));
115
- req.logger.info(() => ({
116
- msg: "Frictionless decision",
117
- data: {
118
- requestId: req.requestId,
119
- decision: "reuse_session",
120
- captchaType: dedup.captchaType,
121
- sessionId: dedup.sessionId
122
- }
123
- }));
124
- honeypotResponse.attachHoneypot(res, clientRecord);
125
- return res.json({
126
- [types.ApiParams.captchaType]: dedup.captchaType,
127
- [types.ApiParams.sessionId]: dedup.sessionId,
128
- [types.ApiParams.status]: "ok",
129
- dns_url: dnsEventUrl.buildDnsEventUrl(dedup.sessionId)
130
- });
107
+ const dedupCountryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
108
+ const dedupAsn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
109
+ const dedupUserScope = blacklistRequestInspector.getRequestUserScope(
110
+ util.flatten(req.headers),
111
+ req.ja4,
112
+ normalizedIp,
113
+ user,
114
+ void 0,
115
+ void 0,
116
+ dedupCountryCode,
117
+ dedupAsn
118
+ );
119
+ const dedupAccessPolicy = (await tasks$1.frictionlessManager.getPrioritisedAccessPolicies(
120
+ userAccessRulesStorage,
121
+ dapp,
122
+ dedupUserScope
123
+ ))[0];
124
+ const dedupConflictsWithPolicy = dedupAccessPolicy !== void 0 && (dedupAccessPolicy.type === userAccessPolicy.AccessPolicyType.Block || dedupAccessPolicy.captchaType !== void 0 && dedupAccessPolicy.captchaType !== dedup.captchaType);
125
+ if (dedupConflictsWithPolicy) {
126
+ req.logger.info(() => ({
127
+ msg: "Evicting reused session: cached captchaType conflicts with access policy",
128
+ data: {
129
+ userSitekeyIpHash,
130
+ sessionId: dedup.sessionId,
131
+ cachedCaptchaType: dedup.captchaType,
132
+ policyType: dedupAccessPolicy.type,
133
+ policyCaptchaType: dedupAccessPolicy.captchaType
134
+ }
135
+ }));
136
+ await tasks$1.db.checkAndRemoveSession(dedup.sessionId);
137
+ await Promise.all([
138
+ tasks$1.writeQueue?.invalidateCachedSession(dedup.sessionId) ?? Promise.resolve(),
139
+ tasks$1.writeQueue?.invalidateCachedSessionByHash(
140
+ userSitekeyIpHash
141
+ ) ?? Promise.resolve()
142
+ ]);
143
+ } else {
144
+ req.logger.info(() => ({
145
+ msg: "Reusing existing session for user-IP-sitekey combination",
146
+ data: {
147
+ userSitekeyIpHash,
148
+ sessionId: dedup.sessionId,
149
+ captchaType: dedup.captchaType
150
+ }
151
+ }));
152
+ req.logger.info(() => ({
153
+ msg: "Frictionless decision",
154
+ data: {
155
+ decision: "reuse_session",
156
+ captchaType: dedup.captchaType,
157
+ sessionId: dedup.sessionId
158
+ }
159
+ }));
160
+ metrics.recordFrictionlessDecision("reuse_session");
161
+ honeypotResponse.attachHoneypot(res, clientRecord);
162
+ return res.json({
163
+ [types.ApiParams.captchaType]: dedup.captchaType,
164
+ [types.ApiParams.sessionId]: dedup.sessionId,
165
+ [types.ApiParams.status]: "ok",
166
+ dns_url: dnsEventUrl.buildDnsEventUrl(dedup.sessionId)
167
+ });
168
+ }
131
169
  }
132
170
  const ipAddress = compositeIpAddress.getCompositeIpAddress(normalizedIp);
133
171
  const flatHeaders = util.flatten(req.headers);
@@ -145,7 +183,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
145
183
  flatHeaders,
146
184
  sessionMode,
147
185
  userSitekeyIpHash,
148
- requestId: req.requestId,
149
186
  logger: req.logger
150
187
  },
151
188
  res
@@ -180,7 +217,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
180
217
  const {
181
218
  baseBotScore,
182
219
  timestamp,
183
- providerSelectEntropy,
184
220
  userId,
185
221
  userAgent,
186
222
  webView,
@@ -199,7 +235,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
199
235
  data: {
200
236
  baseBotScore,
201
237
  timestamp,
202
- providerSelectEntropy,
203
238
  userId,
204
239
  userAgent,
205
240
  webView
@@ -216,6 +251,10 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
216
251
  })
217
252
  );
218
253
  }
254
+ metrics.recordBotScore(botScore);
255
+ if (triggeredDetectors && triggeredDetectors.length > 0) {
256
+ metrics.recordDetectorTriggered(triggeredDetectors);
257
+ }
219
258
  const botThreshold = clientRecord.settings?.frictionlessThreshold || constants.DEFAULT_FRICTIONLESS_THRESHOLD;
220
259
  let scoreComponents = {
221
260
  baseScore: baseBotScore,
@@ -228,7 +267,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
228
267
  score: botScore,
229
268
  threshold: botThreshold,
230
269
  scoreComponents,
231
- providerSelectEntropy,
232
270
  ipAddress,
233
271
  webView,
234
272
  iFrame,
@@ -268,12 +306,12 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
268
306
  ...req.ja4 && { ja4: req.ja4 }
269
307
  }
270
308
  });
271
- const userAccessPolicy = accessPolicies[0];
309
+ const userAccessPolicy$1 = accessPolicies[0];
272
310
  const accessPolicyOutcome = await accessPolicy.handleAccessPolicy(
273
311
  {
274
312
  tasks: tasks$1,
275
313
  clientRecord,
276
- userAccessPolicy,
314
+ userAccessPolicy: userAccessPolicy$1,
277
315
  baseBotScore,
278
316
  botScore,
279
317
  scoreComponents,
@@ -281,7 +319,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
281
319
  dapp,
282
320
  ipInfo: req.ipInfo,
283
321
  flatHeaders,
284
- requestId: req.requestId,
285
322
  logger: req.logger,
286
323
  userScope
287
324
  },
@@ -306,7 +343,6 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
306
343
  userId,
307
344
  webView,
308
345
  decryptedHeadHash,
309
- providerSelectEntropy,
310
346
  baseBotScore,
311
347
  botScore,
312
348
  scoreComponents,
@@ -13,7 +13,6 @@ const runConfiguredCaptchaTypeShortCircuit = async (input, res) => {
13
13
  score: 0,
14
14
  threshold: input.clientRecord.settings?.frictionlessThreshold ?? constants.DEFAULT_FRICTIONLESS_THRESHOLD,
15
15
  scoreComponents: { baseScore: 0 },
16
- providerSelectEntropy: 0,
17
16
  ipAddress: input.ipAddress,
18
17
  webView: false,
19
18
  iFrame: false,
@@ -27,7 +26,6 @@ const runConfiguredCaptchaTypeShortCircuit = async (input, res) => {
27
26
  input.logger.info(() => ({
28
27
  msg: "Frictionless decision",
29
28
  data: {
30
- requestId: input.requestId,
31
29
  decision: "configured_captcha_type",
32
30
  captchaType: configuredType
33
31
  }
@@ -7,6 +7,7 @@ require("../../tasks/index.cjs");
7
7
  const normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
8
8
  const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
9
9
  const blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
10
+ const metrics = require("../metrics.cjs");
10
11
  const validateAddress = require("../validateAddress.cjs");
11
12
  const maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
12
13
  const tasks = require("../../tasks/tasks.cjs");
@@ -34,7 +35,26 @@ const getImageCaptchaChallenge = (env, userAccessRulesStorage) => async (req, re
34
35
  })
35
36
  );
36
37
  }
37
- const { datasetId, user, dapp, sessionId, simdReadings } = parsed;
38
+ const {
39
+ datasetId: clientDatasetId,
40
+ user,
41
+ dapp,
42
+ sessionId,
43
+ simdReadings
44
+ } = parsed;
45
+ const datasetId = clientDatasetId ?? env.datasetId;
46
+ if (!datasetId) {
47
+ return next(
48
+ new common.ProsopoApiError("API.BAD_REQUEST", {
49
+ context: {
50
+ code: 400,
51
+ error: "No dataset available. Please upload a dataset first."
52
+ },
53
+ i18n: req.i18n,
54
+ logger: req.logger
55
+ })
56
+ );
57
+ }
38
58
  validateAddress.validateSiteKey(dapp);
39
59
  validateAddress.validateAddr(user);
40
60
  if (apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
@@ -164,8 +184,10 @@ const getImageCaptchaChallenge = (env, userAccessRulesStorage) => async (req, re
164
184
  sessionId
165
185
  }
166
186
  }));
187
+ metrics.recordCaptchaIssued(types.CaptchaType.image);
167
188
  return res.json(captchaResponse);
168
189
  } catch (err) {
190
+ metrics.recordCaptchaIssueError(types.CaptchaType.image);
169
191
  req.logger.error(() => ({
170
192
  err,
171
193
  data: req.params,
@@ -7,6 +7,7 @@ require("../../tasks/index.cjs");
7
7
  const normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
8
8
  const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
9
9
  const blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
10
+ const metrics = require("../metrics.cjs");
10
11
  const validateAddress = require("../validateAddress.cjs");
11
12
  const maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
12
13
  const tasks = require("../../tasks/tasks.cjs");
@@ -175,8 +176,10 @@ const getPoWCaptchaChallenge = (env, userAccessRulesStorage) => async (req, res,
175
176
  session: sessionId
176
177
  }
177
178
  }));
179
+ metrics.recordCaptchaIssued(types.CaptchaType.pow);
178
180
  return res.json(getPowCaptchaResponse);
179
181
  } catch (err) {
182
+ metrics.recordCaptchaIssueError(types.CaptchaType.pow);
180
183
  req.logger.error(() => ({
181
184
  err,
182
185
  body: req.body,
@@ -7,6 +7,7 @@ require("../../tasks/index.cjs");
7
7
  const normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
8
8
  const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
9
9
  const blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
10
+ const metrics = require("../metrics.cjs");
10
11
  const validateAddress = require("../validateAddress.cjs");
11
12
  const maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
12
13
  const tasks = require("../../tasks/tasks.cjs");
@@ -178,8 +179,10 @@ const getPuzzleCaptchaChallenge = (env, userAccessRulesStorage) => async (req, r
178
179
  session: sessionId
179
180
  }
180
181
  }));
182
+ metrics.recordCaptchaIssued(types.CaptchaType.puzzle);
181
183
  return res.json(getPuzzleCaptchaResponse);
182
184
  } catch (err) {
185
+ metrics.recordCaptchaIssueError(types.CaptchaType.puzzle);
183
186
  req.logger.error(() => ({
184
187
  err,
185
188
  body: req.body,
@@ -160,7 +160,6 @@ const buildEscalation = async (tasks2, result, challenge) => {
160
160
  originSession.score,
161
161
  originSession.threshold,
162
162
  originSession.scoreComponents,
163
- originSession.providerSelectEntropy,
164
163
  originSession.ipAddress,
165
164
  routed.captchaType,
166
165
  originSession.siteKey ?? powRecord.dappAccount,
@@ -12,6 +12,9 @@ const submitImageCaptchaSolution = require("./captcha/submitImageCaptchaSolution
12
12
  const submitPoWCaptchaSolution = require("./captcha/submitPoWCaptchaSolution.cjs");
13
13
  const submitPuzzleCaptchaSolution = require("./captcha/submitPuzzleCaptchaSolution.cjs");
14
14
  const handler = require("./captcha/getFrictionlessCaptchaChallenge/handler.cjs");
15
+ const asyncHandler = (handler2) => (req, res, next) => {
16
+ Promise.resolve().then(() => handler2(req, res, next)).catch(next);
17
+ };
15
18
  function prosopoRouter(env) {
16
19
  const router = express.Router();
17
20
  let userAccessRulesStorage;
@@ -26,41 +29,35 @@ function prosopoRouter(env) {
26
29
  }
27
30
  router.post(
28
31
  types.ClientApiPaths.GetImageCaptchaChallenge,
29
- (req, res, next) => getImageCaptchaChallenge(env, userAccessRulesStorage)(req, res, next)
32
+ asyncHandler(getImageCaptchaChallenge(env, userAccessRulesStorage))
30
33
  );
31
34
  router.post(
32
35
  types.ClientApiPaths.SubmitImageCaptchaSolution,
33
- (req, res, next) => submitImageCaptchaSolution(env)(req, res, next)
36
+ asyncHandler(submitImageCaptchaSolution(env))
34
37
  );
35
38
  router.post(
36
39
  types.ClientApiPaths.GetPowCaptchaChallenge,
37
- (req, res, next) => getPoWCaptchaChallenge(env, userAccessRulesStorage)(req, res, next)
40
+ asyncHandler(getPoWCaptchaChallenge(env, userAccessRulesStorage))
38
41
  );
39
42
  router.post(
40
43
  types.ClientApiPaths.SubmitPowCaptchaSolution,
41
- (req, res, next) => submitPoWCaptchaSolution(env)(req, res, next)
44
+ asyncHandler(submitPoWCaptchaSolution(env))
42
45
  );
43
46
  router.post(
44
47
  types.ClientApiPaths.GetFrictionlessCaptchaChallenge,
45
- (req, res, next) => handler(env, userAccessRulesStorage)(
46
- req,
47
- res,
48
- next
49
- )
48
+ asyncHandler(handler(env, userAccessRulesStorage))
50
49
  );
51
50
  router.post(
52
51
  types.ClientApiPaths.GetPuzzleCaptchaChallenge,
53
- (req, res, next) => getPuzzleCaptchaChallenge(env, userAccessRulesStorage)(req, res, next)
52
+ asyncHandler(getPuzzleCaptchaChallenge(env, userAccessRulesStorage))
54
53
  );
55
54
  router.post(
56
55
  types.ClientApiPaths.SubmitPuzzleCaptchaSolution,
57
- (req, res, next) => submitPuzzleCaptchaSolution(env)(req, res, next)
58
- );
59
- router.post(
60
- types.ClientApiPaths.CheckSpamEmail,
61
- (req, res, next) => checkSpamEmail(env)(req, res, next)
56
+ asyncHandler(submitPuzzleCaptchaSolution(env))
62
57
  );
58
+ router.post(types.ClientApiPaths.CheckSpamEmail, asyncHandler(checkSpamEmail(env)));
63
59
  router.use(apiExpressRouter.handleErrors);
64
60
  return router;
65
61
  }
62
+ exports.asyncHandler = asyncHandler;
66
63
  exports.prosopoRouter = prosopoRouter;
@@ -7,6 +7,7 @@ const utilCrypto = require("@prosopo/util-crypto");
7
7
  const zod = require("zod");
8
8
  require("../tasks/index.cjs");
9
9
  const apiToggleMaintenanceModeEndpoint = require("./admin/apiToggleMaintenanceModeEndpoint.cjs");
10
+ const metrics = require("./metrics.cjs");
10
11
  const testSiteKey = require("./testSiteKey.cjs");
11
12
  const tasks = require("../tasks/tasks.cjs");
12
13
  const domainMiddleware = (env) => {
@@ -37,6 +38,7 @@ const domainMiddleware = (env) => {
37
38
  throw invalidSiteKeyError(req.i18n, siteKey, req.logger);
38
39
  }
39
40
  if (testSiteKey.isReservedTestSiteKey(siteKey)) {
41
+ metrics.recordDomainValidation("test_key");
40
42
  next();
41
43
  return;
42
44
  }
@@ -58,6 +60,7 @@ const domainMiddleware = (env) => {
58
60
  for (const candidate of candidateOrigins) {
59
61
  for (const domain of allowedDomains) {
60
62
  if (tasks$1.clientTaskManager.domainPatternMatcher(candidate, domain)) {
63
+ metrics.recordDomainValidation("allowed");
61
64
  next();
62
65
  return;
63
66
  }
@@ -65,6 +68,7 @@ const domainMiddleware = (env) => {
65
68
  }
66
69
  throw unauthorizedOriginError(req.i18n, origin, req.logger);
67
70
  } catch (err) {
71
+ metrics.recordDomainValidation("rejected");
68
72
  if (err instanceof common.ProsopoApiError || err instanceof zod.ZodError || err instanceof SyntaxError) {
69
73
  apiExpressRouter.handleErrors(err, req, res, next);
70
74
  } else {