@prosopo/provider 4.15.13 → 4.15.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +106 -106
  2. package/.turbo/turbo-build$colon$tsc.log +24 -24
  3. package/.turbo/turbo-build.log +107 -104
  4. package/CHANGELOG.md +78 -0
  5. package/dist/_virtual/_rolldown/runtime.js +3 -0
  6. package/dist/api/admin/apiAdminRoutesProvider.js +27 -46
  7. package/dist/api/admin/apiClearAllCountersEndpoint.js +62 -57
  8. package/dist/api/admin/apiDnsEventEndpoint.js +79 -92
  9. package/dist/api/admin/apiGetAllDecisionMachinesEndpoint.js +43 -45
  10. package/dist/api/admin/apiGetDecisionMachineEndpoint.js +40 -40
  11. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +23 -22
  12. package/dist/api/admin/apiRegisterSiteKeysEndpoint.js +26 -30
  13. package/dist/api/admin/apiRemoveAllDecisionMachinesEndpoint.js +35 -37
  14. package/dist/api/admin/apiRemoveDecisionMachineEndpoint.js +40 -40
  15. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +1 -1
  16. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js +29 -31
  17. package/dist/api/admin/apiRemoveSiteKeyEndpoint.js +33 -29
  18. package/dist/api/admin/apiRemoveSiteKeysEndpoint.js +32 -31
  19. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +43 -35
  20. package/dist/api/admin/apiUpdateDecisionMachineEndpoint.js +43 -63
  21. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js +36 -35
  22. package/dist/api/admin/createApiAdminRoutesProvider.js +6 -8
  23. package/dist/api/blacklistRequestInspector.js +285 -377
  24. package/dist/api/block.js +17 -30
  25. package/dist/api/captcha/checkSpamEmail.js +88 -98
  26. package/dist/api/captcha/contextAwareValidation.js +21 -15
  27. package/dist/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.js +126 -140
  28. package/dist/api/captcha/getFrictionlessCaptchaChallenge/constants.js +11 -12
  29. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.js +236 -299
  30. package/dist/api/captcha/getFrictionlessCaptchaChallenge/decryptSimdReadings.js +10 -13
  31. package/dist/api/captcha/getFrictionlessCaptchaChallenge/handler.js +336 -462
  32. package/dist/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.js +17 -14
  33. package/dist/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.js +27 -27
  34. package/dist/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.js +42 -63
  35. package/dist/api/captcha/getFrictionlessCaptchaChallenge.js +2 -4
  36. package/dist/api/captcha/getImageCaptchaChallenge.js +136 -207
  37. package/dist/api/captcha/getPoWCaptchaChallenge.js +128 -198
  38. package/dist/api/captcha/getPuzzleCaptchaChallenge.js +132 -201
  39. package/dist/api/captcha/maintenanceModeResponses.js +38 -47
  40. package/dist/api/captcha/submitImageCaptchaSolution.js +75 -101
  41. package/dist/api/captcha/submitPoWCaptchaSolution.js +137 -207
  42. package/dist/api/captcha/submitPuzzleCaptchaSolution.js +73 -105
  43. package/dist/api/captcha.js +76 -58
  44. package/dist/api/dnsEventUrl.js +20 -22
  45. package/dist/api/domainMiddleware.js +104 -115
  46. package/dist/api/forwardVerify.js +62 -48
  47. package/dist/api/handshakeTimingMiddleware.js +43 -62
  48. package/dist/api/hardBlockVerdictCache.js +114 -117
  49. package/dist/api/headerCheckMiddleware.js +34 -34
  50. package/dist/api/ignoreMiddleware.js +13 -15
  51. package/dist/api/ipInfoMiddleware.js +17 -19
  52. package/dist/api/ja4.js +149 -188
  53. package/dist/api/ja4Middleware.js +39 -54
  54. package/dist/api/metrics.js +245 -257
  55. package/dist/api/public.js +52 -54
  56. package/dist/api/robotsMiddleware.js +10 -10
  57. package/dist/api/startProviderApi.js +205 -232
  58. package/dist/api/testSiteKey.js +16 -16
  59. package/dist/api/validateAddress.js +23 -21
  60. package/dist/api/verify.js +334 -377
  61. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  62. package/dist/cjs/api/admin/apiAdminRoutesProvider.cjs +40 -59
  63. package/dist/cjs/api/admin/apiClearAllCountersEndpoint.cjs +63 -58
  64. package/dist/cjs/api/admin/apiDnsEventEndpoint.cjs +82 -93
  65. package/dist/cjs/api/admin/apiGetAllDecisionMachinesEndpoint.cjs +46 -48
  66. package/dist/cjs/api/admin/apiGetDecisionMachineEndpoint.cjs +41 -41
  67. package/dist/cjs/api/admin/apiRegisterSiteKeyEndpoint.cjs +25 -24
  68. package/dist/cjs/api/admin/apiRegisterSiteKeysEndpoint.cjs +28 -32
  69. package/dist/cjs/api/admin/apiRemoveAllDecisionMachinesEndpoint.cjs +38 -40
  70. package/dist/cjs/api/admin/apiRemoveDecisionMachineEndpoint.cjs +41 -41
  71. package/dist/cjs/api/admin/apiRemoveDetectorKeyEndpoint.cjs +31 -33
  72. package/dist/cjs/api/admin/apiRemoveSiteKeyEndpoint.cjs +35 -31
  73. package/dist/cjs/api/admin/apiRemoveSiteKeysEndpoint.cjs +34 -33
  74. package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +45 -35
  75. package/dist/cjs/api/admin/apiUpdateDecisionMachineEndpoint.cjs +45 -65
  76. package/dist/cjs/api/admin/apiUpdateDetectorKeyEndpoint.cjs +38 -37
  77. package/dist/cjs/api/admin/createApiAdminRoutesProvider.cjs +7 -8
  78. package/dist/cjs/api/blacklistRequestInspector.cjs +288 -376
  79. package/dist/cjs/api/block.cjs +18 -30
  80. package/dist/cjs/api/captcha/checkSpamEmail.cjs +90 -100
  81. package/dist/cjs/api/captcha/contextAwareValidation.cjs +21 -14
  82. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/accessPolicy.cjs +125 -140
  83. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/constants.cjs +10 -10
  84. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decisionMachine.cjs +238 -301
  85. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/decryptSimdReadings.cjs +9 -12
  86. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/handler.cjs +349 -473
  87. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.cjs +18 -14
  88. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.cjs +26 -26
  89. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.cjs +42 -63
  90. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge.cjs +2 -3
  91. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +138 -208
  92. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +131 -200
  93. package/dist/cjs/api/captcha/getPuzzleCaptchaChallenge.cjs +135 -203
  94. package/dist/cjs/api/captcha/maintenanceModeResponses.cjs +38 -44
  95. package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +77 -102
  96. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +140 -209
  97. package/dist/cjs/api/captcha/submitPuzzleCaptchaSolution.cjs +76 -107
  98. package/dist/cjs/api/captcha.cjs +79 -58
  99. package/dist/cjs/api/dnsEventUrl.cjs +20 -21
  100. package/dist/cjs/api/domainMiddleware.cjs +106 -117
  101. package/dist/cjs/api/forwardVerify.cjs +63 -49
  102. package/dist/cjs/api/handshakeTimingMiddleware.cjs +43 -61
  103. package/dist/cjs/api/hardBlockVerdictCache.cjs +114 -114
  104. package/dist/cjs/api/headerCheckMiddleware.cjs +34 -34
  105. package/dist/cjs/api/ignoreMiddleware.cjs +12 -14
  106. package/dist/cjs/api/ipInfoMiddleware.cjs +16 -18
  107. package/dist/cjs/api/ja4.cjs +149 -187
  108. package/dist/cjs/api/ja4Middleware.cjs +40 -53
  109. package/dist/cjs/api/metrics.cjs +229 -228
  110. package/dist/cjs/api/public.cjs +57 -57
  111. package/dist/cjs/api/robotsMiddleware.cjs +9 -9
  112. package/dist/cjs/api/startProviderApi.cjs +219 -237
  113. package/dist/cjs/api/testSiteKey.cjs +15 -14
  114. package/dist/cjs/api/validateAddress.cjs +24 -21
  115. package/dist/cjs/api/verify.cjs +338 -379
  116. package/dist/cjs/compositeIpAddress.cjs +40 -47
  117. package/dist/cjs/index.cjs +65 -71
  118. package/dist/cjs/pairs.cjs +31 -35
  119. package/dist/cjs/rules/lang.cjs +10 -14
  120. package/dist/cjs/schedulers/captchaScheduler.cjs +26 -32
  121. package/dist/cjs/schedulers/getClientList.cjs +35 -33
  122. package/dist/cjs/schedulers/setClientEntropy.cjs +35 -33
  123. package/dist/cjs/schedulers/updateSpamEmailDomains.cjs +39 -43
  124. package/dist/cjs/services/ipComparison.cjs +122 -119
  125. package/dist/cjs/tasks/captchaManager.cjs +407 -486
  126. package/dist/cjs/tasks/client/clientTasks.cjs +347 -470
  127. package/dist/cjs/tasks/dataset/datasetTasks.cjs +25 -29
  128. package/dist/cjs/tasks/dataset/datasetTasksUtils.cjs +16 -32
  129. package/dist/cjs/tasks/decisionMachine/decisionMachineRunner.cjs +220 -307
  130. package/dist/cjs/tasks/detection/decodeBehavior.cjs +408 -317
  131. package/dist/cjs/tasks/detection/decodePayload.cjs +686 -468
  132. package/dist/cjs/tasks/detection/decodeSimd.cjs +462 -304
  133. package/dist/cjs/tasks/detection/getBotScore.cjs +37 -43
  134. package/dist/cjs/tasks/dnsEvent/enrichDnsEvent.cjs +88 -71
  135. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +348 -486
  136. package/dist/cjs/tasks/frictionless/frictionlessTasksUtils.cjs +13 -30
  137. package/dist/cjs/tasks/frictionless/routingMachine.cjs +71 -55
  138. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +555 -806
  139. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs +22 -23
  140. package/dist/cjs/tasks/index.cjs +2 -4
  141. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +491 -687
  142. package/dist/cjs/tasks/powCaptcha/powTasksUtils.cjs +17 -29
  143. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasks.cjs +422 -591
  144. package/dist/cjs/tasks/puzzleCaptcha/puzzleTasksUtils.cjs +8 -5
  145. package/dist/cjs/tasks/spam/checkSpamEmail.cjs +133 -141
  146. package/dist/cjs/tasks/spam/checkTrafficFilter.cjs +118 -76
  147. package/dist/cjs/tasks/spam/evaluateEmailSpamRules.cjs +75 -84
  148. package/dist/cjs/tasks/spam/updateSpamEmailDomains.cjs +40 -56
  149. package/dist/cjs/tasks/tasks.cjs +107 -158
  150. package/dist/cjs/util/usageCounters.cjs +220 -211
  151. package/dist/cjs/util.cjs +329 -359
  152. package/dist/cjs/utils/devicePlatform.cjs +14 -8
  153. package/dist/cjs/utils/dns.cjs +68 -93
  154. package/dist/cjs/utils/hashUserAgent.cjs +14 -7
  155. package/dist/cjs/utils/hashUserIp.cjs +14 -6
  156. package/dist/cjs/utils/honeypot/encoders.cjs +74 -80
  157. package/dist/cjs/utils/honeypot/phraseBank.cjs +51 -44
  158. package/dist/cjs/utils/normalizeRequestIp.cjs +33 -25
  159. package/dist/compositeIpAddress.js +38 -46
  160. package/dist/index.js +12 -56
  161. package/dist/pairs.js +31 -37
  162. package/dist/rules/lang.js +11 -15
  163. package/dist/schedulers/captchaScheduler.js +25 -31
  164. package/dist/schedulers/getClientList.js +34 -32
  165. package/dist/schedulers/setClientEntropy.js +34 -32
  166. package/dist/schedulers/updateSpamEmailDomains.js +38 -42
  167. package/dist/services/ipComparison.js +122 -119
  168. package/dist/tasks/captchaManager.js +403 -483
  169. package/dist/tasks/client/clientTasks.js +343 -467
  170. package/dist/tasks/dataset/datasetTasks.js +24 -28
  171. package/dist/tasks/dataset/datasetTasksUtils.js +15 -31
  172. package/dist/tasks/decisionMachine/decisionMachineRunner.js +217 -306
  173. package/dist/tasks/detection/getBotScore.js +37 -43
  174. package/dist/tasks/dnsEvent/enrichDnsEvent.d.ts.map +1 -1
  175. package/dist/tasks/dnsEvent/enrichDnsEvent.js +88 -74
  176. package/dist/tasks/dnsEvent/enrichDnsEvent.js.map +1 -1
  177. package/dist/tasks/frictionless/frictionlessTasks.js +342 -479
  178. package/dist/tasks/frictionless/frictionlessTasksUtils.js +14 -32
  179. package/dist/tasks/frictionless/routingMachine.js +72 -56
  180. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +550 -801
  181. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +21 -22
  182. package/dist/tasks/index.js +1 -3
  183. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  184. package/dist/tasks/powCaptcha/powTasks.js +486 -682
  185. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  186. package/dist/tasks/powCaptcha/powTasksUtils.js +15 -28
  187. package/dist/tasks/puzzleCaptcha/puzzleTasks.d.ts.map +1 -1
  188. package/dist/tasks/puzzleCaptcha/puzzleTasks.js +417 -586
  189. package/dist/tasks/puzzleCaptcha/puzzleTasks.js.map +1 -1
  190. package/dist/tasks/puzzleCaptcha/puzzleTasksUtils.js +9 -6
  191. package/dist/tasks/spam/checkSpamEmail.js +133 -141
  192. package/dist/tasks/spam/checkTrafficFilter.d.ts +1 -0
  193. package/dist/tasks/spam/checkTrafficFilter.d.ts.map +1 -1
  194. package/dist/tasks/spam/checkTrafficFilter.js +117 -77
  195. package/dist/tasks/spam/checkTrafficFilter.js.map +1 -1
  196. package/dist/tasks/spam/evaluateEmailSpamRules.js +75 -86
  197. package/dist/tasks/spam/updateSpamEmailDomains.js +36 -54
  198. package/dist/tasks/tasks.js +98 -150
  199. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +4 -1
  200. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +1 -1
  201. package/dist/tests/unit/api/block.unit.test.js +8 -4
  202. package/dist/tests/unit/api/block.unit.test.js.map +1 -1
  203. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js +8 -6
  204. package/dist/tests/unit/api/captcha/maintenanceModeShortCircuit.unit.test.js.map +1 -1
  205. package/dist/tests/unit/api/forwardVerify.unit.test.js +3 -1
  206. package/dist/tests/unit/api/forwardVerify.unit.test.js.map +1 -1
  207. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js +15 -7
  208. package/dist/tests/unit/api/getFrictionlessCaptchaChallenge.unit.test.js.map +1 -1
  209. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +24 -18
  210. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +1 -1
  211. package/dist/tests/unit/schedulers/getClientList.unit.test.js +19 -13
  212. package/dist/tests/unit/schedulers/getClientList.unit.test.js.map +1 -1
  213. package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js +19 -13
  214. package/dist/tests/unit/schedulers/setClientEntropy.unit.test.js.map +1 -1
  215. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -1
  216. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +22 -16
  217. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
  218. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +6 -0
  219. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
  220. package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js +60 -1
  221. package/dist/tests/unit/tasks/puzzleCaptcha/puzzleTasks.unit.test.js.map +1 -1
  222. package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js +140 -0
  223. package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js.map +1 -1
  224. package/dist/tests/unit/testUtils/mockProviderEnv.d.ts +7 -7
  225. package/dist/util/usageCounters.js +220 -212
  226. package/dist/util.d.ts.map +1 -1
  227. package/dist/util.js +327 -364
  228. package/dist/util.js.map +1 -1
  229. package/dist/utils/devicePlatform.js +15 -9
  230. package/dist/utils/dns.js +64 -77
  231. package/dist/utils/hashUserAgent.js +14 -7
  232. package/dist/utils/hashUserIp.js +14 -6
  233. package/dist/utils/honeypot/encoders.js +74 -80
  234. package/dist/utils/honeypot/phraseBank.js +49 -44
  235. package/dist/utils/normalizeRequestIp.js +34 -26
  236. package/package.json +24 -24
