@blamejs/blamejs-shop 0.4.55 → 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 (399) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/admin.js +385 -2
  3. package/lib/asset-manifest.json +1 -1
  4. package/lib/vendor/MANIFEST.json +426 -366
  5. package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
  6. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  7. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
  8. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
  9. package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
  10. package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
  11. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
  12. package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
  13. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
  14. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  15. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  16. package/lib/vendor/blamejs/api-snapshot.json +1381 -4
  17. package/lib/vendor/blamejs/eslint.config.mjs +1 -0
  18. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
  19. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
  20. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
  21. package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
  22. package/lib/vendor/blamejs/index.js +2 -0
  23. package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
  24. package/lib/vendor/blamejs/lib/acme.js +6 -5
  25. package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
  26. package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
  27. package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
  28. package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
  29. package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
  30. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
  31. package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
  32. package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
  33. package/lib/vendor/blamejs/lib/ai-input.js +2 -2
  34. package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
  35. package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
  36. package/lib/vendor/blamejs/lib/api-key.js +37 -28
  37. package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
  38. package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
  39. package/lib/vendor/blamejs/lib/archive-read.js +5 -17
  40. package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
  41. package/lib/vendor/blamejs/lib/archive.js +2 -10
  42. package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
  43. package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
  44. package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
  45. package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
  46. package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
  47. package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
  48. package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
  49. package/lib/vendor/blamejs/lib/audit.js +84 -0
  50. package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
  51. package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
  52. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
  53. package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
  54. package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
  55. package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
  56. package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
  57. package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
  58. package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
  59. package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
  60. package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
  61. package/lib/vendor/blamejs/lib/auth/password.js +7 -1
  62. package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
  63. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
  64. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
  65. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
  66. package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
  67. package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
  68. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
  69. package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
  70. package/lib/vendor/blamejs/lib/backup/index.js +14 -47
  71. package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
  72. package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
  73. package/lib/vendor/blamejs/lib/cache.js +7 -18
  74. package/lib/vendor/blamejs/lib/cbor.js +2 -1
  75. package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
  76. package/lib/vendor/blamejs/lib/cert.js +3 -10
  77. package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
  78. package/lib/vendor/blamejs/lib/cli.js +5 -1
  79. package/lib/vendor/blamejs/lib/client-hints.js +7 -9
  80. package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
  81. package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
  82. package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
  83. package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
  84. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
  85. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
  86. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
  87. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
  88. package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
  89. package/lib/vendor/blamejs/lib/compliance.js +2 -9
  90. package/lib/vendor/blamejs/lib/config-drift.js +2 -12
  91. package/lib/vendor/blamejs/lib/content-digest.js +10 -8
  92. package/lib/vendor/blamejs/lib/cookies.js +5 -11
  93. package/lib/vendor/blamejs/lib/cose.js +19 -11
  94. package/lib/vendor/blamejs/lib/cra-report.js +1 -11
  95. package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
  96. package/lib/vendor/blamejs/lib/crypto.js +120 -3
  97. package/lib/vendor/blamejs/lib/csp.js +235 -3
  98. package/lib/vendor/blamejs/lib/daemon.js +42 -41
  99. package/lib/vendor/blamejs/lib/data-act.js +19 -9
  100. package/lib/vendor/blamejs/lib/db-query.js +6 -40
  101. package/lib/vendor/blamejs/lib/db.js +34 -12
  102. package/lib/vendor/blamejs/lib/dbsc.js +5 -6
  103. package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
  104. package/lib/vendor/blamejs/lib/deprecate.js +4 -5
  105. package/lib/vendor/blamejs/lib/did.js +6 -2
  106. package/lib/vendor/blamejs/lib/dsr.js +8 -12
  107. package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
  108. package/lib/vendor/blamejs/lib/external-db.js +14 -26
  109. package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
  110. package/lib/vendor/blamejs/lib/fdx.js +22 -18
  111. package/lib/vendor/blamejs/lib/file-upload.js +80 -66
  112. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
  113. package/lib/vendor/blamejs/lib/framework-error.js +12 -0
  114. package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
  115. package/lib/vendor/blamejs/lib/fsm.js +7 -12
  116. package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
  117. package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
  118. package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
  119. package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
  120. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  121. package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
  122. package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
  123. package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
  124. package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
  125. package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
  126. package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
  127. package/lib/vendor/blamejs/lib/guard-email.js +46 -53
  128. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  129. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
  130. package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
  131. package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
  132. package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
  133. package/lib/vendor/blamejs/lib/guard-html.js +65 -117
  134. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
  135. package/lib/vendor/blamejs/lib/guard-image.js +280 -77
  136. package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
  137. package/lib/vendor/blamejs/lib/guard-json.js +87 -103
  138. package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
  139. package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
  140. package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
  141. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
  142. package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
  143. package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
  144. package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
  145. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
  146. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
  147. package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
  148. package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
  149. package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
  150. package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
  151. package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
  152. package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
  153. package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
  154. package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
  155. package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
  156. package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
  157. package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
  158. package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
  159. package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
  160. package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
  161. package/lib/vendor/blamejs/lib/guard-template.js +23 -80
  162. package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
  163. package/lib/vendor/blamejs/lib/guard-text.js +592 -0
  164. package/lib/vendor/blamejs/lib/guard-time.js +27 -95
  165. package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
  166. package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
  167. package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
  168. package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
  169. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
  170. package/lib/vendor/blamejs/lib/http-client.js +8 -21
  171. package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
  172. package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
  173. package/lib/vendor/blamejs/lib/i18n.js +83 -26
  174. package/lib/vendor/blamejs/lib/inbox.js +8 -8
  175. package/lib/vendor/blamejs/lib/incident-report.js +3 -21
  176. package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
  177. package/lib/vendor/blamejs/lib/jobs.js +3 -2
  178. package/lib/vendor/blamejs/lib/keychain.js +6 -18
  179. package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
  180. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
  181. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
  182. package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
  183. package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
  184. package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
  185. package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
  186. package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
  187. package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
  188. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  189. package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
  190. package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
  191. package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
  192. package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
  193. package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
  194. package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
  195. package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
  196. package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
  197. package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
  198. package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
  199. package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
  200. package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
  201. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
  202. package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
  203. package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
  204. package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
  205. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
  206. package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
  207. package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
  208. package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
  209. package/lib/vendor/blamejs/lib/mail-store.js +3 -2
  210. package/lib/vendor/blamejs/lib/mail.js +6 -11
  211. package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
  212. package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
  213. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
  214. package/lib/vendor/blamejs/lib/mcp.js +1 -1
  215. package/lib/vendor/blamejs/lib/mdoc.js +11 -12
  216. package/lib/vendor/blamejs/lib/metrics.js +32 -30
  217. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
  218. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
  219. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
  220. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  221. package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
  222. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
  223. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
  224. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
  225. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
  226. package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
  227. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
  228. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
  229. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
  230. package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
  231. package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
  232. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
  233. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
  234. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
  235. package/lib/vendor/blamejs/lib/migrations.js +4 -13
  236. package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
  237. package/lib/vendor/blamejs/lib/module-loader.js +44 -0
  238. package/lib/vendor/blamejs/lib/money.js +105 -0
  239. package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
  240. package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
  241. package/lib/vendor/blamejs/lib/network-dane.js +8 -6
  242. package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
  243. package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
  244. package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
  245. package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
  246. package/lib/vendor/blamejs/lib/network-tls.js +40 -42
  247. package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
  248. package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
  249. package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
  250. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
  251. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
  252. package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
  253. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
  254. package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
  255. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
  256. package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
  257. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
  258. package/lib/vendor/blamejs/lib/observability.js +95 -0
  259. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
  260. package/lib/vendor/blamejs/lib/otel-export.js +7 -10
  261. package/lib/vendor/blamejs/lib/outbox.js +43 -37
  262. package/lib/vendor/blamejs/lib/pagination.js +11 -15
  263. package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
  264. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
  265. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
  266. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
  267. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
  268. package/lib/vendor/blamejs/lib/pick.js +63 -5
  269. package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
  270. package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
  271. package/lib/vendor/blamejs/lib/problem-details.js +2 -5
  272. package/lib/vendor/blamejs/lib/pubsub.js +4 -8
  273. package/lib/vendor/blamejs/lib/redact.js +2 -1
  274. package/lib/vendor/blamejs/lib/render.js +4 -2
  275. package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
  276. package/lib/vendor/blamejs/lib/restore.js +5 -22
  277. package/lib/vendor/blamejs/lib/retention.js +3 -5
  278. package/lib/vendor/blamejs/lib/safe-async.js +457 -0
  279. package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
  280. package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
  281. package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
  282. package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
  283. package/lib/vendor/blamejs/lib/safe-json.js +7 -8
  284. package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
  285. package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
  286. package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
  287. package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
  288. package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
  289. package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
  290. package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
  291. package/lib/vendor/blamejs/lib/sandbox.js +3 -2
  292. package/lib/vendor/blamejs/lib/scheduler.js +5 -12
  293. package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
  294. package/lib/vendor/blamejs/lib/seeders.js +4 -11
  295. package/lib/vendor/blamejs/lib/self-update.js +92 -69
  296. package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
  297. package/lib/vendor/blamejs/lib/session.js +194 -6
  298. package/lib/vendor/blamejs/lib/sql.js +225 -78
  299. package/lib/vendor/blamejs/lib/sse.js +6 -10
  300. package/lib/vendor/blamejs/lib/static.js +136 -98
  301. package/lib/vendor/blamejs/lib/storage.js +4 -2
  302. package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
  303. package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
  304. package/lib/vendor/blamejs/lib/tsa.js +11 -15
  305. package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
  306. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
  307. package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
  308. package/lib/vendor/blamejs/lib/vc.js +2 -7
  309. package/lib/vendor/blamejs/lib/vex.js +35 -13
  310. package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
  311. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
  312. package/lib/vendor/blamejs/lib/webhook.js +43 -18
  313. package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
  314. package/lib/vendor/blamejs/lib/websocket.js +7 -3
  315. package/lib/vendor/blamejs/lib/worm.js +2 -3
  316. package/lib/vendor/blamejs/lib/ws-client.js +8 -10
  317. package/lib/vendor/blamejs/package.json +1 -1
  318. package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
  319. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
  320. package/lib/vendor/blamejs/test/00-primitives.js +136 -7
  321. package/lib/vendor/blamejs/test/10-state.js +9 -3
  322. package/lib/vendor/blamejs/test/30-chain.js +40 -0
  323. package/lib/vendor/blamejs/test/helpers/check.js +18 -0
  324. package/lib/vendor/blamejs/test/helpers/db.js +4 -0
  325. package/lib/vendor/blamejs/test/helpers/index.js +1 -0
  326. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
  327. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
  328. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
  329. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
  330. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
  331. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
  335. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
  336. package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
  337. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
  338. package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
  341. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
  342. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
  344. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
  345. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
  346. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
  347. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
  348. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
  349. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
  387. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
  388. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
  389. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
  390. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
  391. package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
  392. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
  393. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
  396. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
  397. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
  398. package/lib/winback-campaigns.js +202 -42
  399. package/package.json +1 -1
