@prosopo/provider 4.15.14 → 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 (232) 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 +49 -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/spam/checkTrafficFilter.unit.test.js +140 -0
  219. package/dist/tests/unit/tasks/spam/checkTrafficFilter.unit.test.js.map +1 -1
  220. package/dist/tests/unit/testUtils/mockProviderEnv.d.ts +7 -7
  221. package/dist/util/usageCounters.js +220 -212
  222. package/dist/util.d.ts.map +1 -1
  223. package/dist/util.js +327 -364
  224. package/dist/util.js.map +1 -1
  225. package/dist/utils/devicePlatform.js +15 -9
  226. package/dist/utils/dns.js +64 -77
  227. package/dist/utils/hashUserAgent.js +14 -7
  228. package/dist/utils/hashUserIp.js +14 -6
  229. package/dist/utils/honeypot/encoders.js +74 -80
  230. package/dist/utils/honeypot/phraseBank.js +49 -44
  231. package/dist/utils/normalizeRequestIp.js +34 -26
  232. package/package.json +24 -24
@@ -1,17 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const encoders = require("../../../utils/honeypot/encoders.cjs");
4
- const phraseBank = require("../../../utils/honeypot/phraseBank.cjs");
5
- const HONEYPOT_HEADER = "x-prosopo-meta";
6
- const attachHoneypot = (res, clientRecord) => {
7
- const cfg = clientRecord.settings?.honeypot;
8
- if (!cfg?.enabled) return;
9
- const question = cfg.question ?? phraseBank.getRandomPhrase();
10
- if (!question) return;
11
- res.setHeader(
12
- HONEYPOT_HEADER,
13
- encoders.encodeHoneypotQuestion(question, cfg.encodingType)
14
- );
1
+ const require_encoders = require("../../../utils/honeypot/encoders.cjs");
2
+ const require_phraseBank = require("../../../utils/honeypot/phraseBank.cjs");
3
+ //#region src/api/captcha/getFrictionlessCaptchaChallenge/honeypotResponse.ts
4
+ var HONEYPOT_HEADER = "x-prosopo-meta";
5
+ /**
6
+ * Sets the honeypot header on the response when the client has honeypot
7
+ * enabled. Header value is base64-wrapped morse/semaphore so an inspector
8
+ * doesn't immediately recognise the encoding shape. Falls back to a random
9
+ * phrase from the bank when no custom question is configured; no-op when
10
+ * the bank is empty or honeypot is disabled.
11
+ */
12
+ var attachHoneypot = (res, clientRecord) => {
13
+ const cfg = clientRecord.settings?.honeypot;
14
+ if (!cfg?.enabled) return;
15
+ const question = cfg.question ?? require_phraseBank.getRandomPhrase();
16
+ if (!question) return;
17
+ res.setHeader(HONEYPOT_HEADER, require_encoders.encodeHoneypotQuestion(question, cfg.encodingType));
15
18
  };
19
+ //#endregion
16
20
  exports.HONEYPOT_HEADER = HONEYPOT_HEADER;
17
21
  exports.attachHoneypot = attachHoneypot;
@@ -1,28 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const resolveSessionDedup = async (tasks, token, userSitekeyIpHash, logger) => {
4
- const [existingToken, existingSession] = await Promise.all([
5
- tasks.db.getSessionRecordByToken(token),
6
- tasks.db.getSessionByuserSitekeyIpHash(userSitekeyIpHash)
7
- ]);
8
- const dedup = existingSession ? {
9
- sessionId: existingSession.sessionId,
10
- captchaType: existingSession.captchaType,
11
- session: existingSession
12
- } : null;
13
- if (!dedup && tasks.writeQueue) {
14
- const stalePointer = await tasks.writeQueue.getCachedSessionByHash(userSitekeyIpHash);
15
- if (stalePointer) {
16
- logger.warn(() => ({
17
- msg: "Evicting stale Redis dedup pointer",
18
- data: { userSitekeyIpHash, staleSessionId: stalePointer }
19
- }));
20
- await Promise.all([
21
- tasks.writeQueue.invalidateCachedSessionByHash(userSitekeyIpHash),
22
- tasks.writeQueue.invalidateCachedSession(stalePointer)
23
- ]);
24
- }
25
- }
26
- return { existingToken, dedup };
1
+ //#region src/api/captcha/getFrictionlessCaptchaChallenge/sessionDedup.ts
2
+ var resolveSessionDedup = async (tasks, token, userSitekeyIpHash, logger) => {
3
+ const [existingToken, existingSession] = await Promise.all([tasks.db.getSessionRecordByToken(token), tasks.db.getSessionByuserSitekeyIpHash(userSitekeyIpHash)]);
4
+ const dedup = existingSession ? {
5
+ sessionId: existingSession.sessionId,
6
+ captchaType: existingSession.captchaType,
7
+ session: existingSession
8
+ } : null;
9
+ if (!dedup && tasks.writeQueue) {
10
+ const stalePointer = await tasks.writeQueue.getCachedSessionByHash(userSitekeyIpHash);
11
+ if (stalePointer) {
12
+ logger.warn(() => ({
13
+ msg: "Evicting stale Redis dedup pointer",
14
+ data: {
15
+ userSitekeyIpHash,
16
+ staleSessionId: stalePointer
17
+ }
18
+ }));
19
+ await Promise.all([tasks.writeQueue.invalidateCachedSessionByHash(userSitekeyIpHash), tasks.writeQueue.invalidateCachedSession(stalePointer)]);
20
+ }
21
+ }
22
+ return {
23
+ existingToken,
24
+ dedup
25
+ };
27
26
  };
27
+ //#endregion
28
28
  exports.resolveSessionDedup = resolveSessionDedup;
@@ -1,65 +1,44 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
4
- const constants = require("./constants.cjs");
5
- const honeypotResponse = require("./honeypotResponse.cjs");
6
- const runConfiguredCaptchaTypeShortCircuit = async (input, res) => {
7
- const configuredType = input.clientRecord.settings?.captchaType;
8
- if (!configuredType || configuredType === types.CaptchaType.frictionless) {
9
- return null;
10
- }
11
- const sessionParams = {
12
- token: input.token,
13
- score: 0,
14
- threshold: input.clientRecord.settings?.frictionlessThreshold ?? constants.DEFAULT_FRICTIONLESS_THRESHOLD,
15
- scoreComponents: { baseScore: 0 },
16
- ipAddress: input.ipAddress,
17
- webView: false,
18
- iFrame: false,
19
- decryptedHeadHash: "",
20
- siteKey: input.dapp,
21
- ipInfo: input.ipInfo,
22
- headers: input.flatHeaders,
23
- mode: input.sessionMode,
24
- userSitekeyIpHash: input.userSitekeyIpHash,
25
- ...input.tcpToChelloUs !== void 0 && {
26
- tcpToChelloUs: input.tcpToChelloUs
27
- },
28
- ...input.chelloToHandshakeUs !== void 0 && {
29
- chelloToHandshakeUs: input.chelloToHandshakeUs
30
- }
31
- };
32
- input.logger.info(() => ({
33
- msg: "Frictionless decision",
34
- data: {
35
- decision: "configured_captcha_type",
36
- captchaType: configuredType
37
- }
38
- }));
39
- honeypotResponse.attachHoneypot(res, input.clientRecord);
40
- switch (configuredType) {
41
- case types.CaptchaType.image:
42
- return res.json(
43
- await input.tasks.frictionlessManager.sendImageCaptcha({
44
- ...sessionParams,
45
- solvedImagesCount: Math.min(
46
- input.env.config.captchas.solved.count,
47
- input.clientRecord.settings.imageMaxRounds
48
- )
49
- })
50
- );
51
- case types.CaptchaType.pow:
52
- return res.json(
53
- await input.tasks.frictionlessManager.sendPowCaptcha(sessionParams)
54
- );
55
- case types.CaptchaType.puzzle:
56
- return res.json(
57
- await input.tasks.frictionlessManager.sendPuzzleCaptcha(sessionParams)
58
- );
59
- default:
60
- throw new Error(
61
- `Unhandled configured captchaType in /frictionless short-circuit: ${configuredType}`
62
- );
63
- }
1
+ const require_honeypotResponse = require("./honeypotResponse.cjs");
2
+ require("./constants.cjs");
3
+ let _prosopo_types = require("@prosopo/types");
4
+ //#region src/api/captcha/getFrictionlessCaptchaChallenge/shortCircuit.ts
5
+ var runConfiguredCaptchaTypeShortCircuit = async (input, res) => {
6
+ const configuredType = input.clientRecord.settings?.captchaType;
7
+ if (!configuredType || configuredType === _prosopo_types.CaptchaType.frictionless) return null;
8
+ const sessionParams = {
9
+ token: input.token,
10
+ score: 0,
11
+ threshold: input.clientRecord.settings?.frictionlessThreshold ?? .5,
12
+ scoreComponents: { baseScore: 0 },
13
+ ipAddress: input.ipAddress,
14
+ webView: false,
15
+ iFrame: false,
16
+ decryptedHeadHash: "",
17
+ siteKey: input.dapp,
18
+ ipInfo: input.ipInfo,
19
+ headers: input.flatHeaders,
20
+ mode: input.sessionMode,
21
+ userSitekeyIpHash: input.userSitekeyIpHash,
22
+ ...input.tcpToChelloUs !== void 0 && { tcpToChelloUs: input.tcpToChelloUs },
23
+ ...input.chelloToHandshakeUs !== void 0 && { chelloToHandshakeUs: input.chelloToHandshakeUs }
24
+ };
25
+ input.logger.info(() => ({
26
+ msg: "Frictionless decision",
27
+ data: {
28
+ decision: "configured_captcha_type",
29
+ captchaType: configuredType
30
+ }
31
+ }));
32
+ require_honeypotResponse.attachHoneypot(res, input.clientRecord);
33
+ switch (configuredType) {
34
+ case _prosopo_types.CaptchaType.image: return res.json(await input.tasks.frictionlessManager.sendImageCaptcha({
35
+ ...sessionParams,
36
+ solvedImagesCount: Math.min(input.env.config.captchas.solved.count, input.clientRecord.settings.imageMaxRounds)
37
+ }));
38
+ case _prosopo_types.CaptchaType.pow: return res.json(await input.tasks.frictionlessManager.sendPowCaptcha(sessionParams));
39
+ case _prosopo_types.CaptchaType.puzzle: return res.json(await input.tasks.frictionlessManager.sendPuzzleCaptcha(sessionParams));
40
+ default: throw new Error(`Unhandled configured captchaType in /frictionless short-circuit: ${configuredType}`);
41
+ }
64
42
  };
43
+ //#endregion
65
44
  exports.runConfiguredCaptchaTypeShortCircuit = runConfiguredCaptchaTypeShortCircuit;
@@ -1,3 +1,2 @@
1
- "use strict";
2
- const handler = require("./getFrictionlessCaptchaChallenge/handler.cjs");
3
- module.exports = handler;
1
+ const require_handler = require("./getFrictionlessCaptchaChallenge/handler.cjs");
2
+ exports.default = require_handler.default;
@@ -1,209 +1,139 @@
1
- "use strict";
2
- const common = require("@prosopo/common");
3
- const datasets = require("@prosopo/datasets");
4
- const types = require("@prosopo/types");
5
- const util = require("@prosopo/util");
6
- require("../../tasks/index.cjs");
7
- const normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
8
- const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
9
- const blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
10
- const metrics = require("../metrics.cjs");
11
- const validateAddress = require("../validateAddress.cjs");
12
- const maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
13
- const tasks = require("../../tasks/tasks.cjs");
14
- const getImageCaptchaChallenge = (env, userAccessRulesStorage) => async (req, res, next) => {
15
- let parsed;
16
- const normalizedIp = normalizeRequestIp.normalizeRequestIp(req.ip, req.logger);
17
- if (!normalizedIp) {
18
- return next(
19
- new common.ProsopoApiError("API.BAD_REQUEST", {
20
- context: { code: 400, error: "IP address not found" },
21
- i18n: req.i18n,
22
- logger: req.logger
23
- })
24
- );
25
- }
26
- const ipAddress = util.getIPAddress(normalizedIp);
27
- try {
28
- parsed = types.CaptchaRequestBody.parse(req.body);
29
- } catch (err) {
30
- return next(
31
- new common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
32
- context: { code: 400, error: err },
33
- i18n: req.i18n,
34
- logger: req.logger
35
- })
36
- );
37
- }
38
- const {
39
- datasetId: clientDatasetId,
40
- user,
41
- dapp,
42
- sessionId,
43
- simdReadings
44
- } = parsed;
45
- const datasetId = clientDatasetId ?? env.datasetId;
46
- if (!datasetId) {
47
- return next(
48
- new common.ProsopoApiError("API.BAD_REQUEST", {
49
- context: {
50
- code: 400,
51
- error: "No dataset available. Please upload a dataset first."
52
- },
53
- i18n: req.i18n,
54
- logger: req.logger
55
- })
56
- );
57
- }
58
- validateAddress.validateSiteKey(dapp);
59
- validateAddress.validateAddr(user);
60
- if (apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
61
- req.logger.info(() => ({
62
- msg: "Maintenance mode active - returning dummy image challenge",
63
- data: { dapp, user, sessionId }
64
- }));
65
- return res.json(maintenanceModeResponses.buildImageMaintenanceResponse());
66
- }
67
- const tasks$1 = new tasks.Tasks(env, req.logger);
68
- try {
69
- const clientRecord = await tasks$1.db.getClientRecord(dapp);
70
- if (!clientRecord) {
71
- return next(
72
- new common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
73
- context: { code: 400, siteKey: dapp },
74
- i18n: req.i18n,
75
- logger: req.logger
76
- })
77
- );
78
- }
79
- const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
80
- const asn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
81
- const userScope = blacklistRequestInspector.getRequestUserScope(
82
- util.flatten(req.headers),
83
- req.ja4,
84
- normalizedIp,
85
- user,
86
- void 0,
87
- // headHash
88
- void 0,
89
- // coords
90
- countryCode,
91
- asn
92
- );
93
- const userAccessPolicy = (await tasks$1.imgCaptchaManager.getPrioritisedAccessPolicies(
94
- userAccessRulesStorage,
95
- dapp,
96
- userScope
97
- )).find((p) => !p.deferToVerify);
98
- const {
99
- valid,
100
- reason,
101
- sessionId: validSessionId,
102
- solvedImagesCount
103
- } = await tasks$1.imgCaptchaManager.isValidRequest(
104
- clientRecord,
105
- types.CaptchaType.image,
106
- env,
107
- sessionId,
108
- userAccessPolicy,
109
- normalizedIp
110
- );
111
- if (!valid) {
112
- return next(
113
- new common.ProsopoApiError(reason || "API.BAD_REQUEST", {
114
- context: {
115
- code: 400,
116
- siteKey: dapp,
117
- user
118
- },
119
- i18n: req.i18n,
120
- logger: req.logger
121
- })
122
- );
123
- }
124
- const captchaConfig = {
125
- solved: {
126
- count: Math.min(
127
- solvedImagesCount || userAccessPolicy?.solvedImagesCount || env.config.captchas.solved.count,
128
- clientRecord.settings.imageMaxRounds ?? types.imageMaxRoundsDefault
129
- )
130
- },
131
- unsolved: {
132
- count: userAccessPolicy?.unsolvedImagesCount || env.config.captchas.unsolved.count
133
- }
134
- };
135
- if (validSessionId && simdReadings) {
136
- await tasks$1.frictionlessManager.decryptAndAttachSimdReadingsIfAbsent(
137
- validSessionId,
138
- simdReadings,
139
- types.SimdReadingsStage.challenge
140
- ).catch((updateErr) => {
141
- req.logger.warn(() => ({
142
- err: updateErr,
143
- msg: "Failed to patch session with SIMD readings on image challenge"
144
- }));
145
- });
146
- }
147
- const taskData = await tasks$1.imgCaptchaManager.getRandomCaptchasAndRequestHash(
148
- datasetId,
149
- user,
150
- ipAddress,
151
- captchaConfig,
152
- clientRecord.settings.imageThreshold ?? 0.8,
153
- validSessionId,
154
- // Persist the full ipinfo payload — consumers read
155
- // individual flags off this object instead of separate
156
- // flat fields.
157
- req.ipInfo
158
- );
159
- const captchaResponse = {
160
- [types.ApiParams.status]: "ok",
161
- [types.ApiParams.captchas]: taskData.captchas.map((captcha) => ({
162
- ...captcha,
163
- target: req.t(`TARGET.${captcha.target}`),
164
- items: captcha.items.map(
165
- (item) => datasets.parseCaptchaAssets(item, env.assetsResolver)
166
- )
167
- })),
168
- [types.ApiParams.requestHash]: taskData.requestHash,
169
- [types.ApiParams.timestamp]: taskData.timestamp.toString(),
170
- [types.ApiParams.signature]: {
171
- [types.ApiParams.provider]: {
172
- [types.ApiParams.requestHash]: taskData.signedRequestHash
173
- }
174
- }
175
- };
176
- req.logger.info(() => ({
177
- msg: "Image captcha challenge issued",
178
- data: {
179
- captchaType: types.CaptchaType.image,
180
- requestHash: taskData.requestHash,
181
- solvedImagesCount: captchaConfig.solved.count,
182
- user,
183
- dapp,
184
- sessionId
185
- }
186
- }));
187
- metrics.recordCaptchaIssued(types.CaptchaType.image);
188
- return res.json(captchaResponse);
189
- } catch (err) {
190
- metrics.recordCaptchaIssueError(types.CaptchaType.image);
191
- req.logger.error(() => ({
192
- err,
193
- data: req.params,
194
- msg: "Error in image captcha challenge request"
195
- }));
196
- return next(
197
- new common.ProsopoApiError("API.BAD_REQUEST", {
198
- context: {
199
- error: err,
200
- code: 500,
201
- params: req.params
202
- },
203
- i18n: req.i18n,
204
- logger: req.logger
205
- })
206
- );
207
- }
1
+ const require_validateAddress = require("../validateAddress.cjs");
2
+ const require_metrics = require("../metrics.cjs");
3
+ const require_blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
4
+ const require_tasks = require("../../tasks/tasks.cjs");
5
+ const require_apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
6
+ const require_normalizeRequestIp = require("../../utils/normalizeRequestIp.cjs");
7
+ const require_maintenanceModeResponses = require("./maintenanceModeResponses.cjs");
8
+ let _prosopo_common = require("@prosopo/common");
9
+ let _prosopo_types = require("@prosopo/types");
10
+ let _prosopo_util = require("@prosopo/util");
11
+ let _prosopo_datasets = require("@prosopo/datasets");
12
+ //#region src/api/captcha/getImageCaptchaChallenge.ts
13
+ var getImageCaptchaChallenge_default = (env, userAccessRulesStorage) => async (req, res, next) => {
14
+ let parsed;
15
+ const normalizedIp = require_normalizeRequestIp.normalizeRequestIp(req.ip, req.logger);
16
+ if (!normalizedIp) return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
17
+ context: {
18
+ code: 400,
19
+ error: "IP address not found"
20
+ },
21
+ i18n: req.i18n,
22
+ logger: req.logger
23
+ }));
24
+ const ipAddress = (0, _prosopo_util.getIPAddress)(normalizedIp);
25
+ try {
26
+ parsed = _prosopo_types.CaptchaRequestBody.parse(req.body);
27
+ } catch (err) {
28
+ return next(new _prosopo_common.ProsopoApiError("CAPTCHA.PARSE_ERROR", {
29
+ context: {
30
+ code: 400,
31
+ error: err
32
+ },
33
+ i18n: req.i18n,
34
+ logger: req.logger
35
+ }));
36
+ }
37
+ const { datasetId: clientDatasetId, user, dapp, sessionId, simdReadings } = parsed;
38
+ const datasetId = clientDatasetId ?? env.datasetId;
39
+ if (!datasetId) return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
40
+ context: {
41
+ code: 400,
42
+ error: "No dataset available. Please upload a dataset first."
43
+ },
44
+ i18n: req.i18n,
45
+ logger: req.logger
46
+ }));
47
+ require_validateAddress.validateSiteKey(dapp);
48
+ require_validateAddress.validateAddr(user);
49
+ if (require_apiToggleMaintenanceModeEndpoint.getMaintenanceMode()) {
50
+ req.logger.info(() => ({
51
+ msg: "Maintenance mode active - returning dummy image challenge",
52
+ data: {
53
+ dapp,
54
+ user,
55
+ sessionId
56
+ }
57
+ }));
58
+ return res.json(require_maintenanceModeResponses.buildImageMaintenanceResponse());
59
+ }
60
+ const tasks = new require_tasks.Tasks(env, req.logger);
61
+ try {
62
+ const clientRecord = await tasks.db.getClientRecord(dapp);
63
+ if (!clientRecord) return next(new _prosopo_common.ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
64
+ context: {
65
+ code: 400,
66
+ siteKey: dapp
67
+ },
68
+ i18n: req.i18n,
69
+ logger: req.logger
70
+ }));
71
+ const countryCode = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.countryCode : void 0;
72
+ const asn = req.ipInfo && "isValid" in req.ipInfo && req.ipInfo.isValid ? req.ipInfo.asnNumber : void 0;
73
+ const userScope = require_blacklistRequestInspector.getRequestUserScope((0, _prosopo_util.flatten)(req.headers), req.ja4, normalizedIp, user, void 0, void 0, countryCode, asn);
74
+ const userAccessPolicy = (await tasks.imgCaptchaManager.getPrioritisedAccessPolicies(userAccessRulesStorage, dapp, userScope)).find((p) => !p.deferToVerify);
75
+ const { valid, reason, sessionId: validSessionId, solvedImagesCount } = await tasks.imgCaptchaManager.isValidRequest(clientRecord, _prosopo_types.CaptchaType.image, env, sessionId, userAccessPolicy, normalizedIp);
76
+ if (!valid) return next(new _prosopo_common.ProsopoApiError(reason || "API.BAD_REQUEST", {
77
+ context: {
78
+ code: 400,
79
+ siteKey: dapp,
80
+ user
81
+ },
82
+ i18n: req.i18n,
83
+ logger: req.logger
84
+ }));
85
+ const captchaConfig = {
86
+ solved: { count: Math.min(solvedImagesCount || userAccessPolicy?.solvedImagesCount || env.config.captchas.solved.count, clientRecord.settings.imageMaxRounds ?? _prosopo_types.imageMaxRoundsDefault) },
87
+ unsolved: { count: userAccessPolicy?.unsolvedImagesCount || env.config.captchas.unsolved.count }
88
+ };
89
+ if (validSessionId && simdReadings) await tasks.frictionlessManager.decryptAndAttachSimdReadingsIfAbsent(validSessionId, simdReadings, _prosopo_types.SimdReadingsStage.challenge).catch((updateErr) => {
90
+ req.logger.warn(() => ({
91
+ err: updateErr,
92
+ msg: "Failed to patch session with SIMD readings on image challenge"
93
+ }));
94
+ });
95
+ const taskData = await tasks.imgCaptchaManager.getRandomCaptchasAndRequestHash(datasetId, user, ipAddress, captchaConfig, clientRecord.settings.imageThreshold ?? .8, validSessionId, req.ipInfo);
96
+ const captchaResponse = {
97
+ [_prosopo_types.ApiParams.status]: "ok",
98
+ [_prosopo_types.ApiParams.captchas]: taskData.captchas.map((captcha) => ({
99
+ ...captcha,
100
+ target: req.t(`TARGET.${captcha.target}`),
101
+ items: captcha.items.map((item) => (0, _prosopo_datasets.parseCaptchaAssets)(item, env.assetsResolver))
102
+ })),
103
+ [_prosopo_types.ApiParams.requestHash]: taskData.requestHash,
104
+ [_prosopo_types.ApiParams.timestamp]: taskData.timestamp.toString(),
105
+ [_prosopo_types.ApiParams.signature]: { [_prosopo_types.ApiParams.provider]: { [_prosopo_types.ApiParams.requestHash]: taskData.signedRequestHash } }
106
+ };
107
+ req.logger.info(() => ({
108
+ msg: "Image captcha challenge issued",
109
+ data: {
110
+ captchaType: _prosopo_types.CaptchaType.image,
111
+ requestHash: taskData.requestHash,
112
+ solvedImagesCount: captchaConfig.solved.count,
113
+ user,
114
+ dapp,
115
+ sessionId
116
+ }
117
+ }));
118
+ require_metrics.recordCaptchaIssued(_prosopo_types.CaptchaType.image);
119
+ return res.json(captchaResponse);
120
+ } catch (err) {
121
+ require_metrics.recordCaptchaIssueError(_prosopo_types.CaptchaType.image);
122
+ req.logger.error(() => ({
123
+ err,
124
+ data: req.params,
125
+ msg: "Error in image captcha challenge request"
126
+ }));
127
+ return next(new _prosopo_common.ProsopoApiError("API.BAD_REQUEST", {
128
+ context: {
129
+ error: err,
130
+ code: 500,
131
+ params: req.params
132
+ },
133
+ i18n: req.i18n,
134
+ logger: req.logger
135
+ }));
136
+ }
208
137
  };
209
- module.exports = getImageCaptchaChallenge;
138
+ //#endregion
139
+ exports.default = getImageCaptchaChallenge_default;