@prosopo/provider 3.1.3 → 3.2.1

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 (227) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/api/admin/apiAdminRoutesProvider.js +26 -21
  3. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +21 -20
  4. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js +27 -27
  5. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js +33 -33
  6. package/dist/api/admin/createApiAdminRoutesProvider.js +8 -5
  7. package/dist/api/blacklistRequestInspector.js +116 -98
  8. package/dist/api/block.js +13 -8
  9. package/dist/api/captcha.js +519 -356
  10. package/dist/api/domainMiddleware.js +75 -68
  11. package/dist/api/headerCheckMiddleware.js +26 -25
  12. package/dist/api/ignoreMiddleware.js +12 -10
  13. package/dist/api/ja4Middleware.js +75 -80
  14. package/dist/api/public.js +26 -23
  15. package/dist/api/robotsMiddleware.js +11 -9
  16. package/dist/api/validateAddress.js +20 -18
  17. package/dist/api/verify.js +133 -95
  18. package/dist/cjs/api/blacklistRequestInspector.cjs +4 -6
  19. package/dist/cjs/api/captcha.cjs +45 -36
  20. package/dist/cjs/api/ja4Middleware.cjs +4 -1
  21. package/dist/cjs/tasks/captchaManager.cjs +24 -10
  22. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +0 -3
  23. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +1 -1
  24. package/dist/index.js +38 -15
  25. package/dist/rules/lang.js +14 -14
  26. package/dist/schedulers/captchaScheduler.js +28 -23
  27. package/dist/schedulers/getClientList.js +29 -24
  28. package/dist/tasks/captchaManager.js +109 -85
  29. package/dist/tasks/client/clientTasks.js +265 -204
  30. package/dist/tasks/dataset/datasetTasks.js +27 -16
  31. package/dist/tasks/dataset/datasetTasksUtils.js +31 -31
  32. package/dist/tasks/detection/decodePayload.js +378 -208
  33. package/dist/tasks/detection/getBotScore.js +12 -10
  34. package/dist/tasks/frictionless/frictionlessTasks.js +117 -119
  35. package/dist/tasks/frictionless/frictionlessTasksUtils.js +10 -5
  36. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +360 -271
  37. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +23 -16
  38. package/dist/tasks/index.js +4 -2
  39. package/dist/tasks/powCaptcha/powTasks.js +157 -97
  40. package/dist/tasks/powCaptcha/powTasksUtils.js +24 -20
  41. package/dist/tasks/tasks.js +53 -29
  42. package/dist/util.js +98 -88
  43. package/package.json +31 -27
  44. package/vite.cjs.config.ts +4 -1
  45. package/vite.esm.config.ts +20 -0
  46. package/vite.test.config.ts +15 -3
  47. package/dist/api/admin/apiAdminRoutesProvider.d.ts +0 -9
  48. package/dist/api/admin/apiAdminRoutesProvider.d.ts.map +0 -1
  49. package/dist/api/admin/apiAdminRoutesProvider.js.map +0 -1
  50. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts +0 -14
  51. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +0 -1
  52. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +0 -1
  53. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts +0 -14
  54. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +0 -1
  55. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js.map +0 -1
  56. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts +0 -14
  57. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts.map +0 -1
  58. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js.map +0 -1
  59. package/dist/api/admin/createApiAdminRoutesProvider.d.ts +0 -4
  60. package/dist/api/admin/createApiAdminRoutesProvider.d.ts.map +0 -1
  61. package/dist/api/admin/createApiAdminRoutesProvider.js.map +0 -1
  62. package/dist/api/blacklistRequestInspector.d.ts +0 -44
  63. package/dist/api/blacklistRequestInspector.d.ts.map +0 -1
  64. package/dist/api/blacklistRequestInspector.js.map +0 -1
  65. package/dist/api/block.d.ts +0 -3
  66. package/dist/api/block.d.ts.map +0 -1
  67. package/dist/api/block.js.map +0 -1
  68. package/dist/api/captcha.d.ts +0 -4
  69. package/dist/api/captcha.d.ts.map +0 -1
  70. package/dist/api/captcha.js.map +0 -1
  71. package/dist/api/domainMiddleware.d.ts +0 -4
  72. package/dist/api/domainMiddleware.d.ts.map +0 -1
  73. package/dist/api/domainMiddleware.js.map +0 -1
  74. package/dist/api/headerCheckMiddleware.d.ts +0 -4
  75. package/dist/api/headerCheckMiddleware.d.ts.map +0 -1
  76. package/dist/api/headerCheckMiddleware.js.map +0 -1
  77. package/dist/api/ignoreMiddleware.d.ts +0 -3
  78. package/dist/api/ignoreMiddleware.d.ts.map +0 -1
  79. package/dist/api/ignoreMiddleware.js.map +0 -1
  80. package/dist/api/ja4Middleware.d.ts +0 -10
  81. package/dist/api/ja4Middleware.d.ts.map +0 -1
  82. package/dist/api/ja4Middleware.js.map +0 -1
  83. package/dist/api/public.d.ts +0 -3
  84. package/dist/api/public.d.ts.map +0 -1
  85. package/dist/api/public.js.map +0 -1
  86. package/dist/api/robotsMiddleware.d.ts +0 -3
  87. package/dist/api/robotsMiddleware.d.ts.map +0 -1
  88. package/dist/api/robotsMiddleware.js.map +0 -1
  89. package/dist/api/validateAddress.d.ts +0 -5
  90. package/dist/api/validateAddress.d.ts.map +0 -1
  91. package/dist/api/validateAddress.js.map +0 -1
  92. package/dist/api/verify.d.ts +0 -4
  93. package/dist/api/verify.d.ts.map +0 -1
  94. package/dist/api/verify.js.map +0 -1
  95. package/dist/index.d.ts +0 -15
  96. package/dist/index.d.ts.map +0 -1
  97. package/dist/index.js.map +0 -1
  98. package/dist/rules/lang.d.ts +0 -3
  99. package/dist/rules/lang.d.ts.map +0 -1
  100. package/dist/rules/lang.js.map +0 -1
  101. package/dist/schedulers/captchaScheduler.d.ts +0 -4
  102. package/dist/schedulers/captchaScheduler.d.ts.map +0 -1
  103. package/dist/schedulers/captchaScheduler.js.map +0 -1
  104. package/dist/schedulers/getClientList.d.ts +0 -4
  105. package/dist/schedulers/getClientList.d.ts.map +0 -1
  106. package/dist/schedulers/getClientList.js.map +0 -1
  107. package/dist/tasks/captchaManager.d.ts +0 -48
  108. package/dist/tasks/captchaManager.d.ts.map +0 -1
  109. package/dist/tasks/captchaManager.js.map +0 -1
  110. package/dist/tasks/client/clientTasks.d.ts +0 -21
  111. package/dist/tasks/client/clientTasks.d.ts.map +0 -1
  112. package/dist/tasks/client/clientTasks.js.map +0 -1
  113. package/dist/tasks/dataset/datasetTasks.d.ts +0 -13
  114. package/dist/tasks/dataset/datasetTasks.d.ts.map +0 -1
  115. package/dist/tasks/dataset/datasetTasks.js.map +0 -1
  116. package/dist/tasks/dataset/datasetTasksUtils.d.ts +0 -3
  117. package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +0 -1
  118. package/dist/tasks/dataset/datasetTasksUtils.js.map +0 -1
  119. package/dist/tasks/detection/decodePayload.d.ts +0 -5
  120. package/dist/tasks/detection/decodePayload.d.ts.map +0 -1
  121. package/dist/tasks/detection/decodePayload.js.map +0 -1
  122. package/dist/tasks/detection/getBotScore.d.ts +0 -5
  123. package/dist/tasks/detection/getBotScore.d.ts.map +0 -1
  124. package/dist/tasks/detection/getBotScore.js.map +0 -1
  125. package/dist/tasks/frictionless/frictionlessTasks.d.ts +0 -23
  126. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +0 -1
  127. package/dist/tasks/frictionless/frictionlessTasks.js.map +0 -1
  128. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts +0 -5
  129. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts.map +0 -1
  130. package/dist/tasks/frictionless/frictionlessTasksUtils.js.map +0 -1
  131. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +0 -29
  132. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +0 -1
  133. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +0 -1
  134. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +0 -7
  135. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +0 -1
  136. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +0 -1
  137. package/dist/tasks/index.d.ts +0 -2
  138. package/dist/tasks/index.d.ts.map +0 -1
  139. package/dist/tasks/index.js.map +0 -1
  140. package/dist/tasks/powCaptcha/powTasks.d.ts +0 -16
  141. package/dist/tasks/powCaptcha/powTasks.d.ts.map +0 -1
  142. package/dist/tasks/powCaptcha/powTasks.js.map +0 -1
  143. package/dist/tasks/powCaptcha/powTasksUtils.d.ts +0 -3
  144. package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +0 -1
  145. package/dist/tasks/powCaptcha/powTasksUtils.js.map +0 -1
  146. package/dist/tasks/tasks.d.ts +0 -25
  147. package/dist/tasks/tasks.d.ts.map +0 -1
  148. package/dist/tasks/tasks.js.map +0 -1
  149. package/dist/tests/index.d.ts +0 -2
  150. package/dist/tests/index.d.ts.map +0 -1
  151. package/dist/tests/index.js +0 -2
  152. package/dist/tests/index.js.map +0 -1
  153. package/dist/tests/integration/imgCaptcha.integration.test.d.ts +0 -2
  154. package/dist/tests/integration/imgCaptcha.integration.test.d.ts.map +0 -1
  155. package/dist/tests/integration/imgCaptcha.integration.test.js +0 -261
  156. package/dist/tests/integration/imgCaptcha.integration.test.js.map +0 -1
  157. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +0 -32
  158. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +0 -1
  159. package/dist/tests/integration/mocks/solvedTestCaptchas.js +0 -1046
  160. package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +0 -1
  161. package/dist/tests/integration/powCaptcha.integration.test.d.ts +0 -2
  162. package/dist/tests/integration/powCaptcha.integration.test.d.ts.map +0 -1
  163. package/dist/tests/integration/powCaptcha.integration.test.js +0 -299
  164. package/dist/tests/integration/powCaptcha.integration.test.js.map +0 -1
  165. package/dist/tests/integration/registerSitekey.d.ts +0 -3
  166. package/dist/tests/integration/registerSitekey.d.ts.map +0 -1
  167. package/dist/tests/integration/registerSitekey.js +0 -39
  168. package/dist/tests/integration/registerSitekey.js.map +0 -1
  169. package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts +0 -2
  170. package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts.map +0 -1
  171. package/dist/tests/unit/api/ignoreMiddleware.unit.test.js +0 -43
  172. package/dist/tests/unit/api/ignoreMiddleware.unit.test.js.map +0 -1
  173. package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts +0 -2
  174. package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts.map +0 -1
  175. package/dist/tests/unit/api/ja4Middleware.unit.test.js +0 -71
  176. package/dist/tests/unit/api/ja4Middleware.unit.test.js.map +0 -1
  177. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts +0 -2
  178. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts.map +0 -1
  179. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +0 -75
  180. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +0 -1
  181. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts +0 -2
  182. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts.map +0 -1
  183. package/dist/tests/unit/tasks/captchaManager.unit.test.js +0 -236
  184. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +0 -1
  185. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts +0 -2
  186. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts.map +0 -1
  187. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +0 -277
  188. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +0 -1
  189. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts +0 -2
  190. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts.map +0 -1
  191. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +0 -93
  192. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +0 -1
  193. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts +0 -2
  194. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts.map +0 -1
  195. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +0 -75
  196. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +0 -1
  197. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts +0 -2
  198. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts.map +0 -1
  199. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +0 -68
  200. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +0 -1
  201. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts +0 -2
  202. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts.map +0 -1
  203. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js +0 -37
  204. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js.map +0 -1
  205. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts +0 -2
  206. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts.map +0 -1
  207. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +0 -402
  208. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +0 -1
  209. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts +0 -2
  210. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts.map +0 -1
  211. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +0 -46
  212. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +0 -1
  213. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts +0 -2
  214. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts.map +0 -1
  215. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +0 -228
  216. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +0 -1
  217. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts +0 -2
  218. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts.map +0 -1
  219. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +0 -68
  220. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +0 -1
  221. package/dist/tests/unit/util.unit.test.d.ts +0 -2
  222. package/dist/tests/unit/util.unit.test.d.ts.map +0 -1
  223. package/dist/tests/unit/util.unit.test.js +0 -148
  224. package/dist/tests/unit/util.unit.test.js.map +0 -1
  225. package/dist/util.d.ts +0 -13
  226. package/dist/util.d.ts.map +0 -1
  227. package/dist/util.js.map +0 -1