@@ -1,245 +1,218 @@
1
- import fs from "node:fs";
2
- import https__default from "node:https";
3
- import path from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import { createApiExpressDefaultEndpointAdapter, requestLoggerMiddleware, authMiddleware, apiExpressRouterFactory } from "@prosopo/api-express-router";
6
- import { i18nMiddleware } from "@prosopo/locale";
7
- import { parseLogLevel } from "@prosopo/logger";
8
- import { ClientApiPaths, AdminApiPaths } from "@prosopo/types";
9
- import { AccessRuleApiRoutes, getExpressApiRuleRateLimits } from "@prosopo/user-access-policy/api";
10
- import cors from "cors";
11
- import express from "express";
12
- import rateLimit from "express-rate-limit";
13
- import { createApiAdminRoutesProvider } from "./admin/createApiAdminRoutesProvider.js";
1
+ import { metricsMiddleware } from "./metrics.js";
14
2
  import { getVerdictCache } from "./blacklistRequestInspector.js";
15
3
  import { blockMiddleware } from "./block.js";
16
4
  import { prosopoRouter } from "./captcha.js";
17
- import { domainMiddleware } from "./domainMiddleware.js";
5
+ import { prosopoVerifyRouter } from "./verify.js";
6
+ import { ja4Middleware } from "./ja4Middleware.js";
18
7
  import { handshakeTimingMiddleware } from "./handshakeTimingMiddleware.js";
