@prosopo/provider 3.12.14 → 3.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 (356) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/api/captcha/getFrictionlessCaptchaChallenge.js +338 -0
  3. package/dist/api/captcha/getImageCaptchaChallenge.js +150 -0
  4. package/dist/api/captcha/getPoWCaptchaChallenge.js +156 -0
  5. package/dist/api/captcha/submitImageCaptchaSolution.js +87 -0
  6. package/dist/api/captcha/submitPoWCaptchaSolution.js +77 -0
  7. package/dist/api/captcha.js +18 -696
  8. package/dist/api/verify.js +2 -1
  9. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge.cjs +337 -0
  10. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +149 -0
  11. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +155 -0
  12. package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +86 -0
  13. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +76 -0
  14. package/dist/cjs/api/captcha.cjs +17 -695
  15. package/dist/cjs/api/verify.cjs +2 -1
  16. package/dist/cjs/index.cjs +2 -0
  17. package/dist/cjs/schedulers/setClientEntropy.cjs +36 -0
  18. package/dist/cjs/tasks/captchaManager.cjs +2 -1
  19. package/dist/cjs/tasks/client/clientTasks.cjs +15 -0
  20. package/dist/cjs/tasks/detection/decodePayload.cjs +379 -609
  21. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +28 -9
  22. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +8 -2
  23. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +2 -2
  24. package/dist/cjs/tasks/tasks.cjs +1 -0
  25. package/dist/cjs/utils/hashUserIp.cjs +9 -0
  26. package/dist/index.js +2 -0
  27. package/dist/schedulers/setClientEntropy.js +29 -24
  28. package/dist/tasks/captchaManager.js +2 -1
  29. package/dist/tasks/client/clientTasks.js +16 -1
  30. package/dist/tasks/detection/decodePayload.js +379 -609
  31. package/dist/tasks/detection/getBotScore.js +2 -2
  32. package/dist/tasks/frictionless/frictionlessTasks.js +29 -10
  33. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +8 -2
  34. package/dist/tasks/powCaptcha/powTasks.js +2 -2
  35. package/dist/tasks/tasks.js +1 -0
  36. package/dist/utils/hashUserIp.js +9 -0
  37. package/package.json +18 -18
  38. package/coverage/base.css +0 -224
  39. package/coverage/block-navigation.js +0 -87
  40. package/coverage/clover.xml +0 -4278
  41. package/coverage/coverage-final.json +0 -42
  42. package/coverage/favicon.png +0 -0
  43. package/coverage/index.html +0 -311
  44. package/coverage/prettify.css +0 -1
  45. package/coverage/prettify.js +0 -2
  46. package/coverage/sort-arrow-sprite.png +0 -0
  47. package/coverage/sorter.js +0 -210
  48. package/coverage/src/api/admin/apiAdminRoutesProvider.ts.html +0 -214
  49. package/coverage/src/api/admin/apiRegisterSiteKeyEndpoint.ts.html +0 -259
  50. package/coverage/src/api/admin/apiRemoveDetectorKeyEndpoint.ts.html +0 -283
  51. package/coverage/src/api/admin/apiToggleMaintenanceModeEndpoint.ts.html +0 -334
  52. package/coverage/src/api/admin/apiUpdateDetectorKeyEndpoint.ts.html +0 -298
  53. package/coverage/src/api/admin/createApiAdminRoutesProvider.ts.html +0 -163
  54. package/coverage/src/api/admin/index.html +0 -191
  55. package/coverage/src/api/blacklistRequestInspector.ts.html +0 -751
  56. package/coverage/src/api/block.ts.html +0 -187
  57. package/coverage/src/api/captcha.ts.html +0 -2803
  58. package/coverage/src/api/domainMiddleware.ts.html +0 -493
  59. package/coverage/src/api/headerCheckMiddleware.ts.html +0 -256
  60. package/coverage/src/api/ignoreMiddleware.ts.html +0 -181
  61. package/coverage/src/api/index.html +0 -266
  62. package/coverage/src/api/ja4Middleware.ts.html +0 -400
  63. package/coverage/src/api/public.ts.html +0 -343
  64. package/coverage/src/api/robotsMiddleware.ts.html +0 -157
  65. package/coverage/src/api/validateAddress.ts.html +0 -214
  66. package/coverage/src/api/verify.ts.html +0 -871
  67. package/coverage/src/compositeIpAddress.ts.html +0 -340
  68. package/coverage/src/index.html +0 -161
  69. package/coverage/src/index.ts.html +0 -175
  70. package/coverage/src/pairs.ts.html +0 -238
  71. package/coverage/src/rules/index.html +0 -116
  72. package/coverage/src/rules/lang.ts.html +0 -187
  73. package/coverage/src/schedulers/captchaScheduler.ts.html +0 -250
  74. package/coverage/src/schedulers/getClientList.ts.html +0 -271
  75. package/coverage/src/schedulers/index.html +0 -131
  76. package/coverage/src/services/index.html +0 -131
  77. package/coverage/src/services/ipComparison.ts.html +0 -685
  78. package/coverage/src/services/ipInfo.ts.html +0 -490
  79. package/coverage/src/tasks/captchaManager.ts.html +0 -865
  80. package/coverage/src/tasks/client/clientTasks.ts.html +0 -1381
  81. package/coverage/src/tasks/client/index.html +0 -116
  82. package/coverage/src/tasks/dataset/datasetTasks.ts.html +0 -268
  83. package/coverage/src/tasks/dataset/datasetTasksUtils.ts.html +0 -271
  84. package/coverage/src/tasks/dataset/index.html +0 -131
  85. package/coverage/src/tasks/detection/decodePayload.js.html +0 -127
  86. package/coverage/src/tasks/detection/getBotScore.ts.html +0 -244
  87. package/coverage/src/tasks/detection/index.html +0 -131
  88. package/coverage/src/tasks/frictionless/frictionlessTasks.ts.html +0 -1216
  89. package/coverage/src/tasks/frictionless/frictionlessTasksUtils.ts.html +0 -247
  90. package/coverage/src/tasks/frictionless/index.html +0 -131
  91. package/coverage/src/tasks/imgCaptcha/imgCaptchaTasks.ts.html +0 -1972
  92. package/coverage/src/tasks/imgCaptcha/imgCaptchaTasksUtils.ts.html +0 -232
  93. package/coverage/src/tasks/imgCaptcha/index.html +0 -131
  94. package/coverage/src/tasks/index.html +0 -146
  95. package/coverage/src/tasks/index.ts.html +0 -127
  96. package/coverage/src/tasks/powCaptcha/index.html +0 -131
  97. package/coverage/src/tasks/powCaptcha/powTasks.ts.html +0 -961
  98. package/coverage/src/tasks/powCaptcha/powTasksUtils.ts.html +0 -244
  99. package/coverage/src/tasks/tasks.ts.html +0 -388
  100. package/coverage/src/util.ts.html +0 -1627
  101. package/coverage/src/utils/hashUserAgent.ts.html +0 -184
  102. package/coverage/src/utils/index.html +0 -116
  103. package/dist/api/admin/apiAdminRoutesProvider.d.ts +0 -9
  104. package/dist/api/admin/apiAdminRoutesProvider.d.ts.map +0 -1
  105. package/dist/api/admin/apiAdminRoutesProvider.js.map +0 -1
  106. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts +0 -14
  107. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +0 -1
  108. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +0 -1
  109. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts +0 -23
  110. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +0 -1
  111. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js.map +0 -1
  112. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts +0 -13
  113. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts.map +0 -1
  114. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js.map +0 -1
  115. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts +0 -14
  116. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts.map +0 -1
  117. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js.map +0 -1
  118. package/dist/api/admin/createApiAdminRoutesProvider.d.ts +0 -4
  119. package/dist/api/admin/createApiAdminRoutesProvider.d.ts.map +0 -1
  120. package/dist/api/admin/createApiAdminRoutesProvider.js.map +0 -1
  121. package/dist/api/blacklistRequestInspector.d.ts +0 -19
  122. package/dist/api/blacklistRequestInspector.d.ts.map +0 -1
  123. package/dist/api/blacklistRequestInspector.js.map +0 -1
  124. package/dist/api/block.d.ts +0 -3
  125. package/dist/api/block.d.ts.map +0 -1
  126. package/dist/api/block.js.map +0 -1
  127. package/dist/api/captcha.d.ts +0 -4
  128. package/dist/api/captcha.d.ts.map +0 -1
  129. package/dist/api/captcha.js.map +0 -1
  130. package/dist/api/domainMiddleware.d.ts +0 -4
  131. package/dist/api/domainMiddleware.d.ts.map +0 -1
  132. package/dist/api/domainMiddleware.js.map +0 -1
  133. package/dist/api/headerCheckMiddleware.d.ts +0 -4
  134. package/dist/api/headerCheckMiddleware.d.ts.map +0 -1
  135. package/dist/api/headerCheckMiddleware.js.map +0 -1
  136. package/dist/api/ignoreMiddleware.d.ts +0 -3
  137. package/dist/api/ignoreMiddleware.d.ts.map +0 -1
  138. package/dist/api/ignoreMiddleware.js.map +0 -1
  139. package/dist/api/ja4Middleware.d.ts +0 -10
  140. package/dist/api/ja4Middleware.d.ts.map +0 -1
  141. package/dist/api/ja4Middleware.js.map +0 -1
  142. package/dist/api/public.d.ts +0 -4
  143. package/dist/api/public.d.ts.map +0 -1
  144. package/dist/api/public.js.map +0 -1
  145. package/dist/api/robotsMiddleware.d.ts +0 -3
  146. package/dist/api/robotsMiddleware.d.ts.map +0 -1
  147. package/dist/api/robotsMiddleware.js.map +0 -1
  148. package/dist/api/validateAddress.d.ts +0 -5
  149. package/dist/api/validateAddress.d.ts.map +0 -1
  150. package/dist/api/validateAddress.js.map +0 -1
  151. package/dist/api/verify.d.ts +0 -4
  152. package/dist/api/verify.d.ts.map +0 -1
  153. package/dist/api/verify.js.map +0 -1
  154. package/dist/compositeIpAddress.d.ts +0 -5
  155. package/dist/compositeIpAddress.d.ts.map +0 -1
  156. package/dist/compositeIpAddress.js.map +0 -1
  157. package/dist/index.d.ts +0 -17
  158. package/dist/index.d.ts.map +0 -1
  159. package/dist/index.js.map +0 -1
  160. package/dist/pairs.d.ts +0 -3
  161. package/dist/pairs.d.ts.map +0 -1
  162. package/dist/pairs.js.map +0 -1
  163. package/dist/rules/lang.d.ts +0 -3
  164. package/dist/rules/lang.d.ts.map +0 -1
  165. package/dist/rules/lang.js.map +0 -1
  166. package/dist/schedulers/captchaScheduler.d.ts +0 -4
  167. package/dist/schedulers/captchaScheduler.d.ts.map +0 -1
  168. package/dist/schedulers/captchaScheduler.js.map +0 -1
  169. package/dist/schedulers/getClientList.d.ts +0 -4
  170. package/dist/schedulers/getClientList.d.ts.map +0 -1
  171. package/dist/schedulers/getClientList.js.map +0 -1
  172. package/dist/schedulers/setClientEntropy.d.ts +0 -4
  173. package/dist/schedulers/setClientEntropy.d.ts.map +0 -1
  174. package/dist/schedulers/setClientEntropy.js.map +0 -1
  175. package/dist/services/ipComparison.d.ts +0 -3
  176. package/dist/services/ipComparison.d.ts.map +0 -1
  177. package/dist/services/ipComparison.js.map +0 -1
  178. package/dist/services/ipInfo.d.ts +0 -3
  179. package/dist/services/ipInfo.d.ts.map +0 -1
  180. package/dist/services/ipInfo.js.map +0 -1
  181. package/dist/tasks/captchaManager.d.ts +0 -34
  182. package/dist/tasks/captchaManager.d.ts.map +0 -1
  183. package/dist/tasks/captchaManager.js.map +0 -1
  184. package/dist/tasks/client/clientTasks.d.ts +0 -21
  185. package/dist/tasks/client/clientTasks.d.ts.map +0 -1
  186. package/dist/tasks/client/clientTasks.js.map +0 -1
  187. package/dist/tasks/dataset/datasetTasks.d.ts +0 -13
  188. package/dist/tasks/dataset/datasetTasks.d.ts.map +0 -1
  189. package/dist/tasks/dataset/datasetTasks.js.map +0 -1
  190. package/dist/tasks/dataset/datasetTasksUtils.d.ts +0 -3
  191. package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +0 -1
  192. package/dist/tasks/dataset/datasetTasksUtils.js.map +0 -1
  193. package/dist/tasks/detection/decodePayload.d.ts +0 -5
  194. package/dist/tasks/detection/decodePayload.d.ts.map +0 -1
  195. package/dist/tasks/detection/decodePayload.js.map +0 -1
  196. package/dist/tasks/detection/getBotScore.d.ts +0 -20
  197. package/dist/tasks/detection/getBotScore.d.ts.map +0 -1
  198. package/dist/tasks/detection/getBotScore.js.map +0 -1
  199. package/dist/tasks/frictionless/frictionlessTasks.d.ts +0 -67
  200. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +0 -1
  201. package/dist/tasks/frictionless/frictionlessTasks.js.map +0 -1
  202. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts +0 -6
  203. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts.map +0 -1
  204. package/dist/tasks/frictionless/frictionlessTasksUtils.js.map +0 -1
  205. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +0 -30
  206. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +0 -1
  207. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +0 -1
  208. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +0 -7
  209. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +0 -1
  210. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +0 -1
  211. package/dist/tasks/index.d.ts +0 -2
  212. package/dist/tasks/index.d.ts.map +0 -1
  213. package/dist/tasks/index.js.map +0 -1
  214. package/dist/tasks/powCaptcha/powTasks.d.ts +0 -17
  215. package/dist/tasks/powCaptcha/powTasks.d.ts.map +0 -1
  216. package/dist/tasks/powCaptcha/powTasks.js.map +0 -1
  217. package/dist/tasks/powCaptcha/powTasksUtils.d.ts +0 -3
  218. package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +0 -1
  219. package/dist/tasks/powCaptcha/powTasksUtils.js.map +0 -1
  220. package/dist/tasks/tasks.d.ts +0 -25
  221. package/dist/tasks/tasks.d.ts.map +0 -1
  222. package/dist/tasks/tasks.js.map +0 -1
  223. package/dist/tests/index.d.ts +0 -2
  224. package/dist/tests/index.d.ts.map +0 -1
  225. package/dist/tests/index.js +0 -2
  226. package/dist/tests/index.js.map +0 -1
  227. package/dist/tests/integration/accessRules.integration.test.d.ts +0 -2
  228. package/dist/tests/integration/accessRules.integration.test.d.ts.map +0 -1
  229. package/dist/tests/integration/accessRules.integration.test.js +0 -588
  230. package/dist/tests/integration/accessRules.integration.test.js.map +0 -1
  231. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.d.ts +0 -2
  232. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.d.ts.map +0 -1
  233. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +0 -60
  234. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +0 -1
  235. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.d.ts +0 -2
  236. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.d.ts.map +0 -1
  237. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +0 -368
  238. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +0 -1
  239. package/dist/tests/integration/imgCaptcha.integration.test.d.ts +0 -2
  240. package/dist/tests/integration/imgCaptcha.integration.test.d.ts.map +0 -1
  241. package/dist/tests/integration/imgCaptcha.integration.test.js +0 -272
  242. package/dist/tests/integration/imgCaptcha.integration.test.js.map +0 -1
  243. package/dist/tests/integration/ipValidation.integration.test.d.ts +0 -2
  244. package/dist/tests/integration/ipValidation.integration.test.d.ts.map +0 -1
  245. package/dist/tests/integration/ipValidation.integration.test.js +0 -75
  246. package/dist/tests/integration/ipValidation.integration.test.js.map +0 -1
  247. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +0 -32
  248. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +0 -1
  249. package/dist/tests/integration/mocks/solvedTestCaptchas.js +0 -1046
  250. package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +0 -1
  251. package/dist/tests/integration/powCaptcha.integration.test.d.ts +0 -2
  252. package/dist/tests/integration/powCaptcha.integration.test.d.ts.map +0 -1
  253. package/dist/tests/integration/powCaptcha.integration.test.js +0 -308
  254. package/dist/tests/integration/powCaptcha.integration.test.js.map +0 -1
  255. package/dist/tests/integration/registerSitekey.d.ts +0 -3
  256. package/dist/tests/integration/registerSitekey.d.ts.map +0 -1
  257. package/dist/tests/integration/registerSitekey.js +0 -24
  258. package/dist/tests/integration/registerSitekey.js.map +0 -1
  259. package/dist/tests/integration/userAccessPolicy.d.ts +0 -2
  260. package/dist/tests/integration/userAccessPolicy.d.ts.map +0 -1
  261. package/dist/tests/integration/userAccessPolicy.js +0 -2
  262. package/dist/tests/integration/userAccessPolicy.js.map +0 -1
  263. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.d.ts +0 -2
  264. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.d.ts.map +0 -1
  265. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js +0 -60
  266. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js.map +0 -1
  267. package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts +0 -2
  268. package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts.map +0 -1
  269. package/dist/tests/unit/api/ignoreMiddleware.unit.test.js +0 -43
  270. package/dist/tests/unit/api/ignoreMiddleware.unit.test.js.map +0 -1
  271. package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts +0 -2
  272. package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts.map +0 -1
  273. package/dist/tests/unit/api/ja4Middleware.unit.test.js +0 -57
  274. package/dist/tests/unit/api/ja4Middleware.unit.test.js.map +0 -1
  275. package/dist/tests/unit/compositeIpAddress.unit.test.d.ts +0 -2
  276. package/dist/tests/unit/compositeIpAddress.unit.test.d.ts.map +0 -1
  277. package/dist/tests/unit/compositeIpAddress.unit.test.js +0 -86
  278. package/dist/tests/unit/compositeIpAddress.unit.test.js.map +0 -1
  279. package/dist/tests/unit/pairs.unit.test.d.ts +0 -2
  280. package/dist/tests/unit/pairs.unit.test.d.ts.map +0 -1
  281. package/dist/tests/unit/pairs.unit.test.js +0 -83
  282. package/dist/tests/unit/pairs.unit.test.js.map +0 -1
  283. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts +0 -2
  284. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts.map +0 -1
  285. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +0 -75
  286. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +0 -1
  287. package/dist/tests/unit/services/ipComparison.unit.test.d.ts +0 -2
  288. package/dist/tests/unit/services/ipComparison.unit.test.d.ts.map +0 -1
  289. package/dist/tests/unit/services/ipComparison.unit.test.js +0 -258
  290. package/dist/tests/unit/services/ipComparison.unit.test.js.map +0 -1
  291. package/dist/tests/unit/services/ipInfo.unit.test.d.ts +0 -2
  292. package/dist/tests/unit/services/ipInfo.unit.test.d.ts.map +0 -1
  293. package/dist/tests/unit/services/ipInfo.unit.test.js +0 -210
  294. package/dist/tests/unit/services/ipInfo.unit.test.js.map +0 -1
  295. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts +0 -2
  296. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts.map +0 -1
  297. package/dist/tests/unit/tasks/captchaManager.unit.test.js +0 -311
  298. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +0 -1
  299. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts +0 -2
  300. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts.map +0 -1
  301. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +0 -289
  302. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +0 -1
  303. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts +0 -2
  304. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts.map +0 -1
  305. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +0 -92
  306. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +0 -1
  307. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts +0 -2
  308. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts.map +0 -1
  309. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +0 -75
  310. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +0 -1
  311. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.d.ts +0 -2
  312. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.d.ts.map +0 -1
  313. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js +0 -143
  314. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js.map +0 -1
  315. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts +0 -2
  316. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts.map +0 -1
  317. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +0 -145
  318. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +0 -1
  319. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts +0 -2
  320. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts.map +0 -1
  321. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js +0 -64
  322. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js.map +0 -1
  323. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts +0 -2
  324. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts.map +0 -1
  325. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +0 -388
  326. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +0 -1
  327. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts +0 -2
  328. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts.map +0 -1
  329. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +0 -46
  330. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +0 -1
  331. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts +0 -2
  332. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts.map +0 -1
  333. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +0 -216
  334. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +0 -1
  335. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts +0 -2
  336. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts.map +0 -1
  337. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +0 -69
  338. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +0 -1
  339. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.d.ts +0 -2
  340. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.d.ts.map +0 -1
  341. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js +0 -505
  342. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js.map +0 -1
  343. package/dist/tests/unit/util.ipDistance.unit.test.d.ts +0 -2
  344. package/dist/tests/unit/util.ipDistance.unit.test.d.ts.map +0 -1
  345. package/dist/tests/unit/util.ipDistance.unit.test.js +0 -93
  346. package/dist/tests/unit/util.ipDistance.unit.test.js.map +0 -1
  347. package/dist/tests/unit/util.unit.test.d.ts +0 -2
  348. package/dist/tests/unit/util.unit.test.d.ts.map +0 -1
  349. package/dist/tests/unit/util.unit.test.js +0 -170
  350. package/dist/tests/unit/util.unit.test.js.map +0 -1
  351. package/dist/util.d.ts +0 -24
  352. package/dist/util.d.ts.map +0 -1
  353. package/dist/util.js.map +0 -1
  354. package/dist/utils/hashUserAgent.d.ts +0 -2
  355. package/dist/utils/hashUserAgent.d.ts.map +0 -1
  356. package/dist/utils/hashUserAgent.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @prosopo/provider