@@ -1,103 +1,141 @@
1
- import { handleErrors, verifySignature } from "@prosopo/api-express-router";
1
+ import { verifySignature, handleErrors } from "@prosopo/api-express-router";
2
2
  import { ProsopoApiError } from "@prosopo/common";
3
- import { ApiParams, ClientApiPaths, ServerPowCaptchaVerifyRequestBody, VerifySolutionBody, decodeProcaptchaOutput, } from "@prosopo/types";
3
+ import { ClientApiPaths, VerifySolutionBody, decodeProcaptchaOutput, ApiParams, ServerPowCaptchaVerifyRequestBody } from "@prosopo/types";
4
4
  import { validateAddress } from "@prosopo/util-crypto";
5
5
  import express from "express";
6
6
  import { Tasks } from "../tasks/tasks.js";
7
- export function prosopoVerifyRouter(env) {
8
- const router = express.Router();
9
- router.post(ClientApiPaths.VerifyImageCaptchaSolutionDapp, async (req, res, next) => {
10
- const tasks = new Tasks(env, req.logger);
11
- let parsed;
12
- try {
13
- parsed = VerifySolutionBody.parse(req.body);
7
+ function prosopoVerifyRouter(env) {
8
+ const router = express.Router();
9
+ router.post(
10
+ ClientApiPaths.VerifyImageCaptchaSolutionDapp,
11
+ async (req, res, next) => {
12
+ const tasks = new Tasks(env, req.logger);
13
+ let parsed;
14
+ try {
15
+ parsed = VerifySolutionBody.parse(req.body);
16
+ } catch (err) {
17
+ return next(
18
+ new ProsopoApiError("CAPTCHA.PARSE_ERROR", {
19
+ context: { code: 400, error: err, body: req.body },
20
+ i18n: req.i18n,
21
+ logger: req.logger
22
+ })
23
+ );
24
+ }
25
+ const { dappSignature, token, ip } = parsed;
26
+ try {
27
+ const { user, dapp, timestamp, commitmentId } = decodeProcaptchaOutput(token);
28
+ validateAddress(dapp, false, 42);
29
+ validateAddress(user, false, 42);
30
+ const clientRecord = await tasks.db.getClientRecord(dapp);
31
+ if (!clientRecord) {
32
+ return next(
33
+ new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
34
+ context: { code: 400, siteKey: dapp, user },
35
+ i18n: req.i18n,
36
+ logger: req.logger
37
+ })
38
+ );
14
39
  }
15
- catch (err) {
16
- return next(new ProsopoApiError("CAPTCHA.PARSE_ERROR", {
17
- context: { code: 400, error: err, body: req.body },
18
- i18n: req.i18n,
19
- logger: req.logger,
20
- }));
40
+ const keyPair = env.keyring.addFromAddress(dapp);
41
+ verifySignature(dappSignature, timestamp.toString(), keyPair);
42
+ const response = await tasks.imgCaptchaManager.verifyImageCaptchaSolution(
43
+ user,
44
+ dapp,
45
+ commitmentId,
46
+ parsed.maxVerifiedTime,
47
+ ip
48
+ );
49
+ req.logger.debug(() => ({ data: { response } }));
50
+ const verificationResponse = tasks.imgCaptchaManager.getVerificationResponse(
51
+ response[ApiParams.verified],
52
+ clientRecord,
53
+ req.i18n.t,
54
+ response[ApiParams.score],
55
+ response[ApiParams.commitmentId]
56
+ );
57
+ res.json(verificationResponse);
58
+ } catch (err) {
59
+ req.logger.error(() => ({ err, data: { body: req.body } }));
60
+ return next(
61
+ new ProsopoApiError("API.BAD_REQUEST", {
62
+ context: { code: 500, siteKey: req.body.dapp, user: req.body.user },
63
+ i18n: req.i18n,
64
+ logger: req.logger
65
+ })
66
+ );
67
+ }
68
+ }
69
+ );
70
+ router.post(
71
+ ClientApiPaths.VerifyPowCaptchaSolution,
72
+ async (req, res, next) => {
73
+ const tasks = new Tasks(env, req.logger);
74
+ let parsed;
75
+ try {
76
+ parsed = ServerPowCaptchaVerifyRequestBody.parse(req.body);
77
+ } catch (err) {
78
+ return next(
79
+ new ProsopoApiError("CAPTCHA.PARSE_ERROR", {
80
+ context: { code: 400, error: err, body: req.body },
81
+ i18n: req.i18n,
82
+ logger: req.logger
83
+ })
84
+ );
85
+ }
86
+ try {
87
+ const { token, dappSignature, verifiedTimeout, ip } = parsed;
88
+ const { dapp, user, timestamp, challenge } = decodeProcaptchaOutput(token);
89
+ validateAddress(dapp, false, 42);
90
+ validateAddress(user, false, 42);
91
+ const clientRecord = await tasks.db.getClientRecord(dapp);
92
+ if (!clientRecord) {
93
+ return next(
94
+ new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
95
+ context: { code: 400, siteKey: dapp },
96
+ i18n: req.i18n,
97
+ logger: req.logger
98
+ })
99
+ );
21
100
  }
22
- const { dappSignature, token, ip } = parsed;
23
- try {
24
- const { user, dapp, timestamp, commitmentId } = decodeProcaptchaOutput(token);
25
- validateAddress(dapp, false, 42);
26
- validateAddress(user, false, 42);
27
- const clientRecord = await tasks.db.getClientRecord(dapp);
28
- if (!clientRecord) {
29
- return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
30
- context: { code: 400, siteKey: dapp, user },
31
- i18n: req.i18n,
32
- logger: req.logger,
33
- }));
34
- }
35
- const keyPair = env.keyring.addFromAddress(dapp);
36
- verifySignature(dappSignature, timestamp.toString(), keyPair);
37
- const response = await tasks.imgCaptchaManager.verifyImageCaptchaSolution(user, dapp, commitmentId, parsed.maxVerifiedTime, ip);
38
- req.logger.debug(() => ({ data: { response } }));
39
- const verificationResponse = tasks.imgCaptchaManager.getVerificationResponse(response[ApiParams.verified], clientRecord, req.i18n.t, response[ApiParams.score], response[ApiParams.commitmentId]);
40
- res.json(verificationResponse);
101
+ if (!challenge) {
102
+ const unverifiedResponse = {
103
+ status: req.i18n.t("API.USER_NOT_VERIFIED"),
104
+ [ApiParams.verified]: false
105
+ };
106
+ return res.json(unverifiedResponse);
41
107
  }
42
- catch (err) {
43
- req.logger.error(() => ({ err, data: { body: req.body } }));
44
- return next(new ProsopoApiError("API.BAD_REQUEST", {
45
- context: { code: 500, siteKey: req.body.dapp, user: req.body.user },
46
- i18n: req.i18n,
47
- logger: req.logger,
48
- }));
49
- }
50
- });
51
- router.post(ClientApiPaths.VerifyPowCaptchaSolution, async (req, res, next) => {
52
- const tasks = new Tasks(env, req.logger);
53
- let parsed;
54
- try {
55
- parsed = ServerPowCaptchaVerifyRequestBody.parse(req.body);
56
- }
57
- catch (err) {
58
- return next(new ProsopoApiError("CAPTCHA.PARSE_ERROR", {
59
- context: { code: 400, error: err, body: req.body },
60
- i18n: req.i18n,
61
- logger: req.logger,
62
- }));
63
- }
64
- try {
65
- const { token, dappSignature, verifiedTimeout, ip } = parsed;
66
- const { dapp, user, timestamp, challenge } = decodeProcaptchaOutput(token);
67
- validateAddress(dapp, false, 42);
68
- validateAddress(user, false, 42);
69
- const clientRecord = await tasks.db.getClientRecord(dapp);
70
- if (!clientRecord) {
71
- return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
72
- context: { code: 400, siteKey: dapp },
73
- i18n: req.i18n,
74
- logger: req.logger,
75
- }));
76
- }
77
- if (!challenge) {
78
- const unverifiedResponse = {
79
- status: req.i18n.t("API.USER_NOT_VERIFIED"),
80
- [ApiParams.verified]: false,
81
- };
82
- return res.json(unverifiedResponse);
83
- }
84
- const dappPair = env.keyring.addFromAddress(dapp);
85
- verifySignature(dappSignature, timestamp.toString(), dappPair);
86
- const { verified, score } = await tasks.powCaptchaManager.serverVerifyPowCaptchaSolution(dapp, challenge, verifiedTimeout, ip);
87
- const verificationResponse = tasks.powCaptchaManager.getVerificationResponse(verified, clientRecord, req.i18n.t, score);
88
- return res.json(verificationResponse);
89
- }
90
- catch (err) {
91
- console.error("\nError in verifyPowCaptchaSolution:", err);
92
- req.logger.error(() => ({ err, data: { body: req.body } }));
93
- return next(new ProsopoApiError("API.BAD_REQUEST", {
94
- context: { code: 500, error: err },
95
- i18n: req.i18n,
96
- logger: req.logger,
97
- }));
98
- }
99
- });
100
- router.use(handleErrors);
101
- return router;
108
+ const dappPair = env.keyring.addFromAddress(dapp);
109
+ verifySignature(dappSignature, timestamp.toString(), dappPair);
110
+ const { verified, score } = await tasks.powCaptchaManager.serverVerifyPowCaptchaSolution(
111
+ dapp,
112
+ challenge,
113
+ verifiedTimeout,
114
+ ip
115
+ );
116
+ const verificationResponse = tasks.powCaptchaManager.getVerificationResponse(
117
+ verified,
118
+ clientRecord,
119
+ req.i18n.t,
120
+ score
121
+ );
122
+ return res.json(verificationResponse);
123
+ } catch (err) {
124
+ console.error("\nError in verifyPowCaptchaSolution:", err);
125
+ req.logger.error(() => ({ err, data: { body: req.body } }));
126
+ return next(
127
+ new ProsopoApiError("API.BAD_REQUEST", {
128
+ context: { code: 500, error: err },
129
+ i18n: req.i18n,
130
+ logger: req.logger
131
+ })
132
+ );
133
+ }
134
+ }
135
+ );
136
+ router.use(handleErrors);
137
+ return router;
102
138
  }