@@ -103,7 +103,7 @@
103
103
  */
104
104
 
105
105
  var net = require("node:net");
106
- var lazyRequire = require("./lazy-require");
106
+ var safeBuffer = require("./safe-buffer");
107
107
  var C = require("./constants");
108
108
  var bCrypto = require("./crypto");
109
109
  var numericBounds = require("./numeric-bounds");
@@ -111,11 +111,12 @@ var validateOpts = require("./validate-opts");
111
111
  var guardPop3Command = require("./guard-pop3-command");
112
112
  var mailServerRateLimit = require("./mail-server-rate-limit");
113
113
  var mailServerTls = require("./mail-server-tls");
114
+ var mailServerNet = require("./mail-server-net");
114
115
  var safeSmtp = require("./safe-smtp");
115
116
  var safeAsync = require("./safe-async");
116
117
  var { defineClass } = require("./framework-error");
117
118
 
118
- var audit = lazyRequire(function () { return require("./audit"); });
119
+ var auditEmit = require("./audit-emit");
119
120
 
120
121
  var MailServerPop3Error = defineClass("MailServerPop3Error", { alwaysPermanent: true });
121
122
 
@@ -229,40 +230,18 @@ function create(opts) {
229
230
  }
230
231
  }
231
232
 
232
- var rateLimit;
233
- if (opts.rateLimit === false) {
234
- rateLimit = mailServerRateLimit.create({ disabled: true });
235
- } else if (opts.rateLimit && typeof opts.rateLimit.admitConnection === "function") {
236
- rateLimit = opts.rateLimit;
237
- } else {
238
- rateLimit = mailServerRateLimit.create(opts.rateLimit || {});
239
- }
233
+ var rateLimit = mailServerRateLimit.resolve(opts.rateLimit);
240
234
 