2
2
 
3
+ ## 3.13.0
4
+ ### Minor Changes
5
+
6
+ - bb5f41c: Context awareness
7
+
8
+ ### Patch Changes
9
+
10
+ - fdef625: fix maint mode
11
+ - 55a64c6: stop refresh image to pow
12
+ - aa8216a: bump
13
+ - 8ce9205: Change engine requirements
14
+ - 6ac5367: Less drastic reaction to bad sim score
15
+ - b6e98b2: Run npm audit
16
+ - 55a64c6: Persist sessions for user ip combinations
17
+ - Updated dependencies [8ce9205]
18
+ - Updated dependencies [15ae7cf]
19
+ - Updated dependencies [bb5f41c]
20
+ - Updated dependencies [55a64c6]
21
+ - Updated dependencies [8ce9205]
22
+ - Updated dependencies [df79c03]
23
+ - Updated dependencies [8f22479]
24
+ - Updated dependencies [b6e98b2]
25
+ - Updated dependencies [55a64c6]
26
+ - @prosopo/user-access-policy@3.5.28
27
+ - @prosopo/types@3.6.0
28
+ - @prosopo/types-database@4.0.0
29
+ - @prosopo/database@3.5.0
30
+ - @prosopo/util@3.2.0
31
+ - @prosopo/api-express-router@3.0.34
32
+ - @prosopo/load-balancer@2.8.9
33
+ - @prosopo/util-crypto@13.5.24
34
+ - @prosopo/api-route@2.6.30
35
+ - @prosopo/types-env@2.7.47
36
+ - @prosopo/datasets@3.0.43
37
+ - @prosopo/keyring@2.8.36
38
+ - @prosopo/common@3.1.22
39
+ - @prosopo/locale@3.1.22
40
+ - @prosopo/api@3.1.33
41
+ - @prosopo/env@3.2.22
42
+ - @prosopo/config@3.1.22
43
+
3
44
  ## 3.12.14