103
- //# sourceMappingURL=verify.js.map
139
+ export {
140
+ prosopoVerifyRouter
141
+ };
@@ -4,13 +4,12 @@ const types = require("@prosopo/types");
4
4
  const userAccessPolicy = require("@prosopo/user-access-policy");
5
5
  const util = require("@prosopo/util");
6
6
  const getRequestUserScope = (requestHeaders, ja4, ip, user) => {
7
- const ipAddress = util.getIPAddress(ip || "");
8
7
  const userAgent = requestHeaders["user-agent"] ? requestHeaders["user-agent"].toString() : void 0;
9
8
  return {
10
9
  ...user && { userId: user },
11
10
  ...ja4 && { ja4Hash: ja4 },
12
11
  ...userAgent && { userAgent },
13
- ...ipAddress && { ipAddress: ipAddress.bigInt() }
12
+ ...ip && { ip }
14
13
  };
15
14
  };
16
15
  const getPrioritisedAccessRule = async (userAccessRulesStorage, userScope, clientId) => {
@@ -25,7 +24,7 @@ const getPrioritisedAccessRule = async (userAccessRulesStorage, userScope, clien
25
24
  },
26
25
  {}
27
26
  )
28
- );
27
+ ).filter((us) => Object.keys(us).length > 0).filter((us) => Object.values(us).some((value) => value !== void 0));
29
28
  const policyPromises = [];