8
+ import { publicRouter } from "./public.js";
9
+ import { domainMiddleware } from "./domainMiddleware.js";
10
+ import { createApiAdminRoutesProvider } from "./admin/createApiAdminRoutesProvider.js";
19
11
  import { headerCheckMiddleware } from "./headerCheckMiddleware.js";
20
12
  import { ignoreMiddleware } from "./ignoreMiddleware.js";
21
13
  import { ipInfoMiddleware } from "./ipInfoMiddleware.js";
22
- import { ja4Middleware } from "./ja4Middleware.js";
23
- import { metricsMiddleware } from "./metrics.js";
24
- import { publicRouter } from "./public.js";
25
14
  import { robotsMiddleware } from "./robotsMiddleware.js";
26
- import { prosopoVerifyRouter } from "./verify.js";
27
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
- const certPath = path.resolve(__dirname, "../../../../certs");
29
- const keyPath = path.join(certPath, "server.key");
30
- const crtPath = path.join(certPath, "server.crt");
31
- const isTlsAvailable = () => {
32
- return fs.existsSync(keyPath) && fs.existsSync(crtPath);
15
+ import { parseLogLevel } from "@prosopo/logger";
16
+ import { AdminApiPaths, ClientApiPaths } from "@prosopo/types";
17
+ import https from "node:https";
18
+ import fs from "node:fs";
19
+ import { apiExpressRouterFactory, authMiddleware, createApiExpressDefaultEndpointAdapter, requestLoggerMiddleware } from "@prosopo/api-express-router";
20
+ import express from "express";
21
+ import path from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+ import { i18nMiddleware } from "@prosopo/locale";
24
+ import { AccessRuleApiRoutes, getExpressApiRuleRateLimits } from "@prosopo/user-access-policy/api";
25
+ import cors from "cors";
26
+ import rateLimit from "express-rate-limit";
27
+ //#region src/api/startProviderApi.ts
28
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
29
+ var certPath = path.resolve(__dirname, "../../../../certs");
30
+ var keyPath = path.join(certPath, "server.key");
31
+ var crtPath = path.join(certPath, "server.crt");
32
+ /**
33
+ * Check if TLS certificates are available
34
+ * @returns True if both key and cert files exist
35
+ */
36
+ var isTlsAvailable = () => {
37
+ return fs.existsSync(keyPath) && fs.existsSync(crtPath);
33
38
  };
34
- const getClientApiPathsExpectingProsopoHeaders = () => {
35
- const paths = Object.values(ClientApiPaths).filter(
36
- (path2) => path2.indexOf("verify") === -1 && path2.indexOf("spam") === -1
37
- );
38
- return paths;
39
+ /**
40
+ * Get client API paths that expect Prosopo headers (like site key) for validation, excluding verify and spam routes
41
+ * @returns Array of ClientApiPaths excluding verify and spam routes
42
+ */
43
+ var getClientApiPathsExpectingProsopoHeaders = () => {
44
+ return Object.values(ClientApiPaths).filter((path) => path.indexOf("verify") === -1 && path.indexOf("spam") === -1);
39
45
  };
40
- const getUserFromJWT = (req) => {
41
- try {
42
- const authHeader = req.headers.Authorization || req.headers.authorization;
43
- if (!authHeader || typeof authHeader !== "string") {
44
- return void 0;
45
- }
46
- const jwt = authHeader.replace("Bearer ", "");
47
- if (!jwt) {
48
- return void 0;
49
- }
50
- const parts = jwt.split(".");
51
- if (parts.length !== 3 || !parts[1]) {
52
- return void 0;
53
- }
54
- const payload = JSON.parse(
55
- Buffer.from(parts[1], "base64url").toString("utf-8")
56
- );
57
- return payload.sub;
58
- } catch (e) {
59
- return void 0;
60
- }
46
+ /**
47
+ * Extract authenticated user address from JWT for rate limiting
48
+ * @param req Express request object
49
+ * @returns User address from JWT or undefined
50
+ */
51
+ var getUserFromJWT = (req) => {
52
+ try {
53
+ const authHeader = req.headers.Authorization || req.headers.authorization;
54
+ if (!authHeader || typeof authHeader !== "string") return;
55
+ const jwt = authHeader.replace("Bearer ", "");
56
+ if (!jwt) return;
57
+ const parts = jwt.split(".");
58
+ if (parts.length !== 3 || !parts[1]) return;
59
+ return JSON.parse(Buffer.from(parts[1], "base64url").toString("utf-8")).sub;
60
+ } catch (e) {
61
+ return;
62
+ }
61
63
  };
64
+ /**
65
+ * Start the Prosopo Provider API server
66
+ *
67
+ * This function creates and configures an Express server with all necessary middleware
68
+ * for the Prosopo Provider API, including:
69
+ * - CORS support
70
+ * - Rate limiting (disabled in test/development environments)
71
+ * - Authentication and authorization
72
+ * - Request validation (headers, domains, etc.)
73
+ * - Blocking and security middleware
74
+ * - Admin and client API routes
75
+ * - Access rule management
76
+ *
77
+ * @param env - The ProviderEnvironment containing configuration and database connections
78
+ * @param admin - Whether to enable admin mode (currently unused, kept for compatibility)
79
+ * @param port - Optional port override. If not provided, uses env.config.server.port
80
+ * @returns Promise<Server> - The Node.js HTTP server instance
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const env = new ProviderEnvironment(config);
85
+ * await env.isReady();
86
+ * const server = await startProviderApi(env);
87
+ * ```
88
+ */
62
89
  async function startProviderApi(env, admin = false, port) {
63
- env.logger.info(() => ({ msg: "Starting Prosopo API" }));
64
- const apiApp = express();
65
- const apiPort = port || env.config.server?.port;
66
- const apiEndpointAdapter = createApiExpressDefaultEndpointAdapter(
67
- parseLogLevel(env.config.logLevel)
68
- );
69
- let apiRuleRoutesProvider;
70
- let apiAdminRoutesProvider;
71
- try {
72
- apiRuleRoutesProvider = new AccessRuleApiRoutes(
73
- env.getDb().getUserAccessRulesStorage(),
74
- env.logger
75
- );
76
- apiAdminRoutesProvider = createApiAdminRoutesProvider(env);
77
- } catch (err) {
78
- env.logger.warn(() => ({
79
- msg: "Skipping admin/access-rule routes; DB unavailable",
80
- err
81
- }));
82
- }
83
- const clientPathsExcludingVerify = getClientApiPathsExpectingProsopoHeaders();
84
- env.logger.debug(() => ({
85
- msg: "Adding headerCheckMiddleware",
86
- paths: clientPathsExcludingVerify
87
- }));
88
- apiApp.set("trust proxy", 1);
89
- apiApp.use(
90
- cors({
91
- exposedHeaders: ["x-prosopo-meta"],
92
- allowedHeaders: [
93
- "Accept",
94
- "Accept-Language",
95
- "Authorization",
96
- "Content-Language",
97
- "Content-Type",
98
- "Prosopo-Site-Key",
99
- "Prosopo-User",
100
- "x-prosopo-meta"
101
- ],
102
- maxAge: 86400
103
- })
104
- );
105
- apiApp.use(express.json({ limit: "1mb" }));
106
- apiApp.use(publicRouter(env));
107
- apiApp.use(metricsMiddleware());
108
- const isTestOrDevelopmentEnv = process.env.NODE_ENV === "test" || env.config.defaultEnvironment === "development";
109
- if (!isTestOrDevelopmentEnv) {
110
- const configRateLimits = env.config.rateLimits;
111
- const rateLimits = {
112
- ...configRateLimits,
113
- ...getExpressApiRuleRateLimits()
114
- };
115
- const adminPaths = Object.values(AdminApiPaths);
116
- const rateLimitHandler = (path2) => (req, res, _next, options) => {
117
- env.logger.warn(() => ({
118
- msg: "Rate limit exceeded",
119
- data: {
120
- path: path2,
121
- ip: req.ip,
122
- siteKey: req.headers["prosopo-site-key"]
123
- }
124
- }));
125
- res.status(options.statusCode).send(options.message);
126
- };
127
- for (const [path2, limit] of Object.entries(rateLimits)) {
128
- const enumPath = path2;
129
- if (adminPaths.includes(enumPath)) {
130
- apiApp.use(
131
- enumPath,
132
- rateLimit({
133
- ...limit,
134
- handler: rateLimitHandler(enumPath),
135
- keyGenerator: (req) => {
136
- const user = getUserFromJWT(req);
137
- return user || req.ip || "unknown";
138
- }
139
- })
140
- );
141
- } else if (path2 === ClientApiPaths.VerifyImageCaptchaSolutionDapp || path2 === ClientApiPaths.VerifyPowCaptchaSolution) {
142
- apiApp.use(
143
- enumPath,
144
- rateLimit({
145
- ...limit,
146
- handler: rateLimitHandler(enumPath),
147
- keyGenerator: (req) => {
148
- const siteKey = req.headers["prosopo-site-key"];
149
- return siteKey || req.ip || "unknown";
150
- }
151
- })
152
- );
153
- } else {
154
- apiApp.use(
155
- enumPath,
156
- rateLimit({ ...limit, handler: rateLimitHandler(enumPath) })
157
- );
158
- }
159
- }
160
- }
161
- const i18Middleware = await i18nMiddleware({});
162
- apiApp.use(robotsMiddleware());
163
- apiApp.use(ignoreMiddleware());
164
- apiApp.use(requestLoggerMiddleware(env));
165
- apiApp.use(i18Middleware);
166
- apiApp.use(ja4Middleware(env));
167
- apiApp.use(handshakeTimingMiddleware(env));
168
- apiApp.use(ipInfoMiddleware(env));
169
- apiApp.use(clientPathsExcludingVerify, headerCheckMiddleware(env));
170
- apiApp.use(prosopoVerifyRouter(env));
171
- env.logger.info(() => ({ msg: "Enabling admin auth middleware" }));
172
- apiApp.use(
173
- "/v1/prosopo/provider/admin",
174
- authMiddleware(env.pair, env.authAccount)
175
- );
176
- if (apiRuleRoutesProvider) {
177
- const userAccessRuleRoutes = apiRuleRoutesProvider.getRoutes();
178
- for (const userAccessRuleRoute in userAccessRuleRoutes) {
179
- apiApp.use(
180
- userAccessRuleRoute,
181
- authMiddleware(env.pair, env.authAccount)
182
- );
183
- }
184
- for (const userAccessRuleRoute in userAccessRuleRoutes) {
185
- apiApp.use(userAccessRuleRoute, (req, res, next) => {
186
- if (req.method === "POST") {
187
- res.on("finish", () => {
188
- if (res.statusCode >= 200 && res.statusCode < 300) {
189
- getVerdictCache().clear();
190
- }
191
- });
192
- }
193
- next();
194
- });
195
- }
196
- apiApp.use(
197
- apiExpressRouterFactory.createRouter(
198
- apiRuleRoutesProvider,
199
- apiEndpointAdapter
200
- )
201
- );
202
- }
203
- if (apiAdminRoutesProvider) {
204
- apiApp.use(
205
- apiExpressRouterFactory.createRouter(
206
- apiAdminRoutesProvider,
207
- // unlike the default one, it should have errorStatusCode as 400
208
- createApiExpressDefaultEndpointAdapter(
209
- parseLogLevel(env.config.logLevel),
210
- 400
211
- )
212
- )
213
- );
214
- }
215
- apiApp.use(blockMiddleware(env));
216
- apiApp.use("/v1/prosopo/provider/client/", domainMiddleware(env));
217
- apiApp.use(prosopoRouter(env));
218
- const useTls = fs.existsSync(keyPath) && fs.existsSync(crtPath);
219
- if (useTls) {
220
- env.logger.info(() => ({ msg: "Starting Provider API with HTTPS" }));
221
- const httpsOptions = {
222
- key: fs.readFileSync(keyPath),
223
- cert: fs.readFileSync(crtPath)
224
- };
225
- const httpsServer = https__default.createServer(httpsOptions, apiApp);
226
- return httpsServer.listen(apiPort, () => {
227
- env.logger.info(() => ({
228
- data: { apiPort, protocol: "https" },
229
- msg: "Prosopo app listening with HTTPS"
230
- }));
231
- });
232
- }
233
- return apiApp.listen(apiPort, () => {
234
- env.logger.info(() => ({
235
- data: { apiPort },
236
- msg: "Prosopo app listening"
237
- }));
238
- });
90
+ env.logger.info(() => ({ msg: "Starting Prosopo API" }));
91
+ const apiApp = express();
92
+ const apiPort = port || env.config.server?.port;
93
+ const apiEndpointAdapter = createApiExpressDefaultEndpointAdapter(parseLogLevel(env.config.logLevel));
94
+ let apiRuleRoutesProvider;
95
+ let apiAdminRoutesProvider;
96
+ try {
97
+ apiRuleRoutesProvider = new AccessRuleApiRoutes(env.getDb().getUserAccessRulesStorage(), env.logger);
98
+ apiAdminRoutesProvider = createApiAdminRoutesProvider(env);
99
+ } catch (err) {
100
+ env.logger.warn(() => ({
101
+ msg: "Skipping admin/access-rule routes; DB unavailable",
102
+ err
103
+ }));
104
+ }
105
+ const clientPathsExcludingVerify = getClientApiPathsExpectingProsopoHeaders();
106
+ env.logger.debug(() => ({
107
+ msg: "Adding headerCheckMiddleware",
108
+ paths: clientPathsExcludingVerify
109
+ }));
110
+ apiApp.set("trust proxy", 1);
111
+ apiApp.use(cors({
112
+ exposedHeaders: ["x-prosopo-meta"],
113
+ allowedHeaders: [
114
+ "Accept",
115
+ "Accept-Language",
116
+ "Authorization",
117
+ "Content-Language",
118
+ "Content-Type",
119
+ "Prosopo-Site-Key",
120
+ "Prosopo-User",
121
+ "x-prosopo-meta"
122
+ ],
123
+ maxAge: 86400
124
+ }));
125
+ apiApp.use(express.json({ limit: "1mb" }));
126
+ apiApp.use(publicRouter(env));
127
+ apiApp.use(metricsMiddleware());
128
+ if (!(process.env.NODE_ENV === "test" || env.config.defaultEnvironment === "development")) {
129
+ const rateLimits = {
130
+ ...env.config.rateLimits,
131
+ ...getExpressApiRuleRateLimits()
132
+ };
133
+ const adminPaths = Object.values(AdminApiPaths);
134
+ const rateLimitHandler = (path) => (req, res, _next, options) => {
135
+ env.logger.warn(() => ({
136
+ msg: "Rate limit exceeded",
137
+ data: {
138
+ path,
139
+ ip: req.ip,
140
+ siteKey: req.headers["prosopo-site-key"]
141
+ }
142
+ }));
143
+ res.status(options.statusCode).send(options.message);
144
+ };
145
+ for (const [path, limit] of Object.entries(rateLimits)) {
146
+ const enumPath = path;
147
+ if (adminPaths.includes(enumPath)) apiApp.use(enumPath, rateLimit({
148
+ ...limit,
149
+ handler: rateLimitHandler(enumPath),
150
+ keyGenerator: (req) => {
151
+ return getUserFromJWT(req) || req.ip || "unknown";
152
+ }
153
+ }));
154
+ else if (path === ClientApiPaths.VerifyImageCaptchaSolutionDapp || path === ClientApiPaths.VerifyPowCaptchaSolution) apiApp.use(enumPath, rateLimit({
155
+ ...limit,
156
+ handler: rateLimitHandler(enumPath),
157
+ keyGenerator: (req) => {
158
+ return req.headers["prosopo-site-key"] || req.ip || "unknown";
159
+ }
160
+ }));
161
+ else apiApp.use(enumPath, rateLimit({
162
+ ...limit,
163
+ handler: rateLimitHandler(enumPath)
164
+ }));
165
+ }
166
+ }
167
+ const i18Middleware = await i18nMiddleware({});
168
+ apiApp.use(robotsMiddleware());
169
+ apiApp.use(ignoreMiddleware());
170
+ apiApp.use(requestLoggerMiddleware(env));
171
+ apiApp.use(i18Middleware);
172
+ apiApp.use(ja4Middleware(env));
173
+ apiApp.use(handshakeTimingMiddleware(env));
174
+ apiApp.use(ipInfoMiddleware(env));
175
+ apiApp.use(clientPathsExcludingVerify, headerCheckMiddleware(env));
176
+ apiApp.use(prosopoVerifyRouter(env));
177
+ env.logger.info(() => ({ msg: "Enabling admin auth middleware" }));
178
+ apiApp.use("/v1/prosopo/provider/admin", authMiddleware(env.pair, env.authAccount));
179
+ if (apiRuleRoutesProvider) {
180
+ const userAccessRuleRoutes = apiRuleRoutesProvider.getRoutes();
181
+ for (const userAccessRuleRoute in userAccessRuleRoutes) apiApp.use(userAccessRuleRoute, authMiddleware(env.pair, env.authAccount));
182
+ for (const userAccessRuleRoute in userAccessRuleRoutes) apiApp.use(userAccessRuleRoute, (req, res, next) => {
183
+ if (req.method === "POST") res.on("finish", () => {
184
+ if (res.statusCode >= 200 && res.statusCode < 300) getVerdictCache().clear();
185
+ });
186
+ next();
187
+ });
188
+ apiApp.use(apiExpressRouterFactory.createRouter(apiRuleRoutesProvider, apiEndpointAdapter));
189
+ }
190
+ if (apiAdminRoutesProvider) apiApp.use(apiExpressRouterFactory.createRouter(apiAdminRoutesProvider, createApiExpressDefaultEndpointAdapter(parseLogLevel(env.config.logLevel), 400)));
191
+ apiApp.use(blockMiddleware(env));
192
+ apiApp.use("/v1/prosopo/provider/client/", domainMiddleware(env));
193
+ apiApp.use(prosopoRouter(env));
194
+ if (fs.existsSync(keyPath) && fs.existsSync(crtPath)) {
195
+ env.logger.info(() => ({ msg: "Starting Provider API with HTTPS" }));
196
+ const httpsOptions = {
197
+ key: fs.readFileSync(keyPath),
198
+ cert: fs.readFileSync(crtPath)
199
+ };
200
+ return https.createServer(httpsOptions, apiApp).listen(apiPort, () => {
201
+ env.logger.info(() => ({
202
+ data: {
203
+ apiPort,
204
+ protocol: "https"
205
+ },
206
+ msg: "Prosopo app listening with HTTPS"
207
+ }));
208
+ });
209
+ }
210
+ return apiApp.listen(apiPort, () => {
211
+ env.logger.info(() => ({
212
+ data: { apiPort },
213
+ msg: "Prosopo app listening"
214
+ }));
215
+ });
239
216
  }
240
- export {
241
- getClientApiPathsExpectingProsopoHeaders,
242
- getUserFromJWT,
243
- isTlsAvailable,
244
- startProviderApi
245
- };
217
+ //#endregion
218
+ export { getClientApiPathsExpectingProsopoHeaders, getUserFromJWT, isTlsAvailable, startProviderApi };
@@ -1,17 +1,17 @@
1
- import { getTestSiteKeyMode, TestSiteKeyMode } from "@prosopo/types";
2
- const isReservedTestSiteKey = (siteKey) => getTestSiteKeyMode(siteKey) !== null;
3
- const resolveTestSiteKeyVerdict = (siteKey, logger) => {
4
- const mode = getTestSiteKeyMode(siteKey);
5
- if (mode === null) {
6
- return null;
7
- }
8
- logger?.warn(() => ({
9
- msg: "Reserved TEST site key - forcing deterministic captcha verdict",
10
- data: { siteKey, mode }
11
- }));
12
- return mode === TestSiteKeyMode.Pass;
13
- };
14
- export {
15
- isReservedTestSiteKey,
16
- resolveTestSiteKeyVerdict
1
+ import { TestSiteKeyMode, getTestSiteKeyMode } from "@prosopo/types";
2
+ //#region src/api/testSiteKey.ts
3
+ var isReservedTestSiteKey = (siteKey) => getTestSiteKeyMode(siteKey) !== null;
4
+ var resolveTestSiteKeyVerdict = (siteKey, logger) => {
5
+ const mode = getTestSiteKeyMode(siteKey);
6
+ if (mode === null) return null;
7
+ logger?.warn(() => ({
8
+ msg: "Reserved TEST site key - forcing deterministic captcha verdict",
9
+ data: {
10
+ siteKey,
11
+ mode
12
+ }
13
+ }));
14
+ return mode === TestSiteKeyMode.Pass;
17
15
  };
16
+ //#endregion
17
+ export { isReservedTestSiteKey, resolveTestSiteKeyVerdict };
@@ -1,25 +1,27 @@
1
1
  import { ProsopoApiError } from "@prosopo/common";
2
2
  import { validateAddress } from "@prosopo/util-crypto";
3
- const validateSiteKey = (siteKey, logger) => {
4
- return validateAddr(siteKey, "API.INVALID_SITE_KEY", logger);
3
+ //#region src/api/validateAddress.ts
4
+ var validateSiteKey = (siteKey, logger) => {
5
+ return validateAddr(siteKey, "API.INVALID_SITE_KEY", logger);
5
6
  };
6
- const validateAddr = (address, translationKey = "CONTRACT.INVALID_ADDRESS", logger) => {
7
- try {
8
- const valid = validateAddress(address, false, 42);
9
- if (!valid) {
10
- throw new ProsopoApiError(translationKey, {
11
- context: { code: 400, siteKey: address },
12
- logger
13
- });
14
- }
15
- } catch (err) {
16
- throw new ProsopoApiError(translationKey, {
17
- context: { code: 400, siteKey: address },
18
- logger
19
- });
20
- }
21
- };
22
- export {
23
- validateAddr,
24
- validateSiteKey
7
+ var validateAddr = (address, translationKey = "CONTRACT.INVALID_ADDRESS", logger) => {
8
+ try {
9
+ if (!validateAddress(address, false, 42)) throw new ProsopoApiError(translationKey, {
10
+ context: {
11
+ code: 400,
12
+ siteKey: address
13
+ },
14
+ logger
15
+ });
16
+ } catch (err) {
17
+ throw new ProsopoApiError(translationKey, {
18
+ context: {
19
+ code: 400,
20
+ siteKey: address
21
+ },
22
+ logger
23
+ });
24
+ }
25
25
  };
26
+ //#endregion
27
+ export { validateAddr, validateSiteKey };