@blamejs/blamejs-shop 0.4.56 → 0.4.57

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 (397) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +426 -366
  4. package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
  5. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  6. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
  7. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
  8. package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
  9. package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
  10. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
  11. package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
  12. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
  13. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  14. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  15. package/lib/vendor/blamejs/api-snapshot.json +1381 -4
  16. package/lib/vendor/blamejs/eslint.config.mjs +1 -0
  17. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
  18. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
  19. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
  20. package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
  21. package/lib/vendor/blamejs/index.js +2 -0
  22. package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
  23. package/lib/vendor/blamejs/lib/acme.js +6 -5
  24. package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
  25. package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
  26. package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
  27. package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
  28. package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
  29. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
  30. package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
  31. package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
  32. package/lib/vendor/blamejs/lib/ai-input.js +2 -2
  33. package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
  34. package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
  35. package/lib/vendor/blamejs/lib/api-key.js +37 -28
  36. package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
  37. package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
  38. package/lib/vendor/blamejs/lib/archive-read.js +5 -17
  39. package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
  40. package/lib/vendor/blamejs/lib/archive.js +2 -10
  41. package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
  42. package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
  43. package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
  44. package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
  45. package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
  46. package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
  47. package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
  48. package/lib/vendor/blamejs/lib/audit.js +84 -0
  49. package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
  50. package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
  51. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
  52. package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
  53. package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
  54. package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
  55. package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
  56. package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
  57. package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
  58. package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
  59. package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
  60. package/lib/vendor/blamejs/lib/auth/password.js +7 -1
  61. package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
  62. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
  63. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
  64. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
  65. package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
  66. package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
  67. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
  68. package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
  69. package/lib/vendor/blamejs/lib/backup/index.js +14 -47
  70. package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
  71. package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
  72. package/lib/vendor/blamejs/lib/cache.js +7 -18
  73. package/lib/vendor/blamejs/lib/cbor.js +2 -1
  74. package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
  75. package/lib/vendor/blamejs/lib/cert.js +3 -10
  76. package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
  77. package/lib/vendor/blamejs/lib/cli.js +5 -1
  78. package/lib/vendor/blamejs/lib/client-hints.js +7 -9
  79. package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
  80. package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
  81. package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
  82. package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
  83. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
  84. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
  85. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
  86. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
  87. package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
  88. package/lib/vendor/blamejs/lib/compliance.js +2 -9
  89. package/lib/vendor/blamejs/lib/config-drift.js +2 -12
  90. package/lib/vendor/blamejs/lib/content-digest.js +10 -8
  91. package/lib/vendor/blamejs/lib/cookies.js +5 -11
  92. package/lib/vendor/blamejs/lib/cose.js +19 -11
  93. package/lib/vendor/blamejs/lib/cra-report.js +1 -11
  94. package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
  95. package/lib/vendor/blamejs/lib/crypto.js +120 -3
  96. package/lib/vendor/blamejs/lib/csp.js +235 -3
  97. package/lib/vendor/blamejs/lib/daemon.js +42 -41
  98. package/lib/vendor/blamejs/lib/data-act.js +19 -9
  99. package/lib/vendor/blamejs/lib/db-query.js +6 -40
  100. package/lib/vendor/blamejs/lib/db.js +34 -12
  101. package/lib/vendor/blamejs/lib/dbsc.js +5 -6
  102. package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
  103. package/lib/vendor/blamejs/lib/deprecate.js +4 -5
  104. package/lib/vendor/blamejs/lib/did.js +6 -2
  105. package/lib/vendor/blamejs/lib/dsr.js +8 -12
  106. package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
  107. package/lib/vendor/blamejs/lib/external-db.js +14 -26
  108. package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
  109. package/lib/vendor/blamejs/lib/fdx.js +22 -18
  110. package/lib/vendor/blamejs/lib/file-upload.js +80 -66
  111. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
  112. package/lib/vendor/blamejs/lib/framework-error.js +12 -0
  113. package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
  114. package/lib/vendor/blamejs/lib/fsm.js +7 -12
  115. package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
  116. package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
  117. package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
  118. package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
  119. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  120. package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
  121. package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
  122. package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
  123. package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
  124. package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
  125. package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
  126. package/lib/vendor/blamejs/lib/guard-email.js +46 -53
  127. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  128. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
  129. package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
  130. package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
  131. package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
  132. package/lib/vendor/blamejs/lib/guard-html.js +65 -117
  133. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
  134. package/lib/vendor/blamejs/lib/guard-image.js +280 -77
  135. package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
  136. package/lib/vendor/blamejs/lib/guard-json.js +87 -103
  137. package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
  138. package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
  139. package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
  140. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
  141. package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
  142. package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
  143. package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
  144. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
  145. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
  146. package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
  147. package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
  148. package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
  149. package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
  150. package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
  151. package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
  152. package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
  153. package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
  154. package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
  155. package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
  156. package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
  157. package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
  158. package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
  159. package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
  160. package/lib/vendor/blamejs/lib/guard-template.js +23 -80
  161. package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
  162. package/lib/vendor/blamejs/lib/guard-text.js +592 -0
  163. package/lib/vendor/blamejs/lib/guard-time.js +27 -95
  164. package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
  165. package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
  166. package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
  167. package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
  168. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
  169. package/lib/vendor/blamejs/lib/http-client.js +8 -21
  170. package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
  171. package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
  172. package/lib/vendor/blamejs/lib/i18n.js +83 -26
  173. package/lib/vendor/blamejs/lib/inbox.js +8 -8
  174. package/lib/vendor/blamejs/lib/incident-report.js +3 -21
  175. package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
  176. package/lib/vendor/blamejs/lib/jobs.js +3 -2
  177. package/lib/vendor/blamejs/lib/keychain.js +6 -18
  178. package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
  179. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
  180. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
  181. package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
  182. package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
  183. package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
  184. package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
  185. package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
  186. package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
  187. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  188. package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
  189. package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
  190. package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
  191. package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
  192. package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
  193. package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
  194. package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
  195. package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
  196. package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
  197. package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
  198. package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
  199. package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
  200. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
  201. package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
  202. package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
  203. package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
  204. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
  205. package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
  206. package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
  207. package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
  208. package/lib/vendor/blamejs/lib/mail-store.js +3 -2
  209. package/lib/vendor/blamejs/lib/mail.js +6 -11
  210. package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
  211. package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
  212. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
  213. package/lib/vendor/blamejs/lib/mcp.js +1 -1
  214. package/lib/vendor/blamejs/lib/mdoc.js +11 -12
  215. package/lib/vendor/blamejs/lib/metrics.js +32 -30
  216. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
  217. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
  218. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
  219. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  220. package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
  221. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
  222. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
  223. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
  224. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
  225. package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
  226. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
  227. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
  228. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
  229. package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
  230. package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
  231. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
  232. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
  233. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
  234. package/lib/vendor/blamejs/lib/migrations.js +4 -13
  235. package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
  236. package/lib/vendor/blamejs/lib/module-loader.js +44 -0
  237. package/lib/vendor/blamejs/lib/money.js +105 -0
  238. package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
  239. package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
  240. package/lib/vendor/blamejs/lib/network-dane.js +8 -6
  241. package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
  242. package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
  243. package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
  244. package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
  245. package/lib/vendor/blamejs/lib/network-tls.js +40 -42
  246. package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
  247. package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
  248. package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
  249. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
  250. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
  251. package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
  252. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
  253. package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
  254. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
  255. package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
  256. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
  257. package/lib/vendor/blamejs/lib/observability.js +95 -0
  258. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
  259. package/lib/vendor/blamejs/lib/otel-export.js +7 -10
  260. package/lib/vendor/blamejs/lib/outbox.js +43 -37
  261. package/lib/vendor/blamejs/lib/pagination.js +11 -15
  262. package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
  263. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
  264. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
  265. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
  266. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
  267. package/lib/vendor/blamejs/lib/pick.js +63 -5
  268. package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
  269. package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
  270. package/lib/vendor/blamejs/lib/problem-details.js +2 -5
  271. package/lib/vendor/blamejs/lib/pubsub.js +4 -8
  272. package/lib/vendor/blamejs/lib/redact.js +2 -1
  273. package/lib/vendor/blamejs/lib/render.js +4 -2
  274. package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
  275. package/lib/vendor/blamejs/lib/restore.js +5 -22
  276. package/lib/vendor/blamejs/lib/retention.js +3 -5
  277. package/lib/vendor/blamejs/lib/safe-async.js +457 -0
  278. package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
  279. package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
  280. package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
  281. package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
  282. package/lib/vendor/blamejs/lib/safe-json.js +7 -8
  283. package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
  284. package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
  285. package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
  286. package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
  287. package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
  288. package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
  289. package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
  290. package/lib/vendor/blamejs/lib/sandbox.js +3 -2
  291. package/lib/vendor/blamejs/lib/scheduler.js +5 -12
  292. package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
  293. package/lib/vendor/blamejs/lib/seeders.js +4 -11
  294. package/lib/vendor/blamejs/lib/self-update.js +92 -69
  295. package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
  296. package/lib/vendor/blamejs/lib/session.js +194 -6
  297. package/lib/vendor/blamejs/lib/sql.js +225 -78
  298. package/lib/vendor/blamejs/lib/sse.js +6 -10
  299. package/lib/vendor/blamejs/lib/static.js +136 -98
  300. package/lib/vendor/blamejs/lib/storage.js +4 -2
  301. package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
  302. package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
  303. package/lib/vendor/blamejs/lib/tsa.js +11 -15
  304. package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
  305. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
  306. package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
  307. package/lib/vendor/blamejs/lib/vc.js +2 -7
  308. package/lib/vendor/blamejs/lib/vex.js +35 -13
  309. package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
  310. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
  311. package/lib/vendor/blamejs/lib/webhook.js +43 -18
  312. package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
  313. package/lib/vendor/blamejs/lib/websocket.js +7 -3
  314. package/lib/vendor/blamejs/lib/worm.js +2 -3
  315. package/lib/vendor/blamejs/lib/ws-client.js +8 -10
  316. package/lib/vendor/blamejs/package.json +1 -1
  317. package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
  318. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
  319. package/lib/vendor/blamejs/test/00-primitives.js +136 -7
  320. package/lib/vendor/blamejs/test/10-state.js +9 -3
  321. package/lib/vendor/blamejs/test/30-chain.js +40 -0
  322. package/lib/vendor/blamejs/test/helpers/check.js +18 -0
  323. package/lib/vendor/blamejs/test/helpers/db.js +4 -0
  324. package/lib/vendor/blamejs/test/helpers/index.js +1 -0
  325. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
  326. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
  327. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
  328. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
  329. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
  330. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
  331. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
  335. package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
  336. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
  337. package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
  341. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
  342. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
  344. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
  346. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
  347. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
  348. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
  349. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
  387. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
  388. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
  389. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
  390. package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
  391. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
  392. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
  393. package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
  396. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
  397. package/package.json +1 -1