30
29
  for (const clientOrUndefined of [clientId, void 0]) {
31
30
  for (const scope of prioritisedUserScopes) {
@@ -34,9 +33,9 @@ const getPrioritisedAccessRule = async (userAccessRulesStorage, userScope, clien
34
33
  ...clientOrUndefined && {
35
34
  policyScope: {
36
35
  clientId: clientOrUndefined
37
- },
38
- policyScopeMatch: userAccessPolicy.ScopeMatch.Exact
36
+ }
39
37
  },
38
+ policyScopeMatch: userAccessPolicy.ScopeMatch.Exact,
40
39
  userScope: userAccessPolicy.userScopeInputSchema.parse(scope),
41
40
  userScopeMatch: userAccessPolicy.ScopeMatch.Exact
42
41
  })
@@ -52,7 +51,6 @@ class BlacklistRequestInspector {
52
51
  }
53
52
  async abortRequestForBlockedUsers(request, res, next) {
54
53
  const rawIp = request.ip || "";
55
- console.log(`Raw IP: ${rawIp}`);
56
54
  request.logger.debug(() => ({
57
55
  data: { ja4: request.ja4 }
58
56
  }));
@@ -54,10 +54,22 @@ function prosopoRouter(env) {
54
54
  })
55
55
  );
56
56
  }