4
45
  ### Patch Changes
5
46
 
@@ -0,0 +1,338 @@
1
+ import { ProsopoApiError } from "@prosopo/common";
2
+ import { GetFrictionlessCaptchaChallengeRequestBody, ApiParams, CaptchaType } from "@prosopo/types";
3
+ import { flatten, compareBinaryStrings } from "@prosopo/util";
4
+ import { getCompositeIpAddress } from "../../compositeIpAddress.js";
5
+ import { FrictionlessReason, FrictionlessManager } from "../../tasks/frictionless/frictionlessTasks.js";
6
+ import { timestampDecayFunction } from "../../tasks/frictionless/frictionlessTasksUtils.js";
7
+ import "../../tasks/index.js";
8
+ import { hashUserAgent } from "../../utils/hashUserAgent.js";
9
+ import { hashUserIp } from "../../utils/hashUserIp.js";
10
+ import { getMaintenanceMode } from "../admin/apiToggleMaintenanceModeEndpoint.js";
11
+ import { getRequestUserScope } from "../blacklistRequestInspector.js";
12
+ import { Tasks } from "../../tasks/tasks.js";
13
+ const DEFAULT_FRICTIONLESS_THRESHOLD = 0.5;
14
+ const getRoundsFromSimScore = (simScore) => {
15
+ if (simScore >= 0.9) return 0;
16
+ if (simScore >= 0.8) return 3;
17
+ if (simScore >= 0.7) return 4;
18
+ if (simScore >= 0.6) return 6;
19
+ if (simScore >= 0.5) return 7;
20
+ return 8;
21
+ };
22
+ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (req, res, next) => {
23
+ try {
24
+ const tasks = new Tasks(env, req.logger);
25
+ const { token, headHash, dapp, user } = GetFrictionlessCaptchaChallengeRequestBody.parse(req.body);
26
+ if (getMaintenanceMode()) {
27
+ req.logger.info(() => ({
28
+ msg: "Maintenance mode active - storing dummy token and sending PoW captcha",
29
+ data: { dapp, user }
30
+ }));
31
+ return res.json(
32
+ await tasks.frictionlessManager.sendPowCaptcha({
33
+ token,
34
+ score: 0,
35
+ threshold: 0.5,
36
+ scoreComponents: {
37
+ baseScore: 0
38
+ },
39
+ providerSelectEntropy: 0,
40
+ ipAddress: getCompositeIpAddress(req.ip || ""),
41
+ webView: false,
42
+ iFrame: false,
43
+ decryptedHeadHash: ""
44
+ })
45
+ );
46
+ }
47
+ const existingToken = await tasks.db.getSessionRecordByToken(token);
48
+ if (existingToken) {
49
+ req.logger.info(() => ({
50
+ token: existingToken,
51
+ msg: "Token has already been used"
52
+ }));
53
+ return next(
54
+ new ProsopoApiError("API.BAD_REQUEST", {
55
+ context: {
56
+ code: 400,
57
+ siteKey: dapp,
58
+ user
59
+ },
60
+ i18n: req.i18n,
61
+ logger: req.logger
62
+ })
63
+ );
64
+ }
65
+ const userSitekeyIpHash = hashUserIp(user, req.ip || "", dapp);
66
+ const existingSession = await tasks.db.getSessionByuserSitekeyIpHash(userSitekeyIpHash);
67
+ if (existingSession) {
68
+ req.logger.info(() => ({
69
+ msg: "Reusing existing session for user-IP-sitekey combination",
70
+ data: {
71
+ userSitekeyIpHash,
72
+ sessionId: existingSession.sessionId,
73
+ captchaType: existingSession.captchaType
74
+ }
75
+ }));
76
+ return res.json({
77
+ [ApiParams.captchaType]: existingSession.captchaType,
78
+ [ApiParams.sessionId]: existingSession.sessionId,
79
+ [ApiParams.status]: "ok"
80
+ });
81
+ }
82
+ const lScore = tasks.frictionlessManager.checkLangRules(
83
+ req.headers["accept-language"] || ""
84
+ );
85
+ const {
86
+ baseBotScore,
87
+ timestamp,
88
+ providerSelectEntropy,
89
+ userId,
90
+ userAgent,
91
+ webView,
92
+ iFrame,
93
+ decryptedHeadHash
94
+ } = await tasks.frictionlessManager.decryptPayload(token, headHash);
95
+ req.logger.debug(() => ({
96
+ msg: "Decrypted payload",
97
+ data: {
98
+ baseBotScore,
99
+ timestamp,
100
+ providerSelectEntropy,
101
+ userId,
102
+ userAgent,
103
+ webView
104
+ }
105
+ }));
106
+ let botScore = baseBotScore + lScore;
107
+ const clientRecord = await tasks.db.getClientRecord(dapp);
108
+ if (!clientRecord) {
109
+ return next(
110
+ new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
111
+ context: { code: 400, siteKey: dapp },
112
+ i18n: req.i18n,
113
+ logger: req.logger
114
+ })
115
+ );
116
+ }
117
+ const { valid, reason } = await tasks.frictionlessManager.isValidRequest(
118
+ clientRecord,
119
+ CaptchaType.frictionless,
120
+ env
121
+ );
122
+ if (!valid) {
123
+ return next(
124
+ new ProsopoApiError(reason || "API.BAD_REQUEST", {
125
+ context: {
126
+ code: 400,
127
+ siteKey: dapp,
128
+ user
129
+ },
130
+ i18n: req.i18n,
131
+ logger: req.logger
132
+ })
133
+ );
134
+ }
135
+ const botThreshold = clientRecord.settings?.frictionlessThreshold || DEFAULT_FRICTIONLESS_THRESHOLD;
136
+ let scoreComponents = {
137
+ baseScore: baseBotScore,
138
+ ...lScore && { lScore }
139
+ };
140
+ const ipAddress = getCompositeIpAddress(req.ip || "");
141
+ tasks.frictionlessManager.setSessionParams({
142
+ token,
143
+ score: botScore,
144
+ threshold: botThreshold,
145
+ scoreComponents,
146
+ providerSelectEntropy,
147
+ ipAddress,
148
+ webView,
149
+ iFrame,
150
+ decryptedHeadHash
151
+ });
152
+ const userScope = getRequestUserScope(
153
+ flatten(req.headers),
154
+ req.ja4,
155
+ req.ip,
156
+ user
157
+ );
158
+ const userAccessPolicy = (await tasks.frictionlessManager.getPrioritisedAccessPolicies(
159
+ userAccessRulesStorage,
160
+ dapp,
161
+ userScope
162
+ ))[0];
163
+ const headersUserAgent = req.headers["user-agent"];
164
+ const hashedHeadersUserAgent = headersUserAgent ? hashUserAgent(headersUserAgent) : "";
165
+ const headersProsopoUser = req.headers["prosopo-user"];
166
+ if (hashedHeadersUserAgent !== userAgent || headersProsopoUser !== userId) {
167
+ req.logger.info(() => ({
168
+ msg: "User agent or user id does not match",
169
+ data: {
170
+ headersUserAgent,
171
+ hashedHeadersUserAgent,
172
+ userAgent,
173
+ // This is the hashed user agent from the token
174
+ headersProsopoUser,
175
+ userId
176
+ }
177
+ }));
178
+ return res.json(
179
+ await tasks.frictionlessManager.sendImageCaptcha({
180
+ solvedImagesCount: timestampDecayFunction(timestamp),
181
+ userSitekeyIpHash,
182
+ reason: FrictionlessReason.USER_AGENT_MISMATCH
183
+ })
184
+ );
185
+ }
186
+ if (userAccessPolicy) {
187
+ const scoreUpdate = tasks.frictionlessManager.scoreIncreaseAccessPolicy(
188
+ userAccessPolicy,
189
+ baseBotScore,
190
+ botScore,
191
+ scoreComponents
192
+ );
193
+ botScore = scoreUpdate.score;
194
+ scoreComponents = scoreUpdate.scoreComponents;
195
+ tasks.frictionlessManager.updateScore(botScore, scoreComponents);
196
+ if (userAccessPolicy.captchaType === CaptchaType.image) {
197
+ return res.json(
198
+ await tasks.frictionlessManager.sendImageCaptcha({
199
+ solvedImagesCount: userAccessPolicy.solvedImagesCount,
200
+ userSitekeyIpHash,
201
+ reason: FrictionlessReason.USER_ACCESS_POLICY
202
+ })
203
+ );
204
+ }
205
+ if (userAccessPolicy.captchaType === CaptchaType.pow) {
206
+ return res.json(
207
+ await tasks.frictionlessManager.sendPowCaptcha({
208
+ userSitekeyIpHash,
209
+ reason: FrictionlessReason.USER_ACCESS_POLICY
210
+ })
211
+ );
212
+ }
213
+ }
214
+ if (clientRecord.settings.contextAware?.enabled) {
215
+ const clientEntropy = await tasks.frictionlessManager.getClientEntropy(
216
+ clientRecord.account
217
+ );
218
+ if (clientEntropy) {
219
+ if (!decryptedHeadHash) {
220
+ tasks.logger.info(() => ({
221
+ msg: "No decryptedHeadHash in session for context aware client"
222
+ }));
223
+ return next(
224
+ new ProsopoApiError("API.BAD_REQUEST", {
225
+ context: {
226
+ code: 400,
227
+ siteKey: dapp,
228
+ user
229
+ },
230
+ i18n: req.i18n,
231
+ logger: req.logger
232
+ })
233
+ );
234
+ }
235
+ const sim = compareBinaryStrings(decryptedHeadHash, clientEntropy);
236
+ const isValidContext = sim >= clientRecord.settings.contextAware.threshold;
237
+ if (!isValidContext) {
238
+ return res.json(
239
+ await tasks.frictionlessManager.sendImageCaptcha({
240
+ solvedImagesCount: getRoundsFromSimScore(sim),
241
+ userSitekeyIpHash,
242
+ reason: FrictionlessReason.CONTEXT_AWARE_VALIDATION_FAILED
243
+ })
244
+ );
245
+ }
246
+ }
247
+ }
248
+ if (clientRecord.settings.disallowWebView && webView) {
249
+ tasks.logger.info(() => ({
250
+ msg: "WebView detected"
251
+ }));
252
+ const scoreUpdate = tasks.frictionlessManager.scoreIncreaseWebView(
253
+ baseBotScore,
254
+ botScore,
255
+ scoreComponents
256
+ );
257
+ botScore = scoreUpdate.score;
258
+ scoreComponents = scoreUpdate.scoreComponents;
259
+ tasks.frictionlessManager.updateScore(botScore, scoreComponents);
260
+ return res.json(
261
+ await tasks.frictionlessManager.sendImageCaptcha({
262
+ solvedImagesCount: env.config.captchas.solved.count * 2,
263
+ userSitekeyIpHash,
264
+ reason: FrictionlessReason.WEBVIEW_DETECTED
265
+ })
266
+ );
267
+ }
268
+ if (FrictionlessManager.timestampTooOld(timestamp)) {
269
+ const scoreUpdate = tasks.frictionlessManager.scoreIncreaseTimestamp(
270
+ timestamp,
271
+ baseBotScore,
272
+ botScore,
273
+ scoreComponents
274
+ );
275
+ botScore = scoreUpdate.score;
276
+ scoreComponents = scoreUpdate.scoreComponents;
277
+ tasks.frictionlessManager.updateScore(botScore, scoreComponents);
278
+ return res.json(
279
+ await tasks.frictionlessManager.sendImageCaptcha({
280
+ solvedImagesCount: timestampDecayFunction(timestamp),
281
+ userSitekeyIpHash,
282
+ reason: FrictionlessReason.OLD_TIMESTAMP
283
+ })
284
+ );
285
+ }
286
+ const hostVerified = await tasks.frictionlessManager.hostVerified(
287
+ providerSelectEntropy
288
+ );
289
+ if (!hostVerified.verified) {
290
+ const scoreUpdate = tasks.frictionlessManager.scoreIncreaseUnverifiedHost(
291
+ hostVerified.domain,
292
+ baseBotScore,
293
+ botScore,
294
+ scoreComponents
295
+ );
296
+ botScore = scoreUpdate.score;
297
+ scoreComponents = scoreUpdate.scoreComponents;
298
+ tasks.frictionlessManager.updateScore(botScore, scoreComponents);
299
+ }
300
+ if (Number(botScore) > botThreshold) {
301
+ req.logger.info(() => ({
302
+ msg: "Bot score is greater than threshold",
303
+ data: {
304
+ botScore,
305
+ botThreshold,
306
+ token
307
+ }
308
+ }));
309
+ return res.json(
310
+ await tasks.frictionlessManager.sendImageCaptcha({
311
+ solvedImagesCount: env.config.captchas.solved.count,
312
+ userSitekeyIpHash,
313
+ reason: FrictionlessReason.BOT_SCORE_ABOVE_THRESHOLD
314
+ })
315
+ );
316
+ }
317
+ return res.json(
318
+ await tasks.frictionlessManager.sendPowCaptcha({
319
+ userSitekeyIpHash
320
+ })
321
+ );
322
+ } catch (err) {
323
+ req.logger.error(() => ({
324
+ err,
325
+ msg: "Error in frictionless captcha challenge"
326
+ }));
327
+ return next(
328
+ new ProsopoApiError("API.BAD_REQUEST", {
329
+ context: { code: 400, error: err },
330
+ i18n: req.i18n,
331
+ logger: req.logger
332
+ })
333
+ );
334
+ }
335
+ };
336
+ export {
337
+ getFrictionlessCaptchaChallenge as default
338
+ };
@@ -0,0 +1,150 @@
1
+ import { ProsopoApiError } from "@prosopo/common";
2
+ import { parseCaptchaAssets } from "@prosopo/datasets";
3
+ import { CaptchaRequestBody, CaptchaType, ApiParams } from "@prosopo/types";
4
+ import { getIPAddress, flatten } from "@prosopo/util";
5
+ import "../../tasks/index.js";
6
+ import { getRequestUserScope } from "../blacklistRequestInspector.js";
7
+ import { validateSiteKey, validateAddr } from "../validateAddress.js";
8
+ import { Tasks } from "../../tasks/tasks.js";
9
+ const getImageCaptchaChallenge = (env, userAccessRulesStorage) => async (req, res, next) => {
10
+ const tasks = new Tasks(env, req.logger);
11
+ let parsed;
12
+ if (!req.ip) {
13
+ return next(
14
+ new ProsopoApiError("API.BAD_REQUEST", {
15
+ context: { code: 400, error: "IP address not found" },
16
+ i18n: req.i18n,
17
+ logger: req.logger
18
+ })
19
+ );
20
+ }
21
+ const ipAddress = getIPAddress(req.ip || "");
22
+ try {
23
+ parsed = CaptchaRequestBody.parse(req.body);
24
+ } catch (err) {
25
+ return next(
26
+ new ProsopoApiError("CAPTCHA.PARSE_ERROR", {
27
+ context: { code: 400, error: err },
28
+ i18n: req.i18n,
29
+ logger: req.logger
30
+ })
31
+ );
32
+ }
33
+ const { datasetId, user, dapp, sessionId } = parsed;
34
+ validateSiteKey(dapp);
35
+ validateAddr(user);
36
+ try {
37
+ const clientRecord = await tasks.db.getClientRecord(dapp);
38
+ if (!clientRecord) {
39
+ return next(
40
+ new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
41
+ context: { code: 400, siteKey: dapp },
42
+ i18n: req.i18n,
43
+ logger: req.logger
44
+ })
45
+ );
46
+ }
47
+ const userScope = getRequestUserScope(
48
+ flatten(req.headers),
49
+ req.ja4,
50
+ req.ip,
51
+ user
52
+ );
53
+ const userAccessPolicy = (await tasks.imgCaptchaManager.getPrioritisedAccessPolicies(
54
+ userAccessRulesStorage,
55
+ dapp,
56
+ userScope
57
+ ))[0];
58
+ const {
59
+ valid,
60
+ reason,
61
+ sessionId: validSessionId,
62
+ solvedImagesCount
63
+ } = await tasks.imgCaptchaManager.isValidRequest(
64
+ clientRecord,
65
+ CaptchaType.image,
66
+ env,
67
+ sessionId,
68
+ userAccessPolicy,
69
+ req.ip
70
+ );
71
+ if (!valid) {
72
+ return next(
73
+ new ProsopoApiError(reason || "API.BAD_REQUEST", {
74
+ context: {
75
+ code: 400,
76
+ siteKey: dapp,
77
+ user
78
+ },
79
+ i18n: req.i18n,
80
+ logger: req.logger
81
+ })
82
+ );
83
+ }
84
+ const captchaConfig = {
85
+ solved: {
86
+ count: solvedImagesCount || userAccessPolicy?.solvedImagesCount || env.config.captchas.solved.count
87
+ },
88
+ unsolved: {
89
+ count: userAccessPolicy?.unsolvedImagesCount || env.config.captchas.unsolved.count
90
+ }
91
+ };
92
+ const taskData = await tasks.imgCaptchaManager.getRandomCaptchasAndRequestHash(
93
+ datasetId,
94
+ user,
95
+ ipAddress,
96
+ captchaConfig,
97
+ clientRecord.settings.imageThreshold ?? 0.8,
98
+ validSessionId
99
+ );
100
+ const captchaResponse = {
101
+ [ApiParams.status]: "ok",
102
+ [ApiParams.captchas]: taskData.captchas.map((captcha) => ({
103
+ ...captcha,
104
+ target: req.t(`TARGET.${captcha.target}`),
105
+ items: captcha.items.map(
106
+ (item) => parseCaptchaAssets(item, env.assetsResolver)
107
+ )
108
+ })),
109
+ [ApiParams.requestHash]: taskData.requestHash,
110
+ [ApiParams.timestamp]: taskData.timestamp.toString(),
111
+ [ApiParams.signature]: {
112
+ [ApiParams.provider]: {
113
+ [ApiParams.requestHash]: taskData.signedRequestHash
114
+ }
115
+ }
116
+ };
117
+ req.logger.info(() => ({
118
+ msg: "Image captcha challenge issued",
119
+ data: {
120
+ captchaType: CaptchaType.image,
121
+ requestHash: taskData.requestHash,
122
+ solvedImagesCount: captchaConfig.solved.count,
123
+ user,
124
+ dapp,
125
+ sessionId
126
+ }
127
+ }));
128
+ return res.json(captchaResponse);
129
+ } catch (err) {
130
+ req.logger.error(() => ({
131
+ err,
132
+ data: req.params,
133
+ msg: "Error in image captcha challenge request"
134
+ }));
135
+ return next(
136
+ new ProsopoApiError("API.BAD_REQUEST", {
137
+ context: {
138
+ error: err,
139
+ code: 500,
140
+ params: req.params
141
+ },
142
+ i18n: req.i18n,
143
+ logger: req.logger
144
+ })
145
+ );
146
+ }
147
+ };
148
+ export {
149
+ getImageCaptchaChallenge as default
150
+ };
@@ -0,0 +1,156 @@
1
+ import { ProsopoApiError } from "@prosopo/common";
2
+ import { GetPowCaptchaChallengeRequestBody, CaptchaType, ApiParams } from "@prosopo/types";
3
+ import { flatten } from "@prosopo/util";
4
+ import { getCompositeIpAddress } from "../../compositeIpAddress.js";
5
+ import "../../tasks/index.js";
6
+ import { getRequestUserScope } from "../blacklistRequestInspector.js";
7
+ import { validateSiteKey, validateAddr } from "../validateAddress.js";
8
+ import { Tasks } from "../../tasks/tasks.js";
9
+ const getPoWCaptchaChallenge = (env, userAccessRulesStorage) => async (req, res, next) => {
10
+ let parsed;
11
+ const tasks = new Tasks(env);
12
+ tasks.setLogger(req.logger);
13
+ try {
14
+ parsed = GetPowCaptchaChallengeRequestBody.parse(req.body);
15
+ } catch (err) {
16
+ return next(
17
+ new ProsopoApiError("CAPTCHA.PARSE_ERROR", {
18
+ context: { code: 400, error: err },
19
+ i18n: req.i18n,
20
+ logger: req.logger
21
+ })
22
+ );
23
+ }
24
+ const { user, dapp, sessionId } = parsed;
25
+ validateSiteKey(dapp);
26
+ validateAddr(user);
27
+ try {
28
+ const clientSettings = await tasks.db.getClientRecord(dapp);
29
+ if (!clientSettings) {
30
+ return next(
31
+ new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
32
+ context: { code: 400, siteKey: dapp },
33
+ i18n: req.i18n,
34
+ logger: req.logger
35
+ })
36
+ );
37
+ }
38
+ const userScope = getRequestUserScope(
39
+ flatten(req.headers),
40
+ req.ja4,
41
+ req.ip,
42
+ user
43
+ );
44
+ const userAccessPolicy = (await tasks.powCaptchaManager.getPrioritisedAccessPolicies(
45
+ userAccessRulesStorage,
46
+ dapp,
47
+ userScope
48
+ ))[0];
49
+ const {
50
+ valid,
51
+ reason,
52
+ sessionId: validSessionId,
53
+ powDifficulty
54
+ } = await tasks.powCaptchaManager.isValidRequest(
55
+ clientSettings,
56
+ CaptchaType.pow,
57
+ env,
58
+ sessionId,
59
+ userAccessPolicy,
60
+ req.ip
61
+ );
62
+ if (!valid) {
63
+ return next(
64
+ new ProsopoApiError(reason || "API.BAD_REQUEST", {
65
+ context: {
66
+ code: 400,
67
+ siteKey: dapp,
68
+ user
69
+ },
70
+ i18n: req.i18n,
71
+ logger: req.logger
72
+ })
73
+ );
74
+ }
75
+ const origin = req.headers.origin;
76
+ if (!origin) {
77
+ return next(
78
+ new ProsopoApiError("API.BAD_REQUEST", {
79
+ context: {
80
+ error: "Origin header not found",
81
+ code: 400,
82
+ siteKey: dapp,
83
+ user
84
+ },
85
+ i18n: req.i18n,
86
+ logger: req.logger
87
+ })
88
+ );
89
+ }
90
+ const difficulty = powDifficulty || userAccessPolicy?.powDifficulty || clientSettings?.settings?.powDifficulty;
91
+ const challenge = await tasks.powCaptchaManager.getPowCaptchaChallenge(
92
+ user,
93
+ dapp,
94
+ origin,
95
+ difficulty
96
+ );
97
+ await tasks.db.storePowCaptchaRecord(
98
+ challenge.challenge,
99
+ {
100
+ requestedAtTimestamp: challenge.requestedAtTimestamp,
101
+ userAccount: user,
102
+ dappAccount: dapp
103
+ },
104
+ challenge.difficulty,
105
+ challenge.providerSignature,
106
+ getCompositeIpAddress(req.ip || ""),
107
+ flatten(req.headers),
108
+ req.ja4,
109
+ validSessionId
110
+ );
111
+ const getPowCaptchaResponse = {
112
+ [ApiParams.status]: "ok",
113
+ [ApiParams.challenge]: challenge.challenge,
114
+ [ApiParams.difficulty]: challenge.difficulty,
115
+ [ApiParams.timestamp]: challenge.requestedAtTimestamp.toString(),
116
+ [ApiParams.signature]: {
117
+ [ApiParams.provider]: {
118
+ [ApiParams.challenge]: challenge.providerSignature
119
+ }
120
+ }
121
+ };
122
+ req.logger.info(() => ({
123
+ msg: "PoW captcha challenge issued",
124
+ data: {
125
+ captchaType: CaptchaType.pow,
126
+ challenge: challenge.challenge,
127
+ difficulty: challenge.difficulty,
128
+ user,
129
+ dapp,
130
+ session: sessionId
131
+ }
132
+ }));
133
+ return res.json(getPowCaptchaResponse);
134
+ } catch (err) {
135
+ req.logger.error(() => ({
136
+ err,
137
+ body: req.body,
138
+ msg: "Error in PoW captcha challenge request"
139
+ }));
140
+ return next(
141
+ new 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
+ };
154
+ export {
155
+ getPoWCaptchaChallenge as default
156
+ };