@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,92 +1,83 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
4
- const GMAIL_DOMAINS = /* @__PURE__ */ new Set(["gmail.com", "googlemail.com"]);
5
- const DEFAULT_EMAIL_SPAM_PATTERNS = [
6
- // More than 3 dots in the local part of any address (very common
7
- // evasion against systems that don't normalise gmail addresses).
8
- {
9
- name: "many-dots-local-part",
10
- pattern: /^[^@]*\.[^@]*\.[^@]*\.[^@]*\.[^@]*@/
11
- },
12
- // Random alphanumeric suffix tags on gmail (e.g. +vkd38uoukd5).
13
- {
14
- name: "gmail-random-plus-tag",
15
- pattern: /^[^@+]+\+[a-z0-9]{6,}@(gmail|googlemail)\.com$/i
16
- }
17
- ];
18
- const splitEmail = (email) => {
19
- const trimmed = email.trim().toLowerCase();
20
- const at = trimmed.lastIndexOf("@");
21
- if (at <= 0 || at === trimmed.length - 1) {
22
- return null;
23
- }
24
- return { local: trimmed.slice(0, at), domain: trimmed.slice(at + 1) };
1
+ let _prosopo_types = require("@prosopo/types");
2
+ //#region src/tasks/spam/evaluateEmailSpamRules.ts
3
+ var GMAIL_DOMAINS = /* @__PURE__ */ new Set(["gmail.com", "googlemail.com"]);
4
+ var DEFAULT_EMAIL_SPAM_PATTERNS = [{
5
+ name: "many-dots-local-part",
6
+ pattern: /^[^@]*\.[^@]*\.[^@]*\.[^@]*\.[^@]*@/
7
+ }, {
8
+ name: "gmail-random-plus-tag",
9
+ pattern: /^[^@+]+\+[a-z0-9]{6,}@(gmail|googlemail)\.com$/i
10
+ }];
11
+ var splitEmail = (email) => {
12
+ const trimmed = email.trim().toLowerCase();
13
+ const at = trimmed.lastIndexOf("@");
14
+ if (at <= 0 || at === trimmed.length - 1) return null;
15
+ return {
16
+ local: trimmed.slice(0, at),
17
+ domain: trimmed.slice(at + 1)
18
+ };
25
19
  };
26
- const normaliseGmailAddress = (email) => {
27
- const parts = splitEmail(email);
28
- if (!parts) return email.trim().toLowerCase();
29
- if (!GMAIL_DOMAINS.has(parts.domain)) {
30
- return `${parts.local}@${parts.domain}`;
31
- }
32
- const stripped = parts.local.replace(/\./g, "").split("+")[0] ?? "";
33
- return `${stripped}@gmail.com`;
20
+ /**
21
+ * Removes dots and +tag suffixes from a gmail/googlemail local part.
22
+ * Useful for treating x.y@gmail.com, xy@gmail.com, x.y+tag@gmail.com as the
23
+ * same underlying account.
24
+ */
25
+ var normaliseGmailAddress = (email) => {
26
+ const parts = splitEmail(email);
27
+ if (!parts) return email.trim().toLowerCase();
28
+ if (!GMAIL_DOMAINS.has(parts.domain)) return `${parts.local}@${parts.domain}`;
29
+ return `${parts.local.replace(/\./g, "").split("+")[0] ?? ""}@gmail.com`;
34
30
  };
35
- const countDots = (s) => {
36
- let n = 0;
37
- for (const c of s) if (c === ".") n += 1;
38
- return n;
31
+ var countDots = (s) => {
32
+ let n = 0;
33
+ for (const c of s) if (c === ".") n += 1;
34
+ return n;
39
35
  };
40
- const regexCache = /* @__PURE__ */ new Map();
41
- const getCompiledRegex = (raw) => {
42
- const cached = regexCache.get(raw);
43
- if (cached !== void 0) {
44
- return cached;
45
- }
46
- let compiled;
47
- try {
48
- compiled = new RegExp(raw, "i");
49
- } catch {
50
- compiled = null;
51
- }
52
- regexCache.set(raw, compiled);
53
- return compiled;
36
+ var regexCache = /* @__PURE__ */ new Map();
37
+ var getCompiledRegex = (raw) => {
38
+ const cached = regexCache.get(raw);
39
+ if (cached !== void 0) return cached;
40
+ let compiled;
41
+ try {
42
+ compiled = new RegExp(raw, "i");
43
+ } catch {
44
+ compiled = null;
45
+ }
46
+ regexCache.set(raw, compiled);
47
+ return compiled;
54
48
  };
55
- const evaluateEmailSpamRules = (email, rules) => {
56
- if (!rules || !rules.enabled || !email) {
57
- return { isSpam: false };
58
- }
59
- const parts = splitEmail(email);
60
- if (!parts) {
61
- return { isSpam: true, reason: types.ResultReason.EMAIL_INVALID };
62
- }
63
- if (typeof rules.maxLocalPartDots === "number" && countDots(parts.local) > rules.maxLocalPartDots) {
64
- return { isSpam: true, reason: types.ResultReason.EMAIL_TOO_MANY_DOTS };
65
- }
66
- const target = rules.normaliseGmail ? normaliseGmailAddress(`${parts.local}@${parts.domain}`) : `${parts.local}@${parts.domain}`;
67
- if (rules.useDefaultPatterns) {
68
- for (const { name, pattern } of DEFAULT_EMAIL_SPAM_PATTERNS) {
69
- if (pattern.test(`${parts.local}@${parts.domain}`)) {
70
- return {
71
- isSpam: true,
72
- reason: types.ResultReason.EMAIL_MATCHED_DEFAULT_PATTERN,
73
- pattern: name
74
- };
75
- }
76
- }
77
- }
78
- for (const raw of rules.customRegexBlocklist ?? []) {
79
- const regex = getCompiledRegex(raw);
80
- if (regex?.test(target)) {
81
- return {
82
- isSpam: true,
83
- reason: types.ResultReason.EMAIL_MATCHED_CUSTOM_PATTERN,
84
- pattern: raw
85
- };
86
- }
87
- }
88
- return { isSpam: false };
49
+ /**
50
+ * Synchronously evaluates an email against a site's email spam rules.
51
+ * Returns { isSpam: false } if the rules are disabled, no email is supplied,
52
+ * or no rule matched.
53
+ */
54
+ var evaluateEmailSpamRules = (email, rules) => {
55
+ if (!rules || !rules.enabled || !email) return { isSpam: false };
56
+ const parts = splitEmail(email);
57
+ if (!parts) return {
58
+ isSpam: true,
59
+ reason: _prosopo_types.ResultReason.EMAIL_INVALID
60
+ };
61
+ if (typeof rules.maxLocalPartDots === "number" && countDots(parts.local) > rules.maxLocalPartDots) return {
62
+ isSpam: true,
63
+ reason: _prosopo_types.ResultReason.EMAIL_TOO_MANY_DOTS
64
+ };
65
+ const target = rules.normaliseGmail ? normaliseGmailAddress(`${parts.local}@${parts.domain}`) : `${parts.local}@${parts.domain}`;
66
+ if (rules.useDefaultPatterns) {
67
+ for (const { name, pattern } of DEFAULT_EMAIL_SPAM_PATTERNS) if (pattern.test(`${parts.local}@${parts.domain}`)) return {
68
+ isSpam: true,
69
+ reason: _prosopo_types.ResultReason.EMAIL_MATCHED_DEFAULT_PATTERN,
70
+ pattern: name
71
+ };
72
+ }
73
+ for (const raw of rules.customRegexBlocklist ?? []) if (getCompiledRegex(raw)?.test(target)) return {
74
+ isSpam: true,
75
+ reason: _prosopo_types.ResultReason.EMAIL_MATCHED_CUSTOM_PATTERN,
76
+ pattern: raw
77
+ };
78
+ return { isSpam: false };
89
79
  };
80
+ //#endregion
90
81
  exports.DEFAULT_EMAIL_SPAM_PATTERNS = DEFAULT_EMAIL_SPAM_PATTERNS;
91
82
  exports.evaluateEmailSpamRules = evaluateEmailSpamRules;
92
83
  exports.normaliseGmailAddress = normaliseGmailAddress;
@@ -1,58 +1,42 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const fs = require("node:fs");
4
- const types = require("@prosopo/types");
5
- const util = require("@prosopo/util");
6
- const node = require("@prosopo/util/node");
7
- const CACHE_FILE_PREFIX = "spam-email-domains";
8
- const CACHE_FILE_TYPE = ".txt";
9
- const updateSpamEmailDomains = async (db, logger, spamEmailDomainsUrls, cacheDir = "./spam-cache") => {
10
- const taskID = await db.createScheduledTaskStatus(
11
- types.ScheduledTaskNames.UpdateSpamEmailDomains,
12
- types.ScheduledTaskStatus.Running
13
- );
14
- try {
15
- const domainsSet = /* @__PURE__ */ new Set();
16
- for (const [index, url] of spamEmailDomainsUrls.entries()) {
17
- const filePath = await node.cacheFile(
18
- cacheDir,
19
- url,
20
- logger,
21
- `${CACHE_FILE_PREFIX}-${index.toString()}-`,
22
- CACHE_FILE_TYPE
23
- );
24
- const text = fs.readFileSync(filePath, "utf-8");
25
- const domains = text.trim().split("\n");
26
- for (const domain of domains) {
27
- const trimmedDomain = domain.trim().toLowerCase();
28
- if (trimmedDomain && !trimmedDomain.startsWith("#") && !trimmedDomain.startsWith("//") && util.validateDomain(trimmedDomain)) {
29
- domainsSet.add(trimmedDomain);
30
- }
31
- }
32
- }
33
- const ops = Array.from(domainsSet).map((domain) => ({
34
- filter: { domain: domain.trim() },
35
- update: { domain: domain.trim() }
36
- }));
37
- await db.bulkUpdateSpamEmailDomains(ops, true);
38
- await db.updateScheduledTaskStatus(taskID, types.ScheduledTaskStatus.Completed, {
39
- data: {
40
- domainsProcessed: domainsSet.size
41
- }
42
- });
43
- logger.info(() => ({
44
- msg: "Successfully updated spam email domains.",
45
- data: { domainsProcessed: domainsSet.size }
46
- }));
47
- } catch (error) {
48
- logger.error(() => ({
49
- msg: "Error updating spam email domains.",
50
- error
51
- }));
52
- await db.updateScheduledTaskStatus(taskID, types.ScheduledTaskStatus.Failed, {
53
- error: error instanceof Error ? error.message : String(error)
54
- });
55
- throw error;
56
- }
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ let _prosopo_types = require("@prosopo/types");
3
+ let _prosopo_util = require("@prosopo/util");
4
+ let node_fs = require("node:fs");
5
+ node_fs = require_runtime.__toESM(node_fs, 1);
6
+ let _prosopo_util_node = require("@prosopo/util/node");
7
+ //#region src/tasks/spam/updateSpamEmailDomains.ts
8
+ var CACHE_FILE_PREFIX = "spam-email-domains";
9
+ var CACHE_FILE_TYPE = ".txt";
10
+ var updateSpamEmailDomains = async (db, logger, spamEmailDomainsUrls, cacheDir = "./spam-cache") => {
11
+ const taskID = await db.createScheduledTaskStatus(_prosopo_types.ScheduledTaskNames.UpdateSpamEmailDomains, _prosopo_types.ScheduledTaskStatus.Running);
12
+ try {
13
+ const domainsSet = /* @__PURE__ */ new Set();
14
+ for (const [index, url] of spamEmailDomainsUrls.entries()) {
15
+ const filePath = await (0, _prosopo_util_node.cacheFile)(cacheDir, url, logger, `${CACHE_FILE_PREFIX}-${index.toString()}-`, CACHE_FILE_TYPE);
16
+ const domains = node_fs.default.readFileSync(filePath, "utf-8").trim().split("\n");
17
+ for (const domain of domains) {
18
+ const trimmedDomain = domain.trim().toLowerCase();
19
+ if (trimmedDomain && !trimmedDomain.startsWith("#") && !trimmedDomain.startsWith("//") && (0, _prosopo_util.validateDomain)(trimmedDomain)) domainsSet.add(trimmedDomain);
20
+ }
21
+ }
22
+ const ops = Array.from(domainsSet).map((domain) => ({
23
+ filter: { domain: domain.trim() },
24
+ update: { domain: domain.trim() }
25
+ }));
26
+ await db.bulkUpdateSpamEmailDomains(ops, true);
27
+ await db.updateScheduledTaskStatus(taskID, _prosopo_types.ScheduledTaskStatus.Completed, { data: { domainsProcessed: domainsSet.size } });
28
+ logger.info(() => ({
29
+ msg: "Successfully updated spam email domains.",
30
+ data: { domainsProcessed: domainsSet.size }
31
+ }));
32
+ } catch (error) {
33
+ logger.error(() => ({
34
+ msg: "Error updating spam email domains.",
35
+ error
36
+ }));
37
+ await db.updateScheduledTaskStatus(taskID, _prosopo_types.ScheduledTaskStatus.Failed, { error: error instanceof Error ? error.message : String(error) });
38
+ throw error;
39
+ }
57
40
  };
41
+ //#endregion
58
42
  exports.updateSpamEmailDomains = updateSpamEmailDomains;
@@ -1,159 +1,108 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const common = require("@prosopo/common");
4
- const database = require("@prosopo/database");
5
- const logger = require("@prosopo/logger");
6
- const usageCounters = require("../util/usageCounters.cjs");
7
- const clientTasks = require("./client/clientTasks.cjs");
8
- const datasetTasks = require("./dataset/datasetTasks.cjs");
9
- const decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
10
- const frictionlessTasks = require("./frictionless/frictionlessTasks.cjs");
11
- const imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
12
- const powTasks = require("./powCaptcha/powTasks.cjs");
13
- const puzzleTasks = require("./puzzleCaptcha/puzzleTasks.cjs");
14
- let globalWriteQueue = null;
15
- let flushStarted = false;
16
- class Tasks {
17
- constructor(env, logger$1) {
18
- this.env = env;
19
- this.config = env.config;
20
- this.db = env.getDb();
21
- this.captchaConfig = env.config.captchas;
22
- this.logger = logger$1 || logger.getLogger(logger.parseLogLevel(env.config.logLevel), "Tasks");
23
- if (!env.pair) {
24
- throw new common.ProsopoEnvError("DEVELOPER.MISSING_PROVIDER_PAIR", {
25
- context: { failedFuncName: "Tasks.constructor" }
26
- });
27
- }
28
- this.pair = env.pair;
29
- if (this.config.mongoCaptchaUri && this.db instanceof database.ProviderDatabase && !this.db.hasCentralDbStreamer()) {
30
- const streamer = new database.CentralDbStreamer(
31
- this.config.mongoCaptchaUri,
32
- this.logger
33
- );
34
- this.db.setCentralDbStreamer(streamer);
35
- this.logger.info(() => ({
36
- msg: "Central DB streamer initialized for real-time captcha data streaming"
37
- }));
38
- }
39
- this.writeQueue = this.initWriteQueue();
40
- this.decisionMachineRunner = new decisionMachineRunner.DecisionMachineRunner(this.db);
41
- this.usageCounters = this.initUsageCounters();
42
- this.powCaptchaManager = new powTasks.PowCaptchaManager(
43
- this.db,
44
- this.pair,
45
- this.config,
46
- this.logger,
47
- this.writeQueue,
48
- this.usageCounters
49
- );
50
- this.puzzleCaptchaManager = new puzzleTasks.PuzzleCaptchaManager(
51
- this.db,
52
- this.pair,
53
- this.config,
54
- this.logger,
55
- this.usageCounters
56
- );
57
- this.datasetManager = new datasetTasks.DatasetManager(
58
- this.config,
59
- this.logger,
60
- this.captchaConfig,
61
- this.db
62
- );
63
- this.imgCaptchaManager = new imgCaptchaTasks.ImgCaptchaManager(
64
- this.db,
65
- this.pair,
66
- this.config,
67
- this.logger,
68
- this.writeQueue,
69
- this.usageCounters
70
- );
71
- this.clientTaskManager = new clientTasks.ClientTaskManager(
72
- this.config,
73
- this.logger,
74
- this.db
75
- );
76
- this.frictionlessManager = new frictionlessTasks.FrictionlessManager(
77
- this.db,
78
- this.pair,
79
- this.config,
80
- this.logger,
81
- this.writeQueue,
82
- this.decisionMachineRunner,
83
- this.usageCounters
84
- );
85
- }
86
- initUsageCounters() {
87
- if (!(this.db instanceof database.ProviderDatabase)) return null;
88
- try {
89
- return new usageCounters.UsageCounters(this.db.getRedisConnection(), this.logger);
90
- } catch {
91
- return null;
92
- }
93
- }
94
- initWriteQueue() {
95
- if (globalWriteQueue) {
96
- return globalWriteQueue;
97
- }
98
- if (!(this.db instanceof database.ProviderDatabase)) {
99
- return null;
100
- }
101
- try {
102
- const redisConnection = this.db.getRedisConnection();
103
- globalWriteQueue = new database.RedisWriteQueue(redisConnection, this.logger);
104
- if (!flushStarted) {
105
- flushStarted = true;
106
- const db = this.db;
107
- const logger2 = this.logger;
108
- globalWriteQueue.startPeriodicFlush(async (queue) => {
109
- await Tasks.flushWriteQueue(queue, db, logger2);
110
- }, 1e4);
111
- }
112
- return globalWriteQueue;
113
- } catch {
114
- this.logger.debug(() => ({
115
- msg: "Redis not available for write queue - falling back to direct writes"
116
- }));
117
- return null;
118
- }
119
- }
120
- /**
121
- * Flush queued session records from Redis to MongoDB in bulk.
122
- * Called periodically by the write queue timer.
123
- *
124
- * Note: PoW challenge and pending image commitment records are written
125
- * directly to MongoDB (not queued) because verification endpoints need
126
- * to read them immediately after creation. Session records are safe to
127
- * queue because they are not read in the immediate request path.
128
- */
129
- static async flushWriteQueue(queue, db, logger2) {
130
- const sessionRecords = await queue.drainSessionRecords();
131
- if (sessionRecords.length > 0) {
132
- logger2.info(() => ({
133
- msg: `Flushing ${sessionRecords.length} queued session records to MongoDB`
134
- }));
135
- for (const { record } of sessionRecords) {
136
- try {
137
- await db.storeSessionRecord(
138
- record
139
- );
140
- } catch (error) {
141
- logger2.error(() => ({
142
- msg: "Failed to flush queued session record",
143
- err: error
144
- }));
145
- }
146
- }
147
- }
148
- }
149
- setLogger(logger2) {
150
- this.logger = logger2;
151
- this.powCaptchaManager.logger = logger2;
152
- this.puzzleCaptchaManager.logger = logger2;
153
- this.datasetManager.logger = logger2;
154
- this.imgCaptchaManager.logger = logger2;
155
- this.clientTaskManager.logger = logger2;
156
- this.frictionlessManager.logger = logger2;
157
- }
158
- }
1
+ const require_usageCounters = require("../util/usageCounters.cjs");
2
+ const require_clientTasks = require("./client/clientTasks.cjs");
3
+ const require_datasetTasks = require("./dataset/datasetTasks.cjs");
4
+ const require_decisionMachineRunner = require("./decisionMachine/decisionMachineRunner.cjs");
5
+ const require_frictionlessTasks = require("./frictionless/frictionlessTasks.cjs");
6
+ const require_imgCaptchaTasks = require("./imgCaptcha/imgCaptchaTasks.cjs");
7
+ const require_powTasks = require("./powCaptcha/powTasks.cjs");
8
+ const require_puzzleTasks = require("./puzzleCaptcha/puzzleTasks.cjs");
9
+ let _prosopo_common = require("@prosopo/common");
10
+ let _prosopo_database = require("@prosopo/database");
11
+ let _prosopo_logger = require("@prosopo/logger");
12
+ //#region src/tasks/tasks.ts
13
+ /**
14
+ * Singleton write queue manager.
15
+ * Ensures only one flush timer exists across all Tasks instances.
16
+ */
17
+ var globalWriteQueue = null;
18
+ var flushStarted = false;
19
+ /**
20
+ * @description Tasks that are shared by the API and CLI
21
+ */
22
+ var Tasks = class Tasks {
23
+ constructor(env, logger) {
24
+ this.env = env;
25
+ this.config = env.config;
26
+ this.db = env.getDb();
27
+ this.captchaConfig = env.config.captchas;
28
+ this.logger = logger || (0, _prosopo_logger.getLogger)((0, _prosopo_logger.parseLogLevel)(env.config.logLevel), "Tasks");
29
+ if (!env.pair) throw new _prosopo_common.ProsopoEnvError("DEVELOPER.MISSING_PROVIDER_PAIR", { context: { failedFuncName: "Tasks.constructor" } });
30
+ this.pair = env.pair;
31
+ if (this.config.mongoCaptchaUri && this.db instanceof _prosopo_database.ProviderDatabase && !this.db.hasCentralDbStreamer()) {
32
+ const streamer = new _prosopo_database.CentralDbStreamer(this.config.mongoCaptchaUri, this.logger);
33
+ this.db.setCentralDbStreamer(streamer);
34
+ this.logger.info(() => ({ msg: "Central DB streamer initialized for real-time captcha data streaming" }));
35
+ }
36
+ this.writeQueue = this.initWriteQueue();
37
+ this.decisionMachineRunner = new require_decisionMachineRunner.DecisionMachineRunner(this.db);
38
+ this.usageCounters = this.initUsageCounters();
39
+ this.powCaptchaManager = new require_powTasks.PowCaptchaManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.usageCounters);
40
+ this.puzzleCaptchaManager = new require_puzzleTasks.PuzzleCaptchaManager(this.db, this.pair, this.config, this.logger, this.usageCounters);
41
+ this.datasetManager = new require_datasetTasks.DatasetManager(this.config, this.logger, this.captchaConfig, this.db);
42
+ this.imgCaptchaManager = new require_imgCaptchaTasks.ImgCaptchaManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.usageCounters);
43
+ this.clientTaskManager = new require_clientTasks.ClientTaskManager(this.config, this.logger, this.db);
44
+ this.frictionlessManager = new require_frictionlessTasks.FrictionlessManager(this.db, this.pair, this.config, this.logger, this.writeQueue, this.decisionMachineRunner, this.usageCounters);
45
+ }
46
+ initUsageCounters() {
47
+ if (!(this.db instanceof _prosopo_database.ProviderDatabase)) return null;
48
+ try {
49
+ return new require_usageCounters.UsageCounters(this.db.getRedisConnection(), this.logger);
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+ initWriteQueue() {
55
+ if (globalWriteQueue) return globalWriteQueue;
56
+ if (!(this.db instanceof _prosopo_database.ProviderDatabase)) return null;
57
+ try {
58
+ const redisConnection = this.db.getRedisConnection();
59
+ globalWriteQueue = new _prosopo_database.RedisWriteQueue(redisConnection, this.logger);
60
+ if (!flushStarted) {
61
+ flushStarted = true;
62
+ const db = this.db;
63
+ const logger = this.logger;
64
+ globalWriteQueue.startPeriodicFlush(async (queue) => {
65
+ await Tasks.flushWriteQueue(queue, db, logger);
66
+ }, 1e4);
67
+ }
68
+ return globalWriteQueue;
69
+ } catch {
70
+ this.logger.debug(() => ({ msg: "Redis not available for write queue - falling back to direct writes" }));
71
+ return null;
72
+ }
73
+ }
74
+ /**
75
+ * Flush queued session records from Redis to MongoDB in bulk.
76
+ * Called periodically by the write queue timer.
77
+ *
78
+ * Note: PoW challenge and pending image commitment records are written
79
+ * directly to MongoDB (not queued) because verification endpoints need
80
+ * to read them immediately after creation. Session records are safe to
81
+ * queue because they are not read in the immediate request path.
82
+ */
83
+ static async flushWriteQueue(queue, db, logger) {
84
+ const sessionRecords = await queue.drainSessionRecords();
85
+ if (sessionRecords.length > 0) {
86
+ logger.info(() => ({ msg: `Flushing ${sessionRecords.length} queued session records to MongoDB` }));
87
+ for (const { record } of sessionRecords) try {
88
+ await db.storeSessionRecord(record);
89
+ } catch (error) {
90
+ logger.error(() => ({
91
+ msg: "Failed to flush queued session record",
92
+ err: error
93
+ }));
94
+ }
95
+ }
96
+ }
97
+ setLogger(logger) {
98
+ this.logger = logger;
99
+ this.powCaptchaManager.logger = logger;
100
+ this.puzzleCaptchaManager.logger = logger;
101
+ this.datasetManager.logger = logger;
102
+ this.imgCaptchaManager.logger = logger;
103
+ this.clientTaskManager.logger = logger;
104
+ this.frictionlessManager.logger = logger;
105
+ }
106
+ };
107
+ //#endregion
159
108
  exports.Tasks = Tasks;