57
+ const userScope = blacklistRequestInspector.getRequestUserScope(
58
+ util.flatten(req.headers),
59
+ req.ja4,
60
+ req.ip,
61
+ user
62
+ );
63
+ const userAccessPolicy = (await tasks$1.imgCaptchaManager.getPrioritisedAccessPolicies(
64
+ userAccessRulesStorage,
65
+ dapp,
66
+ userScope
67
+ ))[0];
57
68
  const { valid, reason, frictionlessTokenId } = await tasks$1.imgCaptchaManager.isValidRequest(
58
69
  clientRecord,
59
70
  types.CaptchaType.image,
60
- sessionId
71
+ sessionId,
72
+ userAccessPolicy
61
73
  );
62
74
  if (!valid) {
63
75
  return next(
@@ -72,17 +84,6 @@ function prosopoRouter(env) {
72
84
  })
73
85
  );
74
86
  }
75
- const userScope = blacklistRequestInspector.getRequestUserScope(
76
- util.flatten(req.headers),
77
- req.ja4,
78
- req.ip,
79
- user
80
- );
81
- const userAccessPolicy = (await tasks$1.imgCaptchaManager.getPrioritisedAccessPolicies(
82
- userAccessRulesStorage,
83
- dapp,
84
- userScope
85
- ))[0];
86
87
  const captchaConfig = {
87
88
  solved: {
88
89
  count: userAccessPolicy?.solvedImagesCount || env.config.captchas.solved.count
@@ -236,10 +237,22 @@ function prosopoRouter(env) {
236
237
  })
237
238
  );