@@ -127,8 +127,9 @@
127
127
  */
128
128
 
129
129
  var net = require("node:net");
130
+ var safeBuffer = require("./safe-buffer");
130
131
  var mailServerTls = require("./mail-server-tls");
131
- var lazyRequire = require("./lazy-require");
132
+ var mailServerNet = require("./mail-server-net");
132
133
  var C = require("./constants");
133
134
  var bCrypto = require("./crypto");
134
135
  var numericBounds = require("./numeric-bounds");
@@ -139,7 +140,7 @@ var mailServerRateLimit = require("./mail-server-rate-limit");
139
140
  var mailServerRegistry = require("./mail-server-registry");
140
141
  var { defineClass } = require("./framework-error");
141
142
 
142
- var audit = lazyRequire(function () { return require("./audit"); });
143
+ var auditEmit = require("./audit-emit");
143
144
 
144
145
  var MailServerManageSieveError = defineClass("MailServerManageSieveError",
145
146
  { alwaysPermanent: true });
@@ -226,40 +227,18 @@ function create(opts) {
226
227
  // the actual script bytes — same cap on both sides).
227
228
  var safeSieveProfile = profile;
228
229
 
229
- var rateLimit;
230
- if (opts.rateLimit === false) {
231
- rateLimit = mailServerRateLimit.create({ disabled: true });
232
- } else if (opts.rateLimit && typeof opts.rateLimit.admitConnection === "function") {
233
- rateLimit = opts.rateLimit;
234
- } else {
235
- rateLimit = mailServerRateLimit.create(opts.rateLimit || {});
236
- }
230
+ var rateLimit = mailServerRateLimit.resolve(opts.rateLimit);
237
231
 
238
- var tcpServer = null;
239
- var listening = false;
240
232
  var connections = new Set();
241
233
 
242
- function _emit(action, metadata, outcome) {
243
- try {
244
- audit().safeEmit({
245
- action: action,
246
- outcome: outcome || "success",
247
- metadata: metadata || {},
248
- });
249
- } catch (_e) { /* drop-silent — audit best-effort */ }
250
- }
234
+ var _emit = auditEmit.emit;
251
235
 
252
236
  function _handleConnection(rawSocket) {
253
- var remoteAddress = rawSocket.remoteAddress || "0.0.0.0";
254
- var admit = rateLimit.admitConnection(remoteAddress);
255
- if (!admit.ok) {
256
- _emit("mail.server.managesieve.rate_limit_refused",
257
- { remoteAddress: remoteAddress, reason: admit.reason }, "denied");
258
- try { rawSocket.write('NO "Too many connections from your IP"\r\n'); }
259
- catch (_e) { /* socket may be down */ }
260
- try { rawSocket.destroy(); } catch (_e2) { /* idempotent */ }
261
- return;
262
- }
237
+ var remoteAddress = mailServerNet.admitConnection(rawSocket, rateLimit, _emit, {
238
+ refusedEvent: "mail.server.managesieve.rate_limit_refused",
239
+ refusalLine: 'NO "Too many connections from your IP"\r\n',
240
+ });
241
+ if (remoteAddress === null) return;
263
242
  var connectionId = "msvconn-" + bCrypto.generateToken(8); // connection-id length
264
243
  var socket = rawSocket;
265
244
  connections.add(socket);
@@ -354,7 +333,7 @@ function create(opts) {
354
333
  }
355
334
  var crlf = state.lineBuffer.indexOf("\r\n");
356
335
  if (crlf === -1) {
357
- if (state.lineBuffer.length > maxLineBytes) {
336
+ if (safeBuffer.byteLengthOf(state.lineBuffer) > maxLineBytes) {
358
337
  _writeNo(socket, "Line too long (cap " + maxLineBytes + ")");
359
338
  _close(socket);
360
339
  }
@@ -525,19 +504,18 @@ function create(opts) {
525
504
  }
526
505
  _writeOk(socket, "Begin TLS negotiation now");
527
506
  // RFC 5804 §2.2 — discard any bytes the client queued before the
528
- // upgrade so pre-handshake injection can't survive into the post-
529
- // TLS session. The shared upgradeSocket helper handles the
530
- // CVE-2021-33515 / CVE-2021-38371 listener-strip + pause; the
531
- // pending-protocol state still belongs to managesieve.
532
- state.lineBuffer = Buffer.alloc(0);
533
- state.pendingLiteral = null;
534
- state.pendingAuth = null;
535
- mailServerTls.upgradeSocket({
536
- plainSocket: socket,
507
+ // upgrade (lineBuffer + pendingLiteral + pendingAuth) so pre-
508
+ // handshake injection can't survive into the post-TLS session.
509
+ // The shared upgradeLineProtocol helper owns that drain plus the
510
+ // CVE-2021-33515 / CVE-2021-38371 listener-strip + pause + read-pump.
511
+ mailServerTls.upgradeLineProtocol({
512
+ state: state,
513
+ socket: socket,
537
514
  secureContext: tlsContext,
538
515
  idleTimeoutMs: idleTimeoutMs,
516
+ clearFields: ["pendingLiteral", "pendingAuth"],
517
+ drain: _drainBuffer,
539
518
  onSecure: function (tlsSocket) {
540
- state.tls = true;
541
519
  _emit("mail.server.managesieve.starttls_upgraded",
542
520
  { connectionId: state.id });
543
521
  // RFC 5804 §2.2 — server MUST re-emit capabilities on the
@@ -546,10 +524,6 @@ function create(opts) {
546
524
  _emitCapabilityBanner(state, tlsSocket);
547
525
  _writeOk(tlsSocket, "TLS negotiation successful");
548
526
  },
549
- onData: function (tlsSocket, chunk) {
550
- state.lineBuffer = Buffer.concat([state.lineBuffer, chunk]);
551
- _drainBuffer(state, tlsSocket);
552
- },
553
527
  onError: function (err) {
554
528
  _emit("mail.server.managesieve.starttls_handshake_failed",
555
529
  { connectionId: state.id, error: (err && err.message) || String(err) }, "failure");
@@ -863,43 +837,15 @@ function create(opts) {
863
837
  }
864
838
 
865
839
  // ---- Lifecycle ----------------------------------------------------------
866
- async function listen(listenOpts) {
867
- listenOpts = listenOpts || {};
868
- if (listening) {
869
- throw new MailServerManageSieveError("mail-server-managesieve/already-listening",
870
- "listen: already listening");
871
- }
872
- var port = listenOpts.port === undefined ? DEFAULT_PORT : listenOpts.port;
873
- var address = listenOpts.address || "0.0.0.0";
874
- tcpServer = net.createServer(function (socket) { _handleConnection(socket); });
875
- return new Promise(function (resolve, reject) {
876
- tcpServer.once("error", reject);
877
- tcpServer.listen(port, address, function () {
878
- listening = true;
879
- tcpServer.removeListener("error", reject);
880
- _emit("mail.server.managesieve.listening", { port: port, address: address });
881
- resolve({ port: tcpServer.address().port, address: address });
882
- });
883
- });
884
- }
885
-
886
- async function close() {
887
- if (!listening) return;
888
- listening = false;
889
- for (var s of connections) { try { s.destroy(); } catch (_e) { /* idempotent */ } }
890
- connections.clear();
891
- return new Promise(function (resolve) {
892
- tcpServer.close(function () {
893
- _emit("mail.server.managesieve.closed", {});
894
- resolve();
895
- });
896
- });
897
- }
898
-
899
- return {
900
- listen: listen,
901
- close: close,
902
- };
840
+ return mailServerNet.createStoreServer(net, {
841
+ defaultPort: DEFAULT_PORT,
842
+ handleConnection: _handleConnection,
843
+ errorClass: MailServerManageSieveError,
844
+ errorCodePrefix: "mail-server-managesieve/",
845
+ emit: _emit,
846
+ connections: connections,
847
+ eventBase: "mail.server.managesieve",
848
+ });
903
849
  }
904
850
 
905
851
  module.exports = {
@@ -150,9 +150,10 @@ var guardSmtpCommand = require("./guard-smtp-command");
150
150
  var guardDomain = require("./guard-domain");
151
151
  var mailServerRateLimit = require("./mail-server-rate-limit");
152
152
  var mailServerTls = require("./mail-server-tls");
153
+ var mailServerNet = require("./mail-server-net");
153
154
  var { defineClass } = require("./framework-error");
154
155
 
155
- var audit = lazyRequire(function () { return require("./audit"); });
156
+ var auditEmit = require("./audit-emit");
156
157
  // Lazy like the sibling host primitives' guard loads — the inbound
157
158
  // authentication pipeline (and the DKIM verifier whose range
158
159
  // constants the boot validation mirrors) only loads when an operator
@@ -338,14 +339,7 @@ function create(opts) {
338
339
  // handle from b.mail.server.rateLimit.create({...}) to share one
339
340
  // budget across multiple listeners, or pass an opts object to
340
341
  // override defaults.
341
- var rateLimit;
342
- if (opts.rateLimit === false) {
343
- rateLimit = mailServerRateLimit.create({ disabled: true });
344
- } else if (opts.rateLimit && typeof opts.rateLimit.admitConnection === "function") {
345
- rateLimit = opts.rateLimit;
346
- } else {
347
- rateLimit = mailServerRateLimit.create(opts.rateLimit || {});
348
- }
342
+ var rateLimit = mailServerRateLimit.resolve(opts.rateLimit);
349
343
 
350
344
  // DATA-phase message-authentication gate. `guardEnvelope: true`
351
345
  // gates with defaults; an object tunes it. Like the sibling gates
@@ -451,16 +445,12 @@ function create(opts) {
451
445
  });
452
446
  }
453
447
  function _validateDomainHardened(d, label) {
454
- if (!guardDomainProfile) return { ok: true };
455
- var verdict = guardDomain.validate(d, guardDomainProfile);
456
- if (!verdict.ok) {
457
- _emit("mail.server.mx.domain_refused", {
458
- reason: verdict.issues && verdict.issues[0] && verdict.issues[0].kind,
459
- domain: d,
460
- label: label,
461
- }, "denied");
462
- }
463
- return verdict;
448
+ return mailServerNet.validateDomainHardened(d, label, {
449
+ guardDomainProfile: guardDomainProfile,
450
+ guardDomain: guardDomain,
451
+ emit: _emit,
452
+ refusedEvent: "mail.server.mx.domain_refused",
453
+ });
464
454
  }
465
455
 
466
456
  // Pre-validate operator-supplied localDomains at boot — the same
@@ -479,35 +469,19 @@ function create(opts) {
479
469
  }
480
470
  }
481
471
 
482
- var tcpServer = null;
483
- var listening = false;
484
472
  var connections = new Set();
485
473
 
486
- function _emit(action, metadata, outcome) {
487
- try {
488
- audit().safeEmit({
489
- action: action,
490
- outcome: outcome || "success",
491
- metadata: metadata || {},
492
- });
493
- } catch (_e) { /* drop-silent — audit best-effort */ }
494
- }
474
+ var _emit = auditEmit.emit;
495
475
 
496
476
  // ---- Per-connection state machine ---------------------------------------
497
477
  function _handleConnection(socket) {
498
- var remoteAddress = socket.remoteAddress || "0.0.0.0";
499
- var admit = rateLimit.admitConnection(remoteAddress);
500
- if (!admit.ok) {
501
- // 421 4.7.0 — transient refusal; sender retries elsewhere or later.
502
- // RFC 5321 §3.8 + §4.5.4.2 (transient negative completion).
503
- _emit("mail.server.mx.rate_limit_refused",
504
- { remoteAddress: remoteAddress, reason: admit.reason }, "denied");
505
- try {
506
- socket.write("421 4.7.0 Too many connections from your IP\r\n");
507
- } catch (_e) { /* socket may already be torn down */ }
508
- try { socket.destroy(); } catch (_e2) { /* idempotent */ }
509
- return;
510
- }
478
+ // 421 4.7.0 transient refusal; sender retries elsewhere or later.
479
+ // RFC 5321 §3.8 + §4.5.4.2 (transient negative completion).
480
+ var remoteAddress = mailServerNet.admitConnection(socket, rateLimit, _emit, {
481
+ refusedEvent: "mail.server.mx.rate_limit_refused",
482
+ refusalLine: "421 4.7.0 Too many connections from your IP\r\n",
483
+ });
484
+ if (remoteAddress === null) return;
511
485
  socket.once("close", function () { rateLimit.releaseConnection(remoteAddress); });
512
486
 
513
487
  var connectionId = "mxconn-" + bCrypto.generateToken(8); // connection-id length
@@ -653,7 +627,7 @@ function create(opts) {
653
627
 
654
628
  // Command phase — byte-buffered (8BITMIME-safe).
655
629
  lineBuffer = lineBuffer.length === 0 ? chunk : Buffer.concat([lineBuffer, chunk]);
656
- if (lineBuffer.length > maxLineBytes * 4) {
630
+ if (safeBuffer.byteLengthOf(lineBuffer) > maxLineBytes * 4) {
657
631
  _writeReply(socket, REPLY_500_SYNTAX,
658
632
  "5.5.6 Line too long (>" + maxLineBytes + " bytes)");
659
633
  _closeConnection(socket);
@@ -1229,38 +1203,23 @@ function create(opts) {
1229
1203
  }
1230
1204
 
1231
1205
  // ---- Lifecycle ----------------------------------------------------------
1232
- async function listen(listenOpts) {
1233
- listenOpts = listenOpts || {};
1234
- if (listening) {
1235
- throw new MailServerMxError("mail-server-mx/already-listening",
1236
- "listen: already listening");
1237
- }
1238
- // Port 0 (ephemeral, test mode) must NOT fall back to 25 the
1239
- // `|| 25` short-circuit was a footgun on the test path.
1240
- var port = listenOpts.port === undefined ? 25 : listenOpts.port; // SMTP MX port (IANA)
1241
- var address = listenOpts.address || "0.0.0.0";
1242
- tcpServer = net.createServer(function (socket) {
1243
- _handleConnection(socket);
1244
- });
1245
- return new Promise(function (resolve, reject) {
1246
- tcpServer.once("error", reject);
1247
- tcpServer.listen(port, address, function () {
1248
- listening = true;
1249
- tcpServer.removeListener("error", reject);
1250
- _emit("mail.server.mx.listening", {
1251
- port: port, address: address,
1252
- });
1253
- resolve({ port: tcpServer.address().port, address: address });
1254
- });
1255
- });
1256
- }
1206
+ // Port 0 (ephemeral, test mode) must NOT fall back to 25 — the `|| 25`
1207
+ // short-circuit was a footgun on the test path; createTcpListener honors an
1208
+ // explicit 0 (only an OMITTED port falls back to the default).
1209
+ var _tcpListener = mailServerNet.createTcpListener(net, {
1210
+ defaultPort: 25, // SMTP MX port (IANA)
1211
+ handleConnection: _handleConnection,
1212
+ errorFactory: function (code, message) { return new MailServerMxError("mail-server-mx/" + code, message); },
1213
+ emit: _emit,
1214
+ listeningEvent: "mail.server.mx.listening",
1215
+ });
1257
1216
 
1258
1217
  async function close(closeOpts) {
1259
1218
  closeOpts = closeOpts || {};
1260
- if (!listening) return;
1219
+ if (!_tcpListener.isListening()) return;
1261
1220
  var timeoutMs = closeOpts.timeoutMs || C.TIME.seconds(30);
1262
- listening = false;
1263
- tcpServer.close();
1221
+ _tcpListener.markClosed();
1222
+ _tcpListener.getServer().close();
1264
1223
  connections.forEach(function (sock) {
1265
1224
  try { _writeReply(sock, REPLY_421_SERVICE_NOT_AVAIL, "4.3.0 Server shutting down"); }
1266
1225
  catch (_e) { /* socket already gone */ }
@@ -1279,10 +1238,10 @@ function create(opts) {
1279
1238
  function connectionCount() { return connections.size; }
1280
1239
 
1281
1240
  return {
1282
- listen: listen,
1241
+ listen: _tcpListener.listen,
1283
1242
  close: close,
1284
1243
  connectionCount: connectionCount,
1285
- _portForTest: function () { return tcpServer ? tcpServer.address().port : null; },
1244
+ _portForTest: function () { var s = _tcpListener.getServer(); return s ? s.address().port : null; },
1286
1245
  };
1287
1246
  }
1288
1247
 
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+
3
+ // mail-server-net — the TCP-listener lifecycle shared by the mailbox / transfer
4
+ // servers (b.mail.server.imap / pop3 / mx / managesieve / submission). Each of
5
+ // those keeps its OWN connection set and close() drain because those diverge:
6
+ // the store servers (IMAP/POP3/ManageSieve) await a Promise-wrapped
7
+ // tcpServer.close(), while the transfer servers (MX/Submission) send an SMTP
8
+ // 421 to every live socket and drain with a timeout. What every server shares
9
+ // verbatim is the bind: refuse a double-listen, resolve the default port (never
10
+ // falling back off an explicit port 0 — the ephemeral test-bind path), create
11
+ // the listener, and arm a one-shot "error"→reject so a bind failure (EADDRINUSE,
12
+ // EACCES) rejects the listen promise instead of crashing the process. That, plus
13
+ // the listening/server state, is what createTcpListener owns.
14
+
15
+ // createTcpListener(net, cfg) — build a listener lifecycle.
16
+ // cfg.defaultPort port used when listenOpts.port is omitted (an explicit
17
+ // 0 is honored, for an ephemeral test bind).
18
+ // cfg.handleConnection (socket) => void — the server's per-connection handler.
19
+ // cfg.errorFactory (code, message) => Error — builds the typed
20
+ // "<prefix>/already-listening" double-listen error.
21
+ // cfg.emit (action, metadata) => void — the server's audit emitter.
22
+ // cfg.listeningEvent the "...listening" audit action.
23
+ // cfg.listeningExtra optional () => object merged onto the listening event
24
+ // payload (Submission reports implicitTls).
25
+ // Returns { listen, getServer, isListening, markClosed } — the server wires its
26
+ // own close() through getServer()/isListening()/markClosed().
27
+ function createTcpListener(net, cfg) {
28
+ var server = null;
29
+ var listening = false;
30
+
31
+ function listen(listenOpts) {
32
+ listenOpts = listenOpts || {};
33
+ if (listening) {
34
+ throw cfg.errorFactory("already-listening", "listen: already listening");
35
+ }
36
+ var port = listenOpts.port === undefined ? cfg.defaultPort : listenOpts.port;
37
+ var address = listenOpts.address || "0.0.0.0";
38
+ server = net.createServer(function (socket) { cfg.handleConnection(socket); });
39
+ return new Promise(function (resolve, reject) {
40
+ server.once("error", reject);
41
+ server.listen(port, address, function () {
42
+ listening = true;
43
+ server.removeListener("error", reject);
44
+ var payload = { port: port, address: address };
45
+ if (cfg.listeningExtra) {
46
+ var extra = cfg.listeningExtra();
47
+ for (var k in extra) {
48
+ if (Object.prototype.hasOwnProperty.call(extra, k)) payload[k] = extra[k];
49
+ }
50
+ }
51
+ cfg.emit(cfg.listeningEvent, payload);
52
+ resolve({ port: server.address().port, address: address });
53
+ });
54
+ });
55
+ }
56
+
57
+ // closeSimple(closeCfg) — the store-server shutdown (IMAP / POP3 / ManageSieve):
58
+ // mark closed, destroy every live socket immediately, then await the listener's
59
+ // own close before emitting the "...closed" audit. The transfer servers
60
+ // (MX / Submission) do NOT use this — they run a graceful SMTP-421 drain with a
61
+ // timeout, so they own their close() and drive it through markClosed()/getServer().
62
+ // closeCfg.connections the server's live-socket Set (destroyed + cleared).
63
+ // closeCfg.emit the server's audit emitter.
64
+ // closeCfg.closedEvent the "...closed" audit action.
65
+ function closeSimple(closeCfg) {
66
+ if (!listening) return Promise.resolve();
67
+ listening = false;
68
+ for (var s of closeCfg.connections) { try { s.destroy(); } catch (_e) { /* idempotent */ } }
69
+ closeCfg.connections.clear();
70
+ return new Promise(function (resolve) {
71
+ server.close(function () {
72
+ closeCfg.emit(closeCfg.closedEvent, {});
73
+ resolve();
74
+ });
75
+ });
76
+ }
77
+
78
+ return {
79
+ listen: listen,
80
+ closeSimple: closeSimple,
81
+ getServer: function () { return server; },
82
+ isListening: function () { return listening; },
83
+ markClosed: function () { listening = false; },
84
+ };
85
+ }
86
+
87
+ // createStoreServer(net, cfg) — the COMPLETE lifecycle of a mailbox store server
88
+ // (b.mail.server.imap / pop3 / managesieve): compose createTcpListener with the
89
+ // destroy-then-await closeSimple shutdown and return the { listen, close } a
90
+ // store server exposes. The three store servers are byte-identical here, varying
91
+ // only in port, error class, error-code prefix, and audit-event base — so the
92
+ // wiring lives here once. The transfer servers (MX / Submission) do NOT use this:
93
+ // they run a graceful SMTP-421 drain close + a richer return ({ connectionCount,
94
+ // _portForTest, ... }), so they call createTcpListener directly.
95
+ // cfg.defaultPort port used when listen() omits one (explicit 0 honored).
96
+ // cfg.handleConnection (socket) => void — the per-connection handler.
97
+ // cfg.errorClass the server's typed error constructor (code, message).
98
+ // cfg.errorCodePrefix prepended to the double-listen error code
99
+ // (e.g. "mail-server-imap/").
100
+ // cfg.emit (action, metadata) => void — the server's audit emitter.
101
+ // cfg.connections the live-socket Set (destroyed + cleared on close).
102
+ // cfg.eventBase the audit-action base; listeningEvent = eventBase +
103
+ // ".listening", closedEvent = eventBase + ".closed".
104
+ // Returns { listen, close }.
105
+ function createStoreServer(net, cfg) {
106
+ var ErrorClass = cfg.errorClass;
107
+ var listener = createTcpListener(net, {
108
+ defaultPort: cfg.defaultPort,
109
+ handleConnection: cfg.handleConnection,
110
+ errorFactory: function (code, message) { return new ErrorClass(cfg.errorCodePrefix + code, message); },
111
+ emit: cfg.emit,
112
+ listeningEvent: cfg.eventBase + ".listening",
113
+ });
114
+ function close() {
115
+ return listener.closeSimple({
116
+ connections: cfg.connections,
117
+ emit: cfg.emit,
118
+ closedEvent: cfg.eventBase + ".closed",
119
+ });
120
+ }
121
+ return { listen: listener.listen, close: close };
122
+ }
123
+
124
+ // admitConnection(socket, rateLimit, emit, cfg) — the per-connection rate-limit
125
+ // gate every mail listener's _handleConnection opens with: resolve the remote
126
+ // IP, admit it via the shared b.mail.server.rateLimit, or refuse it with a
127
+ // protocol-specific line + a "<...>.rate_limit_refused" audit (outcome "denied")
128
+ // and tear the socket down. Returns the remote address on admit, or null when
129
+ // refused — the caller does `if (addr === null) return;` then runs its own
130
+ // (protocol-specific) close handler, connection-id, tracking-set insert, and
131
+ // state machine, none of which this touches.
132
+ // cfg.refusedEvent the "<...>.rate_limit_refused" audit action.
133
+ // cfg.refusalLine the wire bytes written before destroy (IMAP "* BAD …",
134
+ // POP3 "-ERR …", SMTP "421 4.7.0 …", ManageSieve 'NO "…"').
135
+ function admitConnection(socket, rateLimit, emit, cfg) {
136
+ var remoteAddress = socket.remoteAddress || "0.0.0.0";
137
+ var admit = rateLimit.admitConnection(remoteAddress);
138
+ if (!admit.ok) {
139
+ emit(cfg.refusedEvent, { remoteAddress: remoteAddress, reason: admit.reason }, "denied");
140
+ try { socket.write(cfg.refusalLine); } catch (_e) { /* socket may be down */ }
141
+ try { socket.destroy(); } catch (_e2) { /* idempotent */ }
142
+ return null;
143
+ }
144
+ return remoteAddress;
145
+ }
146
+
147
+ // validateDomainHardened(d, label, cfg) — the hardened-domain check the MX and
148
+ // Submission transfer servers run on every HELO / MAIL FROM / RCPT TO domain.
149
+ // When a guardDomain profile is configured it validates the domain and, on
150
+ // refusal, emits a "<refusedEvent>" audit (the only per-server difference — MX
151
+ // vs Submission) before returning the verdict; with no profile it passes
152
+ // through { ok: true }. Sharing it keeps the two servers' domain-validation
153
+ // posture identical (a divergence would be a silent spoofing / IDN-homograph
154
+ // gap on one server).
155
+ // cfg.guardDomainProfile the b.guardDomain profile (falsy = validation off).
156
+ // cfg.guardDomain the b.guardDomain module (its validate(d, profile)).
157
+ // cfg.emit (action, metadata, outcome) => void audit emitter.
158
+ // cfg.refusedEvent the "<...>.domain_refused" audit action.
159
+ function validateDomainHardened(d, label, cfg) {
160
+ if (!cfg.guardDomainProfile) return { ok: true };
161
+ var verdict = cfg.guardDomain.validate(d, cfg.guardDomainProfile);
162
+ if (!verdict.ok) {
163
+ cfg.emit(cfg.refusedEvent, {
164
+ reason: verdict.issues && verdict.issues[0] && verdict.issues[0].kind,
165
+ domain: d,
166
+ label: label,
167
+ }, "denied");
168
+ }
169
+ return verdict;
170
+ }
171
+
172
+ module.exports = {
173
+ createTcpListener: createTcpListener,
174
+ createStoreServer: createStoreServer,
175
+ admitConnection: admitConnection,
176
+ validateDomainHardened: validateDomainHardened,
177
+ };