241
- var tcpServer = null;
242
- var listening = false;
243
235
  var connections = new Set();
244
236
 
245
- function _emit(action, metadata, outcome) {
246
- try {
247
- audit().safeEmit({
248
- action: action,
249
- outcome: outcome || "success",
250
- metadata: metadata || {},
251
- });
252
- } catch (_e) { /* drop-silent */ }
253
- }
237
+ var _emit = auditEmit.emit;
254
238
 
255
239
  function _handleConnection(rawSocket) {
256
- var remoteAddress = rawSocket.remoteAddress || "0.0.0.0";
257
- var admit = rateLimit.admitConnection(remoteAddress);
258
- if (!admit.ok) {
259
- _emit("mail.server.pop3.rate_limit_refused",
260
- { remoteAddress: remoteAddress, reason: admit.reason }, "denied");
261
- try { rawSocket.write("-ERR Too many connections from your IP\r\n"); }
262
- catch (_e) { /* socket may be down */ }
263
- try { rawSocket.destroy(); } catch (_e2) { /* idempotent */ }
264
- return;
265
- }
240
+ var remoteAddress = mailServerNet.admitConnection(rawSocket, rateLimit, _emit, {
241
+ refusedEvent: "mail.server.pop3.rate_limit_refused",
242
+ refusalLine: "-ERR Too many connections from your IP\r\n",
243
+ });
244
+ if (remoteAddress === null) return;
266
245
  var connectionId = "pop3conn-" + bCrypto.generateToken(8); // connection-id length
267
246
  var socket = rawSocket;
268
247
  connections.add(socket);
@@ -312,7 +291,7 @@ function create(opts) {
312
291
  while (true) {
313
292
  var crlf = state.lineBuffer.indexOf("\r\n");
314
293
  if (crlf === -1) {
315
- if (state.lineBuffer.length > maxLineBytes) {
294
+ if (safeBuffer.byteLengthOf(state.lineBuffer) > maxLineBytes) {
316
295
  _writeErr(socket, "Line too long (cap " + maxLineBytes + ")");
317
296
  _close(socket);
318
297
  }
@@ -398,22 +377,18 @@ function create(opts) {
398
377
  // Drain pre-handshake buffer (RFC 2595 §4 + CVE-2021-33515 class
399
378
  // STLS-injection defense — any pipelined commands the client
400
379
  // queued before the upgrade are discarded; post-TLS reads fresh).
401
- // Listener-removal + idle-timeout re-arm live in the shared
402
- // upgradeSocket helper (b.mail.server.tls.upgradeSocket).
403
- state.lineBuffer = Buffer.alloc(0);
404
- // POP3 doesn't have an authPending shape (the SASL state is local
405
- // to _handleAuth), but reset tentativeUser so a USER pipelined
406
- // pre-handshake cannot bind a post-handshake PASS.
407
- state.tentativeUser = null;
408
- mailServerTls.upgradeSocket({
409
- plainSocket: socket,
380
+ // POP3 has no authPending shape (SASL state is local to
381
+ // _handleAuth), but tentativeUser is reset so a USER pipelined
382
+ // pre-handshake cannot bind a post-handshake PASS. The shared
383
+ // upgradeLineProtocol helper owns the lineBuffer drain + listener-
384
+ // strip + idle re-arm + read-pump.
385
+ mailServerTls.upgradeLineProtocol({
386
+ state: state,
387
+ socket: socket,
410
388
  secureContext: opts.tlsContext,
411
389
  idleTimeoutMs: idleTimeoutMs,
412
- onSecure: function (_tlsSocket) { state.tls = true; },
413
- onData: function (tlsSocket, chunk) {
414
- state.lineBuffer = Buffer.concat([state.lineBuffer, chunk]);
415
- _drainBuffer(state, tlsSocket);
416
- },
390
+ clearFields: ["tentativeUser"],
391
+ drain: _drainBuffer,
417
392
  onError: function (err) {
418
393
  _emit("mail.server.pop3.tls_handshake_failed",
419
394
  { connectionId: state.id, error: (err && err.message) || String(err) }, "failure");
@@ -870,43 +845,15 @@ function create(opts) {
870
845
  }
871
846
 
872
847
  // ---- Lifecycle ----------------------------------------------------------
873
- async function listen(listenOpts) {
874
- listenOpts = listenOpts || {};
875
- if (listening) {
876
- throw new MailServerPop3Error("mail-server-pop3/already-listening",
877
- "listen: already listening");
878
- }
879
- var port = listenOpts.port === undefined ? 110 : listenOpts.port; // RFC 1939 POP3 port (IANA)
880
- var address = listenOpts.address || "0.0.0.0";
881
- tcpServer = net.createServer(function (socket) { _handleConnection(socket); });
882
- return new Promise(function (resolve, reject) {
883
- tcpServer.once("error", reject);
884
- tcpServer.listen(port, address, function () {
885
- listening = true;
886
- tcpServer.removeListener("error", reject);
887
- _emit("mail.server.pop3.listening", { port: port, address: address });
888
- resolve({ port: tcpServer.address().port, address: address });
889
- });
890
- });
891
- }
892
-
893
- async function close() {
894
- if (!listening) return;
895
- listening = false;
896
- for (var s of connections) { try { s.destroy(); } catch (_e) { /* idempotent */ } }
897
- connections.clear();
898
- return new Promise(function (resolve) {
899
- tcpServer.close(function () {
900
- _emit("mail.server.pop3.closed", {});
901
- resolve();
902
- });
903
- });
904
- }
905
-
906
- return {
907
- listen: listen,
908
- close: close,
909
- };
848
+ return mailServerNet.createStoreServer(net, {
849
+ defaultPort: 110, // RFC 1939 POP3 port (IANA)
850
+ handleConnection: _handleConnection,
851
+ errorClass: MailServerPop3Error,
852
+ errorCodePrefix: "mail-server-pop3/",
853
+ emit: _emit,
854
+ connections: connections,
855
+ eventBase: "mail.server.pop3",
856
+ });
910
857
  }
911
858
 
912
859
  module.exports = {
@@ -88,6 +88,7 @@ var C = require("./constants");
88
88
  var lazyRequire = require("./lazy-require");
89
89
  var numericBounds = require("./numeric-bounds");
90
90
  var validateOpts = require("./validate-opts");
91
+ var boundedMap = require("./bounded-map");
91
92
  var { defineClass } = require("./framework-error");
92
93
 
93
94
  var audit = lazyRequire(function () { return require("./audit"); });
@@ -206,8 +207,7 @@ function create(opts) {
206
207
  { reason: "concurrent-per-ip", ip: ip, cap: cfg.maxConcurrentConnectionsPerIp });
207
208
  return { ok: false, reason: "concurrent-per-ip" };
208
209
  }
209
- var times = connectionTimes.get(ip);
210
- if (!times) { times = []; connectionTimes.set(ip, times); }
210
+ var times = boundedMap.getOrInsert(connectionTimes, ip, function () { return []; });
211
211
  _pruneWindow(times, CONNECTION_RATE_WINDOW_MS);
212
212
  if (times.length >= cfg.connectionsPerIpPerMinute) {
213
213
  _audit("mail.server.rate_limit.refused", "denied",
@@ -258,8 +258,7 @@ function create(opts) {
258
258
 
259
259
  function noteAuthFailure(ip) {
260
260
  if (cfg.disabled) return;
261
- var times = authFailureTimes.get(ip);
262
- if (!times) { times = []; authFailureTimes.set(ip, times); }
261
+ var times = boundedMap.getOrInsert(authFailureTimes, ip, function () { return []; });
263
262
  times.push(Date.now());
264
263
  }
265
264
 
@@ -288,8 +287,7 @@ function create(opts) {
288
287
 
289
288
  function noteRcptFailure(ip) {
290
289
  if (cfg.disabled) return;
291
- var times = rcptFailureTimes.get(ip);
292
- if (!times) { times = []; rcptFailureTimes.set(ip, times); }
290
+ var times = boundedMap.getOrInsert(rcptFailureTimes, ip, function () { return []; });
293
291
  times.push(Date.now());
294
292
  }
295
293
 
@@ -308,8 +306,34 @@ function create(opts) {
308
306
  };
309
307
  }
310
308
 
309
+ /**
310
+ * @primitive b.mail.server.rateLimit.resolve
311
+ * @signature b.mail.server.rateLimit.resolve(spec)
312
+ * @since 0.15.13
313
+ * @status stable
314
+ * @related b.mail.server.rateLimit.create
315
+ *
316
+ * Resolve a rate-limit `spec` into a limiter. `false` disables limiting
317
+ * (a disabled limiter that always admits), an already-built limiter — one
318
+ * exposing `admitConnection` — passes through unchanged, and anything else
319
+ * is treated as `create()` options. Every mail server (IMAP / POP3 / SMTP
320
+ * MX / Submission / ManageSieve) composes this at the top of its `create()`
321
+ * so the spec contract is identical across protocols.
322
+ *
323
+ * @example
324
+ * var b = require("blamejs");
325
+ * var rl = b.mail.server.rateLimit.resolve(false); // disabled
326
+ * // → a limiter whose admitConnection always admits
327
+ */
328
+ function resolve(spec) {
329
+ if (spec === false) return create({ disabled: true });
330
+ if (spec && typeof spec.admitConnection === "function") return spec;
331
+ return create(spec || {});
332
+ }
333
+
311
334
  module.exports = {
312
335
  create: create,
336
+ resolve: resolve,
313
337
  MailServerRateLimitError: MailServerRateLimitError,
314
338
  DEFAULTS: DEFAULTS,
315
339
  };
@@ -103,7 +103,6 @@
103
103
 
104
104
  var net = require("node:net");
105
105
  var nodeTls = require("node:tls");
106
- var lazyRequire = require("./lazy-require");
107
106
  var C = require("./constants");
108
107
  var bCrypto = require("./crypto");
109
108
  var numericBounds = require("./numeric-bounds");
@@ -115,9 +114,10 @@ var guardSmtpCommand = require("./guard-smtp-command");
115
114
  var guardDomain = require("./guard-domain");
116
115
  var mailServerRateLimit = require("./mail-server-rate-limit");
117
116
  var mailServerTls = require("./mail-server-tls");
117
+ var mailServerNet = require("./mail-server-net");
118
118
  var { defineClass } = require("./framework-error");
119
119
 
120
- var audit = lazyRequire(function () { return require("./audit"); });
120
+ var auditEmit = require("./audit-emit");
121
121
 
122
122
  var MailServerSubmissionError = defineClass("MailServerSubmissionError", { alwaysPermanent: true });
123
123
 
@@ -341,14 +341,7 @@ function create(opts) {
341
341
  // Default-on per-IP rate limit (see lib/mail-server-rate-limit.js).
342
342
  // Operators pass `rateLimit: false` to disable, a rate-limit handle
343
343
  // to share across listeners, or an opts object to override defaults.
344
- var rateLimit;
345
- if (opts.rateLimit === false) {
346
- rateLimit = mailServerRateLimit.create({ disabled: true });
347
- } else if (opts.rateLimit && typeof opts.rateLimit.admitConnection === "function") {
348
- rateLimit = opts.rateLimit;
349
- } else {
350
- rateLimit = mailServerRateLimit.create(opts.rateLimit || {});
351
- }
344
+ var rateLimit = mailServerRateLimit.resolve(opts.rateLimit);
352
345
 
353
346
  // Default-on guardDomain hardening for HELO / MAIL FROM / RCPT TO.
354
347
  // Same posture as mail-server-mx — IDN homograph / Punycode-spoof
@@ -367,45 +360,25 @@ function create(opts) {
367
360
  });
368
361
  }
369
362
  function _validateDomainHardened(d, label) {
370
- if (!guardDomainProfile) return { ok: true };
371
- var verdict = guardDomain.validate(d, guardDomainProfile);
372
- if (!verdict.ok) {
373
- _emit("mail.server.submission.domain_refused", {
374
- reason: verdict.issues && verdict.issues[0] && verdict.issues[0].kind,
375
- domain: d,
376
- label: label,
377
- }, "denied");
378
- }
379
- return verdict;
363
+ return mailServerNet.validateDomainHardened(d, label, {
364
+ guardDomainProfile: guardDomainProfile,
365
+ guardDomain: guardDomain,
366
+ emit: _emit,
367
+ refusedEvent: "mail.server.submission.domain_refused",
368
+ });
380
369
  }
381
370
 
382
- var tcpServer = null;
383
- var listening = false;
384
371
  var connections = new Set();
385
372
 
386
- function _emit(action, metadata, outcome) {
387
- try {
388
- audit().safeEmit({
389
- action: action,
390
- outcome: outcome || "success",
391
- metadata: metadata || {},
392
- });
393
- } catch (_e) { /* drop-silent */ }
394
- }
373
+ var _emit = auditEmit.emit;
395
374
 
396
375
  function _handleConnection(rawSocket) {
397
- var remoteAddress = rawSocket.remoteAddress || "0.0.0.0";
398
- var admit = rateLimit.admitConnection(remoteAddress);
399
- if (!admit.ok) {
400
- // 421 4.7.0 transient; sender retries elsewhere.
401
- _emit("mail.server.submission.rate_limit_refused",
402
- { remoteAddress: remoteAddress, reason: admit.reason }, "denied");
403
- try {
404
- rawSocket.write("421 4.7.0 Too many connections from your IP\r\n");
405
- } catch (_e) { /* socket may already be torn down */ }
406
- try { rawSocket.destroy(); } catch (_e2) { /* idempotent */ }
407
- return;
408
- }
376
+ // 421 4.7.0 transient; sender retries elsewhere.
377
+ var remoteAddress = mailServerNet.admitConnection(rawSocket, rateLimit, _emit, {
378
+ refusedEvent: "mail.server.submission.rate_limit_refused",
379
+ refusalLine: "421 4.7.0 Too many connections from your IP\r\n",
380
+ });
381
+ if (remoteAddress === null) return;
409
382
  rawSocket.once("close", function () { rateLimit.releaseConnection(remoteAddress); });
410
383
 
411
384
  var connectionId = "submitconn-" + bCrypto.generateToken(8); // connection-id length
@@ -570,7 +543,7 @@ function create(opts) {
570
543
  }
571
544
 
572
545
  lineBuffer = lineBuffer.length === 0 ? chunk : Buffer.concat([lineBuffer, chunk]);
573
- if (lineBuffer.length > maxLineBytes * 4) {
546
+ if (safeBuffer.byteLengthOf(lineBuffer) > maxLineBytes * 4) {
574
547
  _writeReply(socket, REPLY_500_SYNTAX,
575
548
  "5.5.6 Line too long (>" + maxLineBytes + " bytes)");
576
549
  _closeConnection(socket);
@@ -1310,37 +1283,25 @@ function create(opts) {
1310
1283
  }
1311
1284
  }
1312
1285
 
1313
- async function listen(listenOpts) {
1314
- listenOpts = listenOpts || {};
1315
- if (listening) {
1316
- throw new MailServerSubmissionError("mail-server-submission/already-listening",
1317
- "listen: already listening");
1318
- }
1319
- // Port 0 (ephemeral, test mode) must NOT fall back to the protocol
1320
- // default the `|| <default>` short-circuit was a footgun on the
1321
- // test path.
1322
- var defaultPort = implicitTls ? 465 : 587; // RFC 8314 implicit-TLS / RFC 6409 submission ports
1323
- var port = listenOpts.port === undefined ? defaultPort : listenOpts.port;
1324
- var address = listenOpts.address || "0.0.0.0";
1325
- tcpServer = net.createServer(function (socket) { _handleConnection(socket); });
1326
- return new Promise(function (resolve, reject) {
1327
- tcpServer.once("error", reject);
1328
- tcpServer.listen(port, address, function () {
1329
- listening = true;
1330
- tcpServer.removeListener("error", reject);
1331
- _emit("mail.server.submission.listening",
1332
- { port: port, address: address, implicitTls: implicitTls });
1333
- resolve({ port: tcpServer.address().port, address: address });
1334
- });
1335
- });
1336
- }
1286
+ // Port 0 (ephemeral, test mode) must NOT fall back to the protocol default —
1287
+ // the `|| <default>` short-circuit was a footgun on the test path;
1288
+ // createTcpListener honors an explicit 0 (only an OMITTED port defaults). The
1289
+ // listening event reports implicitTls so an operator can confirm the wire mode.
1290
+ var _tcpListener = mailServerNet.createTcpListener(net, {
1291
+ defaultPort: implicitTls ? 465 : 587, // RFC 8314 implicit-TLS / RFC 6409 submission ports
1292
+ handleConnection: _handleConnection,
1293
+ errorFactory: function (code, message) { return new MailServerSubmissionError("mail-server-submission/" + code, message); },
1294
+ emit: _emit,
1295
+ listeningEvent: "mail.server.submission.listening",
1296
+ listeningExtra: function () { return { implicitTls: implicitTls }; },
1297
+ });
1337
1298
 
1338
1299
  async function close(closeOpts) {
1339
1300
  closeOpts = closeOpts || {};
1340
- if (!listening) return;
1301
+ if (!_tcpListener.isListening()) return;
1341
1302
  var timeoutMs = closeOpts.timeoutMs || C.TIME.seconds(30);
1342
- listening = false;
1343
- tcpServer.close();
1303
+ _tcpListener.markClosed();
1304
+ _tcpListener.getServer().close();
1344
1305
  connections.forEach(function (sock) {
1345
1306
  try { _writeReply(sock, REPLY_421_SERVICE_NOT_AVAIL, "4.3.0 Server shutting down"); }
1346
1307
  catch (_e) { /* socket already gone */ }
@@ -1359,10 +1320,10 @@ function create(opts) {
1359
1320
  function connectionCount() { return connections.size; }
1360
1321
 
1361
1322
  return {
1362
- listen: listen,
1323
+ listen: _tcpListener.listen,
1363
1324
  close: close,
1364
1325
  connectionCount: connectionCount,
1365
- _portForTest: function () { return tcpServer ? tcpServer.address().port : null; },
1326
+ _portForTest: function () { var s = _tcpListener.getServer(); return s ? s.address().port : null; },
1366
1327
  };
1367
1328
  }
1368
1329
 
@@ -438,8 +438,97 @@ function upgradeSocket(opts) {
438
438
  return tlsSocket;
439
439
  }
440
440
 
441
+ /**
442
+ * @primitive b.mail.server.tls.upgradeLineProtocol
443
+ * @signature b.mail.server.tls.upgradeLineProtocol(opts)
444
+ * @since 0.15.13
445
+ * @status stable
446
+ * @related b.mail.server.tls.upgradeSocket
447
+ *
448
+ * STARTTLS / STLS completion for the line-buffered store listeners
449
+ * (IMAP / POP3 / ManageSieve), layered over `upgradeSocket`. The
450
+ * caller has already validated protocol state and written its
451
+ * "begin TLS" response; this owns the steps that recur identically
452
+ * across the three:
453
+ *
454
+ * 1. Drop the pre-handshake `state.lineBuffer` (always) plus any
455
+ * protocol-specific half-parsed command / literal / auth fields
456
+ * (`clearFields`) so bytes the peer pipelined before the upgrade
457
+ * cannot survive into the post-TLS session (CVE-2021-33515 /
458
+ * CVE-2021-38371 STARTTLS-injection class). Centralizing the
459
+ * `lineBuffer` reset makes it impossible for a listener to forget.
460
+ * 2. Mark `state.tls = true` on the secure event, then run the
461
+ * caller's optional `onSecure` for protocol-specific work (e.g.
462
+ * ManageSieve re-emitting its capability banner per RFC 5804).
463
+ * 3. Feed every post-handshake chunk through the caller's `drain`
464
+ * via the standard `state.lineBuffer` append.
465
+ *
466
+ * The transfer listeners (MX / submission) ingest via a serialized
467
+ * feed pump, not the line buffer, so they call `upgradeSocket`
468
+ * directly.
469
+ *
470
+ * @opts
471
+ * state: object, // connection state ({ lineBuffer, tls, … })
472
+ * socket: net.Socket, // pre-upgrade plain socket
473
+ * secureContext: tls.SecureContext, // from b.mail.server.tls.context
474
+ * idleTimeoutMs: number, // re-armed post-handshake
475
+ * clearFields: Array<string>, // extra state fields to null pre-upgrade
476
+ * drain: function(state, tlsSocket), // the protocol line drainer
477
+ * onSecure: function(tlsSocket), // optional post-secure work
478
+ * onError: function(err), // handshake / runtime error
479
+ * onTimeout: function(tlsSocket), // optional idle-timeout handler
480
+ *
481
+ * @example
482
+ * b.mail.server.tls.upgradeLineProtocol({
483
+ * state: state, socket: socket, secureContext: opts.tlsContext,
484
+ * idleTimeoutMs: idleTimeoutMs, clearFields: ["pendingLiteral"],
485
+ * drain: _drainBuffer,
486
+ * onError: function (err) { _emit("imap.tls_failed", { err: err.message }); _close(socket, state); },
487
+ * });
488
+ */
489
+ function upgradeLineProtocol(opts) {
490
+ if (!opts || typeof opts !== "object") {
491
+ throw new MailServerTlsError("mail-server-tls/bad-upgrade-line-opts",
492
+ "upgradeLineProtocol: opts required");
493
+ }
494
+ var state = opts.state;
495
+ if (!state || typeof state !== "object") {
496
+ throw new MailServerTlsError("mail-server-tls/bad-upgrade-line-state",
497
+ "upgradeLineProtocol: opts.state object required");
498
+ }
499
+ if (typeof opts.drain !== "function") {
500
+ throw new MailServerTlsError("mail-server-tls/bad-upgrade-line-drain",
501
+ "upgradeLineProtocol: opts.drain(state, tlsSocket) required");
502
+ }
503
+ // CVE-2021-33515 / CVE-2021-38371 injection defense: discard the
504
+ // pre-handshake line buffer plus every protocol-specific half-parsed
505
+ // field so nothing the peer pipelined pre-upgrade survives the TLS
506
+ // boundary.
507
+ state.lineBuffer = Buffer.alloc(0);
508
+ var clearFields = opts.clearFields;
509
+ if (clearFields) {
510
+ for (var i = 0; i < clearFields.length; i += 1) state[clearFields[i]] = null;
511
+ }
512
+ return upgradeSocket({
513
+ plainSocket: opts.socket,
514
+ secureContext: opts.secureContext,
515
+ idleTimeoutMs: opts.idleTimeoutMs,
516
+ onSecure: function (tlsSocket) {
517
+ state.tls = true;
518
+ if (typeof opts.onSecure === "function") opts.onSecure(tlsSocket);
519
+ },
520
+ onData: function (tlsSocket, chunk) {
521
+ state.lineBuffer = Buffer.concat([state.lineBuffer, chunk]);
522
+ opts.drain(state, tlsSocket);
523
+ },
524
+ onError: opts.onError,
525
+ onTimeout: opts.onTimeout,
526
+ });
527
+ }
528
+
441
529
  module.exports = {
442
530
  context: context,
443
531
  upgradeSocket: upgradeSocket,
532
+ upgradeLineProtocol: upgradeLineProtocol,
444
533
  MailServerTlsError: MailServerTlsError,
445
534
  };
@@ -71,6 +71,7 @@ var { defineClass } = require("./framework-error");
71
71
  var lazyRequire = require("./lazy-require");
72
72
  var validateOpts = require("./validate-opts");
73
73
  var gateContract = require("./gate-contract");
74
+ var codepointClass = require("./codepoint-class");
74
75
 
75
76
  var audit = lazyRequire(function () { return require("./audit"); });
76
77
 
@@ -131,7 +132,7 @@ function create(opts) {
131
132
  throw new MailSpamScoreError("mail-spam-score/bad-scorer",
132
133
  "mail.spamScore.create.scorer must be a function; got " + (typeof opts.scorer));
133
134
  }
134
- var profile = opts.profile || (opts.posture && COMPLIANCE_POSTURES[opts.posture]) || DEFAULT_PROFILE;
135
+ var profile = gateContract.resolveProfileName(opts, COMPLIANCE_POSTURES, DEFAULT_PROFILE);
135
136
  if (!PROFILES[profile]) {
136
137
  throw new MailSpamScoreError("mail-spam-score/bad-profile",
137
138
  "mail.spamScore.create.profile: unknown '" + profile +
@@ -250,13 +251,11 @@ function _sanitizeReasons(reasons, caps) {
250
251
  // Refuse control bytes (CR / LF / NUL / etc.) — a compromised
251
252
  // scorer could try to smuggle CRLF into an outbound X-Spam-Status
252
253
  // header.
253
- for (var c = 0; c < r.length; c += 1) {
254
- var cc = r.charCodeAt(c);
255
- if (cc < 0x20 || cc === 0x7f) { // RFC 5234 CTL refusal range
256
- throw new MailSpamScoreError("mail-spam-score/control-byte",
257
- "mail.spamScore.score: reasons[" + i + "] contains control byte 0x" +
258
- cc.toString(16)); // hex radix
259
- }
254
+ var _ctlOff = codepointClass.firstControlCharOffset(r, { forbidTab: true });
255
+ if (_ctlOff !== -1) {
256
+ throw new MailSpamScoreError("mail-spam-score/control-byte",
257
+ "mail.spamScore.score: reasons[" + i + "] contains control byte 0x" +
258
+ r.charCodeAt(_ctlOff).toString(16)); // hex radix
260
259
  }
261
260
  out.push(r);
262
261
  }
@@ -61,6 +61,7 @@ var C = require("./constants");
61
61
  var bCrypto = require("./crypto");
62
62
  var cryptoField = require("./crypto-field");
63
63
  var vault = require("./vault");
64
+ var safeBuffer = require("./safe-buffer");
64
65
  var safeMime = require("./safe-mime");
65
66
  var safeSql = require("./safe-sql");
66
67
  var sql = require("./sql");
@@ -798,7 +799,7 @@ function _appendMessage(args) {
798
799
  "appendMessage: rawBytes must be Buffer or string");
799
800
  }
800
801
  var buf = Buffer.isBuffer(rawBytes) ? rawBytes : Buffer.from(rawBytes, "utf8");
801
- if (buf.length > args.maxMessageBytes) {
802
+ if (safeBuffer.byteLengthOf(buf) > args.maxMessageBytes) {
802
803
  throw new MailStoreError("mail-store/oversize-message",
803
804
  "appendMessage: " + buf.length + " bytes exceeds maxMessageBytes=" + args.maxMessageBytes);
804
805
  }
@@ -854,7 +855,7 @@ function _appendMessage(args) {
854
855
  var bodyText = textPart ? textPart.body : "";
855
856
  var bodyHtml = htmlPart && htmlPart.contentType === "text/html" ? htmlPart.body : "";
856
857
 
857
- if (bodyText.length > args.maxBodyBytes || bodyHtml.length > args.maxBodyBytes) {
858
+ if (safeBuffer.byteLengthOf(bodyText) > args.maxBodyBytes || safeBuffer.byteLengthOf(bodyHtml) > args.maxBodyBytes) {
858
859
  throw new MailStoreError("mail-store/oversize-body",
859
860
  "appendMessage: body exceeds maxBodyBytes=" + args.maxBodyBytes);
860
861
  }
@@ -57,6 +57,8 @@
57
57
  */
58
58
  var C = require("./constants");
59
59
  var bCrypto = require("./crypto");
60
+ var codepointClass = require("./codepoint-class");
61
+ var markupEscape = require("./markup-escape").markupEscape;
60
62
  var lazyRequire = require("./lazy-require");
61
63
  var safeBuffer = require("./safe-buffer");
62
64
  var guardDomain = require("./guard-domain");
@@ -388,11 +390,7 @@ function _renderPostalAddressHtml(addr) {
388
390
  }
389
391
 
390
392
  function _htmlEscape(s) {
391
- return String(s)
392
- .replace(/&/g, "&amp;")
393
- .replace(/</g, "&lt;")
394
- .replace(/>/g, "&gt;")
395
- .replace(/"/g, "&quot;");
393
+ return markupEscape(s);
396
394
  }
397
395
 
398
396
  function _hasUnsubscribe(message) {
@@ -1920,12 +1918,9 @@ function feedbackId(opts) {
1920
1918
  // Refuse CR/LF (header-injection) + control chars. Walk codepoints
1921
1919
  // manually because eslint's no-control-regex refuses control-char
1922
1920
  // ranges in regex literals regardless of escape form.
1923
- for (var ci = 0; ci < f.value.length; ci += 1) {
1924
- var code = f.value.charCodeAt(ci);
1925
- if (code < 32 || code === 127) { // C0 + DEL codepoint range
1926
- throw new MailError("mail/bad-feedback-id-field",
1927
- "feedbackId: " + f.key + " contains control characters");
1928
- }
1921
+ if (codepointClass.firstControlCharOffset(f.value, { forbidTab: true }) !== -1) { // C0 + DEL codepoint range
1922
+ throw new MailError("mail/bad-feedback-id-field",
1923
+ "feedbackId: " + f.key + " contains control characters");
1929
1924
  }
1930
1925
  parts.push(f.value);
1931
1926
  }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ // markup-escape — the shared XML/HTML text + attribute escaper used wherever
4
+ // the framework SERIALIZES a value into markup (mail report / DAV / autoconfig
5
+ // XML, the Azure blob XML API, and — once routed — the b.guardHtml / b.guardSvg
6
+ // sanitizer output). Distinct from markup-tokenizer (which LEXES markup for the
7
+ // sanitizers) and xml-c14n (which canonicalizes for XMLDSig with a different
8
+ // escape set, e.g. \r\n\t and NO ">").
9
+ //
10
+ // markupEscape(str, opts) escapes the four always-dangerous markup
11
+ // metacharacters — & < > " — to their entity forms, with "&" first so the
12
+ // entities it emits are not double-escaped. The one axis that genuinely varies
13
+ // across callers is the apostrophe, so it is a parameter:
14
+ // opts.apos omitted / falsy → "'" is left as-is (element content and
15
+ // double-quoted attributes don't require it escaped)
16
+ // opts.apos === "&#39;" → HTML numeric form
17
+ // opts.apos === "&apos;" → XML named form
18
+ // Input COERCION stays with the caller (some map null/undefined or any
19
+ // non-string to "" before serializing); markupEscape String()s defensively so
20
+ // a stray number/boolean still escapes rather than throwing.
21
+ function markupEscape(str, opts) {
22
+ var s = String(str)
23
+ .replace(/&/g, "&amp;")
24
+ .replace(/</g, "&lt;")
25
+ .replace(/>/g, "&gt;")
26
+ .replace(/"/g, "&quot;");
27
+ var apos = opts && opts.apos;
28
+ return apos ? s.replace(/'/g, apos) : s;
29
+ }
30
+
31
+ module.exports = { markupEscape: markupEscape };