238
239
  }
240
+ const userScope = blacklistRequestInspector.getRequestUserScope(
241
+ util.flatten(req.headers),
242
+ req.ja4,
243
+ req.ip,
244
+ user
245
+ );
246
+ const userAccessPolicy = (await tasks$1.powCaptchaManager.getPrioritisedAccessPolicies(
247
+ userAccessRulesStorage,
248
+ dapp,
249
+ userScope
250
+ ))[0];
239
251
  const { valid, reason, frictionlessTokenId } = await tasks$1.powCaptchaManager.isValidRequest(
240
252
  clientSettings,
241
253
  types.CaptchaType.pow,
242
- sessionId
254
+ sessionId,
255
+ userAccessPolicy
243
256
  );
244
257
  if (!valid) {
245
258
  return next(
@@ -269,17 +282,6 @@ function prosopoRouter(env) {
269
282
  })
270
283
  );
271
284
  }
272
- const userScope = blacklistRequestInspector.getRequestUserScope(
273
- util.flatten(req.headers),
274
- req.ja4,
275
- req.ip,
276
- user
277
- );
278
- const userAccessPolicy = (await tasks$1.powCaptchaManager.getPrioritisedAccessPolicies(
279
- userAccessRulesStorage,
280
- dapp,
281
- userScope
282
- ))[0];
283
285
  const challenge = await tasks$1.powCaptchaManager.getPowCaptchaChallenge(
284
286
  user,
285
287
  dapp,
@@ -462,17 +464,6 @@ function prosopoRouter(env) {
462
464
  ...lScore && { lScore }
463
465
  }
464
466
  });
465
- if (frictionlessTasks.FrictionlessManager.timestampTooOld(timestamp)) {
466
- await tasks$1.frictionlessManager.scoreIncreaseTimestamp(
467
- timestamp,
468
- baseBotScore,
469
- botScore,
470
- tokenId
471
- );
472
- return res.json(
473
- await tasks$1.frictionlessManager.sendImageCaptcha(tokenId)
474
- );
475
- }
476
467
  const userScope = blacklistRequestInspector.getRequestUserScope(
477
468
  util.flatten(req.headers),
478
469
  req.ja4,
@@ -484,13 +475,31 @@ function prosopoRouter(env) {
484
475
  dapp,
485
476
  userScope
486
477
  ))[0];
487
- if (userAccessPolicy?.captchaType === types.CaptchaType.image) {
478
+ if (userAccessPolicy) {
488
479
  await tasks$1.frictionlessManager.scoreIncreaseAccessPolicy(
489
480
  userAccessPolicy,
490
481
  baseBotScore,
491
482
  botScore,
492
483
  tokenId
493
484
  );
485
+ if (userAccessPolicy.captchaType === types.CaptchaType.image) {
486
+ return res.json(
487
+ await tasks$1.frictionlessManager.sendImageCaptcha(tokenId)
488
+ );
489
+ }
490
+ if (userAccessPolicy.captchaType === types.CaptchaType.pow) {
491
+ return res.json(
492
+ await tasks$1.frictionlessManager.sendPowCaptcha(tokenId)
493
+ );
494
+ }
495
+ }
496
+ if (frictionlessTasks.FrictionlessManager.timestampTooOld(timestamp)) {
497
+ await tasks$1.frictionlessManager.scoreIncreaseTimestamp(
498
+ timestamp,
499
+ baseBotScore,
500
+ botScore,
501
+ tokenId
502
+ );
494
503
  return res.json(
495
504
  await tasks$1.frictionlessManager.sendImageCaptcha(tokenId)
496
505
  );
@@ -4,12 +4,15 @@ const node_crypto = require("node:crypto");
4
4
  const node_stream = require("node:stream");
5
5
  const apiExpressRouter = require("@prosopo/api-express-router");
6
6
  const common = require("@prosopo/common");
7
+ const utilCrypto = require("@prosopo/util-crypto");
7
8
  const readTlsClientHello = require("read-tls-client-hello");
8
9
  const DEFAULT_JA4 = "ja4";
9
10
  const getJA4 = async (headers, logger) => {
10
11
  logger = logger || common.getLogger("info", module);
11
12
  if (process.env.NODE_ENV === "development") {
12
- return { ja4PlusFingerprint: DEFAULT_JA4 };
13
+ return {
14
+ ja4PlusFingerprint: `${DEFAULT_JA4}${utilCrypto.randomAsHex().slice(28, 32)}`
15
+ };
13
16
  }
14
17
  try {
15
18
  const xTlsClientHello = (headers["x-tls-clienthello"] || "").toString();
@@ -15,14 +15,28 @@ class CaptchaManager {
15
15
  );
16
16
  return tokenRecord ? tokenRecord._id : void 0;
17
17
  }
18
- async isValidRequest(clientSettings, captchaType, sessionId) {
18
+ async isValidRequest(clientSettings, requestedCaptchaType, sessionId, userAccessPolicy) {
19
19
  this.logger.debug(() => ({
20
20
  msg: "Validating request",
21
21
  data: {
22
- captchaType,
22
+ captchaType: requestedCaptchaType,
23
23
  sessionId
24
24
  }
25
25
  }));
26
+ if (userAccessPolicy && userAccessPolicy.captchaType !== requestedCaptchaType) {
27
+ this.logger.warn(() => ({
28
+ msg: "Invalid captcha type for user access policy",
29
+ data: {
30
+ account: clientSettings.account,
31
+ captchaType: userAccessPolicy.captchaType
32
+ }
33
+ }));
34
+ return {
35
+ valid: false,
36
+ reason: "API.INCORRECT_CAPTCHA_TYPE",
37
+ type: requestedCaptchaType
38
+ };
39
+ }
26
40
  if (sessionId) {
27
41
  if (clientSettings?.settings?.captchaType === types.CaptchaType.frictionless) {
28
42
  const sessionRecord = await this.db.checkAndRemoveSession(sessionId);
@@ -37,14 +51,14 @@ class CaptchaManager {
37
51
  return {
38
52
  valid: false,
39
53
  reason: "CAPTCHA.NO_SESSION_FOUND",
40
- type: captchaType
54
+ type: requestedCaptchaType
41
55
  };
42
56
  }
43
57
  const frictionlessTokenId = await this.getFrictionlessTokenIdFromSession(sessionRecord);
44
58
  return {
45
59
  valid: true,
46
60
  frictionlessTokenId,
47
- type: captchaType
61
+ type: requestedCaptchaType
48
62
  };
49
63
  }
50
64
  this.logger.warn(() => ({
@@ -58,25 +72,25 @@ class CaptchaManager {
58
72
  return {
59
73
  valid: false,
60
74
  reason: "API.INCORRECT_CAPTCHA_TYPE",
61
- type: captchaType
75
+ type: requestedCaptchaType
62
76
  };
63
77
  }
64
- if (clientSettings?.settings?.captchaType !== captchaType) {
78
+ if (clientSettings?.settings?.captchaType !== requestedCaptchaType) {
65
79
  this.logger.warn(() => ({
66
- msg: `Invalid ${captchaType} request`,
80
+ msg: `Invalid ${requestedCaptchaType} request`,
67
81
  data: {
68
82
  account: clientSettings.account,
69
- requestedCaptchaType: captchaType,
83
+ requestedCaptchaType,
70
84
  settingsCaptchaType: clientSettings?.settings?.captchaType
71
85
  }
72
86
  }));
73
87
  return {
74
88
  valid: false,
75
89
  reason: "API.INCORRECT_CAPTCHA_TYPE",
76
- type: captchaType
90
+ type: requestedCaptchaType
77
91
  };
78
92
  }
79
- return { valid: true, type: captchaType };
93
+ return { valid: true, type: requestedCaptchaType };
80
94
  }
81
95
  getVerificationResponse(verified, clientRecord, translateFn, score) {
82
96
  return {
@@ -43,9 +43,6 @@ class FrictionlessManager extends captchaManager.CaptchaManager {
43
43
  async scoreIncreaseAccessPolicy(accessPolicy, baseBotScore, botScore, tokenId) {
44
44
  const accessPolicyPenalty = accessPolicy?.frictionlessScore || this.config.penalties.PENALTY_ACCESS_RULE;
45
45
  botScore += accessPolicyPenalty;
46
- this.logger.info(() => ({
47
- msg: "Address has an image captcha config defined"
48
- }));
49
46
  await this.db.updateFrictionlessTokenRecord(tokenId, {
50
47
  score: botScore,
51
48
  scoreComponents: {
@@ -12,7 +12,7 @@ const checkPowSignature = (message, signature, address, signatureType) => {
12
12
  address
13
13
  );
14
14
  if (!signatureVerification.isValid) {
15
- throw new common.ProsopoContractError("GENERAL.INVALID_SIGNATURE", {
15
+ throw new common.ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
16
16
  context: {
17
17
  ERROR: `Signature is invalid for this message: ${signatureType}`,
18
18
  failedFuncName: checkPowSignature.name,
package/dist/index.js CHANGED
@@ -1,15 +1,38 @@
1
- export * from "./tasks/index.js";
2
- export * from "./util.js";
3
- export * from "./api/block.js";
4
- export * from "./api/captcha.js";
5
- export * from "./api/verify.js";
6
- export * from "./api/ja4Middleware.js";
7
- export * from "./api/public.js";
8
- export * from "./api/domainMiddleware.js";
9
- export * from "./schedulers/captchaScheduler.js";
10
- export * from "./schedulers/getClientList.js";
11
- export * from "./api/headerCheckMiddleware.js";
12
- export * from "./api/admin/createApiAdminRoutesProvider.js";
13
- export * from "./api/ignoreMiddleware.js";
14
- export * from "./api/robotsMiddleware.js";
15
- //# sourceMappingURL=index.js.map
1
+ import "./tasks/index.js";
2
+ import { checkIfTaskIsRunning, encodeStringAddress, getIPAddress, getIPAddressFromBigInt, shuffleArray, validateIpAddress } from "./util.js";
3
+ import { blockMiddleware } from "./api/block.js";
4
+ import { prosopoRouter } from "./api/captcha.js";
5
+ import { prosopoVerifyRouter } from "./api/verify.js";
6
+ import { DEFAULT_JA4, getJA4, ja4Middleware } from "./api/ja4Middleware.js";
7
+ import { publicRouter } from "./api/public.js";
8
+ import { domainMiddleware } from "./api/domainMiddleware.js";
9
+ import { storeCaptchasExternally } from "./schedulers/captchaScheduler.js";
10
+ import { getClientList } from "./schedulers/getClientList.js";
11
+ import { headerCheckMiddleware } from "./api/headerCheckMiddleware.js";
12
+ import { createApiAdminRoutesProvider } from "./api/admin/createApiAdminRoutesProvider.js";
13
+ import { ignoreMiddleware } from "./api/ignoreMiddleware.js";
14
+ import { robotsMiddleware } from "./api/robotsMiddleware.js";
15
+ import { Tasks } from "./tasks/tasks.js";
16
+ export {
17
+ DEFAULT_JA4,
18
+ Tasks,
19
+ blockMiddleware,
20
+ checkIfTaskIsRunning,
21
+ createApiAdminRoutesProvider,
22
+ domainMiddleware,
23
+ encodeStringAddress,
24
+ getClientList,
25
+ getIPAddress,
26
+ getIPAddressFromBigInt,
27
+ getJA4,
28
+ headerCheckMiddleware,
29
+ ignoreMiddleware,
30
+ ja4Middleware,
31
+ prosopoRouter,
32
+ prosopoVerifyRouter,
33
+ publicRouter,
34
+ robotsMiddleware,
35
+ shuffleArray,
36
+ storeCaptchasExternally,
37
+ validateIpAddress
38
+ };
@@ -1,16 +1,16 @@
1
- export const checkLangRules = (config, acceptLanguage) => {
2
- const lConfig = config.lRules;
3
- let lScore = 0;
4
- if (lConfig) {
5
- const languages = acceptLanguage
6
- .split(",")
7
- .map((lang) => lang.trim().split(";")[0]);
8
- for (const lang of languages) {
9
- if (lang && lConfig[lang]) {
10
- lScore += lConfig[lang];
11
- }
12
- }
1
+ const checkLangRules = (config, acceptLanguage) => {
2
+ const lConfig = config.lRules;
3
+ let lScore = 0;
4
+ if (lConfig) {
5
+ const languages = acceptLanguage.split(",").map((lang) => lang.trim().split(";")[0]);
6
+ for (const lang of languages) {
7
+ if (lang && lConfig[lang]) {
8
+ lScore += lConfig[lang];
9
+ }
13
10
  }
14
- return lScore;
11
+ }
12
+ return lScore;
13
+ };
14
+ export {
15
+ checkLangRules
15
16
  };
16
- //# sourceMappingURL=lang.js.map