@blamejs/blamejs-shop 0.5.12 → 0.5.14

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 (522) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/sales-tax-filings.js +143 -0
  4. package/lib/vendor/MANIFEST.json +632 -416
  5. package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
  6. package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
  7. package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
  8. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  9. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
  10. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
  11. package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
  12. package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
  13. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
  14. package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
  15. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
  16. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  17. package/lib/vendor/blamejs/.gitignore +2 -0
  18. package/lib/vendor/blamejs/CHANGELOG.md +122 -0
  19. package/lib/vendor/blamejs/NOTICE +26 -1
  20. package/lib/vendor/blamejs/SECURITY.md +1 -1
  21. package/lib/vendor/blamejs/api-snapshot.json +207 -5
  22. package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
  23. package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
  24. package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
  25. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
  26. package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
  27. package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
  28. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
  29. package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
  30. package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
  31. package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
  32. package/lib/vendor/blamejs/index.js +6 -0
  33. package/lib/vendor/blamejs/lib/a2a.js +4 -4
  34. package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
  35. package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
  36. package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
  37. package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
  38. package/lib/vendor/blamejs/lib/archive-read.js +8 -0
  39. package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
  40. package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
  41. package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
  42. package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
  43. package/lib/vendor/blamejs/lib/audit.js +71 -8
  44. package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
  45. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
  46. package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
  47. package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
  48. package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
  49. package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
  50. package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
  51. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
  52. package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
  53. package/lib/vendor/blamejs/lib/backup/index.js +16 -5
  54. package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
  55. package/lib/vendor/blamejs/lib/base32.js +21 -0
  56. package/lib/vendor/blamejs/lib/break-glass.js +19 -10
  57. package/lib/vendor/blamejs/lib/bundler.js +5 -1
  58. package/lib/vendor/blamejs/lib/cache-status.js +3 -7
  59. package/lib/vendor/blamejs/lib/calendar.js +21 -1
  60. package/lib/vendor/blamejs/lib/cbor.js +12 -1
  61. package/lib/vendor/blamejs/lib/cert.js +29 -11
  62. package/lib/vendor/blamejs/lib/cli.js +94 -24
  63. package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
  64. package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
  65. package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
  66. package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
  67. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
  68. package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
  69. package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
  70. package/lib/vendor/blamejs/lib/content-digest.js +2 -1
  71. package/lib/vendor/blamejs/lib/cookies.js +13 -3
  72. package/lib/vendor/blamejs/lib/cose.js +31 -16
  73. package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
  74. package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
  75. package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
  76. package/lib/vendor/blamejs/lib/crypto.js +314 -19
  77. package/lib/vendor/blamejs/lib/csp.js +11 -3
  78. package/lib/vendor/blamejs/lib/daemon.js +270 -24
  79. package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
  80. package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
  81. package/lib/vendor/blamejs/lib/db-query.js +34 -7
  82. package/lib/vendor/blamejs/lib/db.js +18 -6
  83. package/lib/vendor/blamejs/lib/dbsc.js +17 -0
  84. package/lib/vendor/blamejs/lib/dev.js +21 -2
  85. package/lib/vendor/blamejs/lib/dsr.js +157 -102
  86. package/lib/vendor/blamejs/lib/external-db.js +41 -2
  87. package/lib/vendor/blamejs/lib/file-upload.js +25 -7
  88. package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
  89. package/lib/vendor/blamejs/lib/forms.js +113 -27
  90. package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
  91. package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
  92. package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
  93. package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
  94. package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
  95. package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
  96. package/lib/vendor/blamejs/lib/guard-html.js +26 -53
  97. package/lib/vendor/blamejs/lib/guard-image.js +24 -5
  98. package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
  99. package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
  100. package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
  101. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
  102. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
  103. package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
  104. package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
  105. package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
  106. package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
  107. package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
  108. package/lib/vendor/blamejs/lib/guard-time.js +1 -1
  109. package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
  110. package/lib/vendor/blamejs/lib/html-balance.js +3 -3
  111. package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
  112. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
  113. package/lib/vendor/blamejs/lib/http-client.js +39 -7
  114. package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
  115. package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
  116. package/lib/vendor/blamejs/lib/i18n.js +35 -21
  117. package/lib/vendor/blamejs/lib/incident-report.js +8 -1
  118. package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
  119. package/lib/vendor/blamejs/lib/json-path.js +23 -1
  120. package/lib/vendor/blamejs/lib/jwk.js +20 -3
  121. package/lib/vendor/blamejs/lib/link-header.js +2 -1
  122. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
  123. package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
  124. package/lib/vendor/blamejs/lib/log-stream.js +8 -3
  125. package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
  126. package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
  127. package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
  128. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
  129. package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
  130. package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
  131. package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
  132. package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
  133. package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
  134. package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
  135. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
  136. package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
  137. package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
  138. package/lib/vendor/blamejs/lib/mail.js +15 -5
  139. package/lib/vendor/blamejs/lib/metrics.js +268 -63
  140. package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
  141. package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
  142. package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
  143. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
  144. package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
  145. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
  146. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
  147. package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
  148. package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
  149. package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
  150. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
  151. package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
  152. package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
  153. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
  154. package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
  155. package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
  156. package/lib/vendor/blamejs/lib/network-dns.js +21 -2
  157. package/lib/vendor/blamejs/lib/network-tls.js +69 -7
  158. package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
  159. package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
  160. package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
  161. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
  162. package/lib/vendor/blamejs/lib/outbox.js +1 -1
  163. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
  164. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
  165. package/lib/vendor/blamejs/lib/permissions.js +6 -3
  166. package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
  167. package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
  168. package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
  169. package/lib/vendor/blamejs/lib/pubsub.js +20 -9
  170. package/lib/vendor/blamejs/lib/queue-local.js +8 -1
  171. package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
  172. package/lib/vendor/blamejs/lib/redact.js +54 -0
  173. package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
  174. package/lib/vendor/blamejs/lib/restore.js +19 -0
  175. package/lib/vendor/blamejs/lib/retention.js +12 -4
  176. package/lib/vendor/blamejs/lib/router.js +60 -6
  177. package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
  178. package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
  179. package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
  180. package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
  181. package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
  182. package/lib/vendor/blamejs/lib/safe-object.js +80 -0
  183. package/lib/vendor/blamejs/lib/safe-path.js +52 -4
  184. package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
  185. package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
  186. package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
  187. package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
  188. package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
  189. package/lib/vendor/blamejs/lib/scheduler.js +8 -1
  190. package/lib/vendor/blamejs/lib/security-assert.js +6 -6
  191. package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
  192. package/lib/vendor/blamejs/lib/self-update.js +517 -87
  193. package/lib/vendor/blamejs/lib/server-timing.js +2 -4
  194. package/lib/vendor/blamejs/lib/session.js +34 -12
  195. package/lib/vendor/blamejs/lib/sql.js +15 -1
  196. package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
  197. package/lib/vendor/blamejs/lib/static.js +55 -13
  198. package/lib/vendor/blamejs/lib/storage.js +8 -2
  199. package/lib/vendor/blamejs/lib/subject.js +6 -1
  200. package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
  201. package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
  202. package/lib/vendor/blamejs/lib/tsa.js +34 -13
  203. package/lib/vendor/blamejs/lib/uri-template.js +8 -1
  204. package/lib/vendor/blamejs/lib/vault/index.js +13 -0
  205. package/lib/vendor/blamejs/lib/vc.js +44 -5
  206. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
  207. package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
  208. package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
  209. package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
  210. package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
  211. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
  212. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
  213. package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
  214. package/lib/vendor/blamejs/lib/watcher.js +89 -17
  215. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
  216. package/lib/vendor/blamejs/lib/webhook.js +12 -2
  217. package/lib/vendor/blamejs/lib/ws-client.js +32 -1
  218. package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
  219. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
  220. package/lib/vendor/blamejs/package-lock.json +2 -2
  221. package/lib/vendor/blamejs/package.json +1 -1
  222. package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
  223. package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
  224. package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
  225. package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
  226. package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
  227. package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
  228. package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
  229. package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
  230. package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
  231. package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
  232. package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
  233. package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
  234. package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
  235. package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
  236. package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
  237. package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
  238. package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
  239. package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
  240. package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
  241. package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
  242. package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
  243. package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
  244. package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
  245. package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
  246. package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
  247. package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
  248. package/lib/vendor/blamejs/socket.yml +94 -0
  249. package/lib/vendor/blamejs/test/00-primitives.js +605 -0
  250. package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
  251. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
  252. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
  253. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
  254. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
  255. package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
  256. package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
  257. package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
  258. package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
  259. package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
  260. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
  263. package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
  269. package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
  271. package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
  272. package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
  273. package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
  283. package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
  285. package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
  294. package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
  295. package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
  302. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
  303. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
  308. package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
  310. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
  312. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
  313. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
  314. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
  315. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
  316. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
  317. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
  318. package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
  319. package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
  320. package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
  321. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
  322. package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
  323. package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
  324. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
  325. package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
  326. package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
  327. package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
  328. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
  329. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
  330. package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
  331. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
  335. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
  336. package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
  337. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
  341. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
  342. package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
  344. package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
  346. package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
  347. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
  348. package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
  349. package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
  366. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
  377. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
  387. package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
  388. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
  389. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
  390. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
  391. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
  392. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
  393. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
  396. package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
  397. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
  398. package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
  399. package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
  400. package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
  401. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
  402. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
  403. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
  404. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
  405. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
  406. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
  407. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
  408. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
  409. package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
  410. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
  411. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
  412. package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
  413. package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
  414. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
  415. package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
  416. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
  417. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
  418. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
  419. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
  420. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
  421. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
  422. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
  423. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
  424. package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
  425. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
  426. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
  427. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
  428. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
  429. package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
  430. package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
  431. package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
  432. package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
  433. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
  434. package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
  435. package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
  436. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
  437. package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
  438. package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
  439. package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
  440. package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
  441. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
  442. package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
  443. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
  444. package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
  445. package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
  446. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
  447. package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
  448. package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
  449. package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
  450. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
  451. package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
  452. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
  453. package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
  454. package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
  455. package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
  456. package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
  457. package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
  458. package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
  459. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
  460. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
  461. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
  462. package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
  463. package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
  464. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
  465. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
  466. package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
  467. package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
  468. package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
  469. package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
  470. package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
  471. package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
  472. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
  473. package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
  474. package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
  475. package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
  476. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
  477. package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
  478. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
  479. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
  480. package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
  481. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
  482. package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
  483. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
  484. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
  485. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
  486. package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
  487. package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
  488. package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
  489. package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
  490. package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
  491. package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
  492. package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
  493. package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
  494. package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
  495. package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
  496. package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
  497. package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
  498. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
  499. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
  500. package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
  501. package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
  502. package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
  503. package/lib/vendor/blamejs/test/smoke.js +2 -0
  504. package/package.json +1 -1
  505. package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
  506. package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
  507. package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
  508. package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
  509. package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
  510. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
  511. package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
  512. package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
  513. package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
  514. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
  515. package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
  516. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
  517. package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
  518. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
  519. package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
  520. package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
  521. package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
  522. package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
@@ -6,7 +6,12 @@
6
6
  *
7
7
  * Tests cover opts validation, AUTH-required posture under strict
8
8
  * profile, AUTH-needs-TLS gate (RFC 4954 §4), identity-binding,
9
- * and the multi-step verify hook contract.
9
+ * and the multi-step verify hook contract. Error / defensive /
10
+ * adversarial branches are also driven over a real localhost listener:
11
+ * wrong-state and malformed-command refusals, AUTH failure modes and
12
+ * per-IP rate-limits, tenant scoping, STARTTLS / implicit-TLS postures,
13
+ * DKIM-required modes, recipient policy, size and line limits, DATA
14
+ * smuggling refusals, idle-timeout, and close() drain.
10
15
  */
11
16
 
12
17
  var helpers = require("../helpers");
@@ -369,6 +374,849 @@ async function testBdatOversizeRefused() {
369
374
  } finally { await srv.close({ timeoutMs: 1000 }); } // allow:raw-time-literal — test-only short drain
370
375
  }
371
376
 
377
+ var NUL = String.fromCharCode(0);
378
+ var LF = String.fromCharCode(10);
379
+ var CR = String.fromCharCode(13);
380
+
381
+ // ---- socket plumbing ----
382
+
383
+ function _readReply(socket) {
384
+ return new Promise(function (resolve, reject) {
385
+ var buf = "";
386
+ function onData(chunk) {
387
+ buf += chunk.toString("utf8");
388
+ // A complete SMTP reply always ends with CRLF; only then is its
389
+ // final line the terminal "NNN <text>" (a multiline reply's earlier
390
+ // lines are "NNN-<text>"). Requiring the trailing CRLF prevents
391
+ // resolving on a chunk boundary that happens to split mid-reply.
392
+ if (!/\r\n$/.test(buf)) return;
393
+ var lines = buf.split("\r\n").filter(Boolean);
394
+ var last = lines[lines.length - 1];
395
+ if (last && /^\d{3} /.test(last)) {
396
+ socket.removeListener("data", onData);
397
+ socket.removeListener("error", onErr);
398
+ resolve(buf);
399
+ }
400
+ }
401
+ function onErr(e) {
402
+ socket.removeListener("data", onData);
403
+ reject(e);
404
+ }
405
+ socket.on("data", onData);
406
+ socket.once("error", onErr);
407
+ });
408
+ }
409
+
410
+ function _send(socket, line) {
411
+ var p = _readReply(socket);
412
+ socket.write(line + "\r\n");
413
+ return p;
414
+ }
415
+
416
+ // Write raw bytes and read the next reply (for DATA-body payloads).
417
+ function _writeRaw(socket, bytes) {
418
+ var p = _readReply(socket);
419
+ socket.write(bytes);
420
+ return p;
421
+ }
422
+
423
+ // DATA command → 354 → dot-terminated body → final reply.
424
+ async function _dataDot(socket, body) {
425
+ await _send(socket, "DATA");
426
+ return _writeRaw(socket, body + "\r\n.\r\n");
427
+ }
428
+
429
+ async function _makeTestTlsContextWithCa() {
430
+ var ca = await b.mtlsEngine.generateCa({ name: "submission-wire-test-ca" });
431
+ var leaf = await b.mtlsEngine.signClientCert({
432
+ cn: "submission.test",
433
+ caCertPem: ca.caCertPem,
434
+ caKeyPem: ca.caKeyPem,
435
+ usage: "server",
436
+ sans: ["DNS:submission.test", "DNS:localhost", "IP:127.0.0.1"],
437
+ validityDays: 1,
438
+ });
439
+ return {
440
+ ctx: nodeTls.createSecureContext({ key: leaf.key, cert: leaf.cert }),
441
+ caPem: ca.caCertPem,
442
+ };
443
+ }
444
+
445
+ // Build + listen a submission server sharing the test TLS context.
446
+ async function _mk(tls, extra) {
447
+ var handoffs = [];
448
+ var opts = { tlsContext: tls.ctx };
449
+ if (extra) { Object.keys(extra).forEach(function (k) { opts[k] = extra[k]; }); }
450
+ var srv = b.mail.server.submission.create(opts);
451
+ var info = await srv.listen({ port: 0, address: "127.0.0.1" });
452
+ return { srv: srv, port: info.port, caPem: tls.caPem, handoffs: handoffs };
453
+ }
454
+
455
+ function _agentCapturing(handoffs, mode) {
456
+ return {
457
+ handoff: function (env) {
458
+ handoffs.push(env);
459
+ if (mode === "reject") return Promise.reject(new Error("upstream down"));
460
+ return Promise.resolve({ messageId: "<accepted@test>" });
461
+ },
462
+ };
463
+ }
464
+
465
+ function _connect(port) {
466
+ var socket = nodeNet.connect(port, "127.0.0.1");
467
+ socket.on("error", function () { /* swallow ECONNRESET on close */ });
468
+ return new Promise(function (resolve, reject) {
469
+ socket.once("connect", function () { resolve(socket); });
470
+ socket.once("error", reject);
471
+ });
472
+ }
473
+
474
+ async function _tlsUpgrade(rawSocket, caPem) {
475
+ var tls = nodeTls.connect({ socket: rawSocket, ca: caPem, servername: "localhost" });
476
+ tls.on("error", function () {});
477
+ await new Promise(function (r, j) { tls.once("secureConnect", r); tls.once("error", j); });
478
+ return tls;
479
+ }
480
+
481
+ // SASL PLAIN blob (authzid NUL authcid NUL passwd), base64.
482
+ function _saslPlain(user, pass) {
483
+ return Buffer.from(["", user, pass].join(NUL), "utf8").toString("base64");
484
+ }
485
+
486
+ // ---- create() defensive branches ----
487
+
488
+ function testCreateValidation(tls) {
489
+ function expect(label, opts, code) {
490
+ var threw = null;
491
+ try { b.mail.server.submission.create(opts); } catch (e) { threw = e; }
492
+ check(label, threw && threw.code === code);
493
+ }
494
+ // Non-object opts.
495
+ var threwObj = null;
496
+ try { b.mail.server.submission.create(null); } catch (e) { threwObj = e; }
497
+ check("null opts refused", threwObj && (threwObj.code || "").indexOf("mail-server-submission/") === 0);
498
+
499
+ // Missing tlsContext.
500
+ var threwTls = null;
501
+ try { b.mail.server.submission.create({ profile: "permissive" }); } catch (e) { threwTls = e; }
502
+ check("missing tlsContext refused", threwTls && threwTls.code === "mail-server-submission/no-tls-context");
503
+ // Strict profile requires auth.
504
+ expect("strict profile without auth refused",
505
+ { tlsContext: tls.ctx }, "mail-server-submission/no-auth");
506
+ // Bad auth.verify + bad mechanisms.
507
+ expect("non-function auth.verify refused",
508
+ { tlsContext: tls.ctx, auth: { verify: "nope" } }, "mail-server-submission/bad-auth");
509
+ expect("empty auth.mechanisms refused",
510
+ { tlsContext: tls.ctx, auth: { verify: function () {}, mechanisms: [] } }, "mail-server-submission/bad-auth");
511
+ // Bad numeric bound.
512
+ var threwBound = null;
513
+ try { b.mail.server.submission.create({ tlsContext: tls.ctx, profile: "permissive", maxLineBytes: -1 }); } catch (e) { threwBound = e; }
514
+ check("negative maxLineBytes refused", threwBound && (threwBound.code || "").indexOf("mail-server-submission/") === 0);
515
+
516
+ expect("bad tenantScope (no check fn) refused",
517
+ { tlsContext: tls.ctx, profile: "permissive", tenantScope: {}, agentTenantId: "t1" },
518
+ "mail-server-submission/bad-tenant-scope");
519
+ expect("tenantScope without agentTenantId refused",
520
+ { tlsContext: tls.ctx, profile: "permissive", tenantScope: { check: function () {} } },
521
+ "mail-server-submission/no-agent-tenant-id");
522
+ expect("bad dkimRequireMode refused",
523
+ { tlsContext: tls.ctx, profile: "permissive", dkimRequireMode: "sometimes" },
524
+ "mail-server-submission/bad-dkim-require-mode");
525
+
526
+ // guardDomain:false + guardDomain object both accepted at create.
527
+ var okA = null, okB = null;
528
+ try { b.mail.server.submission.create({ tlsContext: tls.ctx, profile: "permissive", guardDomain: false }); } catch (e) { okA = e; }
529
+ try { b.mail.server.submission.create({ tlsContext: tls.ctx, profile: "permissive", guardDomain: { profile: "strict" } }); } catch (e) { okB = e; }
530
+ check("guardDomain:false accepted", okA === null);
531
+ check("guardDomain object accepted", okB === null);
532
+ }
533
+
534
+ async function testCloseBeforeListen(tls) {
535
+ var srv = b.mail.server.submission.create({ tlsContext: tls.ctx, profile: "permissive" });
536
+ var threw = null;
537
+ try { await srv.close(); } catch (e) { threw = e; }
538
+ check("close() before listen() is a no-op", threw === null);
539
+ check("connectionCount is 0 before listen", srv.connectionCount() === 0);
540
+ check("_portForTest is null before listen", srv._portForTest() === null);
541
+ }
542
+
543
+ async function testDoubleListen(tls) {
544
+ var srv = b.mail.server.submission.create({ tlsContext: tls.ctx, profile: "permissive" });
545
+ await srv.listen({ port: 0, address: "127.0.0.1" });
546
+ try {
547
+ check("_portForTest returns a bound port", typeof srv._portForTest() === "number" && srv._portForTest() > 0);
548
+ var threw = null;
549
+ try { await srv.listen({ port: 0, address: "127.0.0.1" }); } catch (e) { threw = e; }
550
+ check("double listen() refused (already-listening)",
551
+ threw && (threw.code || "").indexOf("mail-server-submission/") === 0);
552
+ } finally { await srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
553
+ }
554
+
555
+ // ---- permissive dispatch + wrong-state + malformed refusals ----
556
+
557
+ async function testPermissiveDispatch(tls) {
558
+ var s = await _mk(tls, { profile: "permissive" });
559
+ var sock = await _connect(s.port);
560
+ try {
561
+ check("greeting is 220", /^220 /.test(await _readReply(sock)));
562
+
563
+ // Wrong-state before EHLO.
564
+ check("MAIL before EHLO → 503", /^503 /.test(await _send(sock, "MAIL FROM:<a@example.com>")));
565
+ check("RCPT before MAIL → 503", /^503 /.test(await _send(sock, "RCPT TO:<b@example.com>")));
566
+ check("DATA before RCPT → 503", /^503 /.test(await _send(sock, "DATA")));
567
+ check("BDAT before MAIL → 503", /^5\d\d /.test(await _send(sock, "BDAT 3 LAST")));
568
+
569
+ // HELO single-line reply branch.
570
+ check("HELO replies single 250", /^250 /.test(await _send(sock, "HELO client.example.com")));
571
+ // EHLO multiline with STARTTLS advertised (plaintext port).
572
+ var ehlo = await _send(sock, "EHLO client.example.com");
573
+ check("EHLO advertises PIPELINING", /250[ -]PIPELINING/.test(ehlo));
574
+ check("EHLO advertises STARTTLS (plaintext port)", /250[ -]STARTTLS/.test(ehlo));
575
+ check("EHLO advertises CHUNKING", /250[ -]CHUNKING/.test(ehlo));
576
+
577
+ // Simple verbs.
578
+ check("NOOP → 250", /^250 /.test(await _send(sock, "NOOP")));
579
+ check("VRFY → 502", /^502 /.test(await _send(sock, "VRFY alice")));
580
+ check("EXPN → 502", /^502 /.test(await _send(sock, "EXPN list")));
581
+ // Unknown verb passes guardSmtpCommand under permissive → switch default 500.
582
+ check("unknown verb → 500", /^500 /.test(await _send(sock, "FLOOP arg")));
583
+ // HELP is a guardSmtpCommand-known verb with no submission handler →
584
+ // reaches the switch default (500 Unknown command).
585
+ check("HELP → 500 (no handler)", /^500 /.test(await _send(sock, "HELP")));
586
+
587
+ // Control-char / NUL / bare-LF / bare-CR refusals (guardSmtpCommand → 500).
588
+ check("bare-LF in command → 500", /^500 /.test(await _writeRaw(sock, "NOOP" + LF + "X\r\n")));
589
+ check("bare-CR in command → 500", /^500 /.test(await _writeRaw(sock, "NOOP" + CR + "X\r\n")));
590
+ check("NUL in command → 500", /^500 /.test(await _writeRaw(sock, "NOOP" + NUL + "X\r\n")));
591
+
592
+ // RSET resets, QUIT closes.
593
+ check("RSET → 250", /^250 /.test(await _send(sock, "RSET")));
594
+ check("QUIT → 221", /^221 /.test(await _send(sock, "QUIT")));
595
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
596
+ }
597
+
598
+ // ---- domain hardening refusals (HELO / MAIL FROM / RCPT TO) ----
599
+
600
+ async function testDomainRefusals(tls) {
601
+ var s = await _mk(tls, { profile: "permissive", guardDomain: { profile: "strict" } });
602
+ var sock = await _connect(s.port);
603
+ try {
604
+ await _readReply(sock);
605
+ // Bare-IPv4 domain refused (CVE-2021-22931 class) at HELO.
606
+ check("EHLO bare-IP domain → 501", /^501 /.test(await _send(sock, "EHLO 10.0.0.1")));
607
+ // Valid EHLO to advance.
608
+ check("EHLO valid domain → 250", /^250[ -]/.test(await _send(sock, "EHLO client.example.com")));
609
+ // MAIL FROM with bare-IP domain refused.
610
+ check("MAIL FROM bare-IP domain → 501", /^501 /.test(await _send(sock, "MAIL FROM:<a@10.0.0.1>")));
611
+ // Valid MAIL FROM.
612
+ check("MAIL FROM valid → 250", /^250 /.test(await _send(sock, "MAIL FROM:<a@example.com>")));
613
+ // RCPT TO with bare-IP domain refused.
614
+ check("RCPT TO bare-IP domain → 501", /^501 /.test(await _send(sock, "RCPT TO:<b@127.0.0.1>")));
615
+ check("RCPT TO valid → 250", /^250 /.test(await _send(sock, "RCPT TO:<b@example.com>")));
616
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
617
+ }
618
+
619
+ // ---- DATA path (audit-only + agent handoff success + agent reject) ----
620
+
621
+ async function testDataPaths(tls) {
622
+ // Audit-only (no agent), permissive.
623
+ var s1 = await _mk(tls, { profile: "permissive" });
624
+ var sock = await _connect(s1.port);
625
+ try {
626
+ await _readReply(sock);
627
+ await _send(sock, "EHLO client.example.com");
628
+ await _send(sock, "MAIL FROM:<a@example.com>");
629
+ await _send(sock, "RCPT TO:<b@example.com>");
630
+ var body = "From: a@example.com\r\nTo: b@example.com\r\nSubject: hi\r\n\r\nHello.";
631
+ check("DATA audit-only → 250", /^250 /.test(await _dataDot(sock, body)));
632
+ } finally { sock.destroy(); await s1.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
633
+
634
+ // Agent handoff resolves → outbound_routed 250.
635
+ var h2 = [];
636
+ var s2 = await _mk(tls, { profile: "permissive", agent: _agentCapturing(h2, "accept") });
637
+ var sock2 = await _connect(s2.port);
638
+ try {
639
+ await _readReply(sock2);
640
+ await _send(sock2, "EHLO client.example.com");
641
+ await _send(sock2, "MAIL FROM:<a@example.com>");
642
+ await _send(sock2, "RCPT TO:<b@example.com>");
643
+ var reply = await _dataDot(sock2, "From: a@example.com\r\n\r\nbody");
644
+ check("agent handoff accepted → 250 with id", /^250 .*accepted/.test(reply));
645
+ check("agent received one handoff", h2.length === 1);
646
+ check("handoff direction outbound", h2[0] && h2[0].direction === "outbound");
647
+ } finally { sock2.destroy(); await s2.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
648
+
649
+ // Agent handoff resolves without a messageId → 250 without id suffix.
650
+ var hEmpty = [];
651
+ var sEmpty = await _mk(tls, {
652
+ profile: "permissive",
653
+ agent: { handoff: function (env) { hEmpty.push(env); return Promise.resolve({}); } },
654
+ });
655
+ var sockE = await _connect(sEmpty.port);
656
+ try {
657
+ await _readReply(sockE);
658
+ await _send(sockE, "EHLO client.example.com");
659
+ await _send(sockE, "MAIL FROM:<a@example.com>");
660
+ await _send(sockE, "RCPT TO:<b@example.com>");
661
+ check("agent ack without messageId → 250", /^250 /.test(await _dataDot(sockE, "From: a@example.com\r\n\r\nx")));
662
+ } finally { sockE.destroy(); await sEmpty.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
663
+
664
+ // Agent handoff rejects → 451.
665
+ var h3 = [];
666
+ var s3 = await _mk(tls, { profile: "permissive", agent: _agentCapturing(h3, "reject") });
667
+ var sock3 = await _connect(s3.port);
668
+ try {
669
+ await _readReply(sock3);
670
+ await _send(sock3, "EHLO client.example.com");
671
+ await _send(sock3, "MAIL FROM:<a@example.com>");
672
+ await _send(sock3, "RCPT TO:<b@example.com>");
673
+ check("agent handoff rejected → 451", /^451 /.test(await _dataDot(sock3, "From: a@example.com\r\n\r\nx")));
674
+ } finally { sock3.destroy(); await s3.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
675
+ }
676
+
677
+ // ---- BDAT extra branches (0-not-last ack, cumulative cap, DATA-before-RCPT) ----
678
+
679
+ async function testBdatBranches(tls) {
680
+ var h = [];
681
+ var s = await _mk(tls, { profile: "permissive", agent: _agentCapturing(h, "accept") });
682
+ var sock = await _connect(s.port);
683
+ try {
684
+ await _readReply(sock);
685
+ await _send(sock, "EHLO client.example.com");
686
+ await _send(sock, "MAIL FROM:<a@example.com>");
687
+ // BDAT with zero recipients → 503.
688
+ check("BDAT with no rcpts → 503", /^503 /.test(await _send(sock, "BDAT 3 LAST")));
689
+ await _send(sock, "RCPT TO:<b@example.com>");
690
+ // Zero-byte non-last chunk → 250 "0 octets received".
691
+ check("BDAT 0 (not last) → 250 0 octets", /^250 .*0 octets/.test(await _send(sock, "BDAT 0")));
692
+ // A real chunk then LAST.
693
+ var part = "From: a@example.com\r\n\r\npayload";
694
+ var pbuf = Buffer.from(part, "utf8");
695
+ var r = _readReply(sock);
696
+ sock.write("BDAT " + pbuf.length + " LAST\r\n");
697
+ sock.write(pbuf);
698
+ check("BDAT LAST finalizes → 250", /^250 /.test(await r));
699
+ await helpers.waitUntil(function () { return h.length >= 1; },
700
+ { timeoutMs: 5000, label: "submission BDAT: agent handoff received after BDAT LAST" });
701
+ check("agent got BDAT body", h.length === 1 && h[0].body.toString("utf8") === part);
702
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
703
+ }
704
+
705
+ // ---- cleartext AUTH accepted + identity binding (strict) ----
706
+
707
+ async function testCleartextAuthAndIdentity(tls) {
708
+ var s = await _mk(tls, {
709
+ profile: "permissive",
710
+ identityBinding: "strict",
711
+ auth: {
712
+ mechanisms: ["PLAIN", "LOGIN"],
713
+ verify: function (mech, creds) {
714
+ var parts = Buffer.from(creds.clientResponse || "", "base64").toString("utf8").split(NUL);
715
+ var user = parts[1];
716
+ if (user === "empty") return Promise.resolve({ ok: true, actor: { id: "empty@example.com" } });
717
+ // "solo" carries a single-mailbox STRING (not the array form).
718
+ if (user === "solo") return Promise.resolve({ ok: true, actor: { id: "solo@example.com", mailbox: "solo@example.com" } });
719
+ return Promise.resolve({ ok: true, actor: { id: user + "@example.com", mailboxes: ["ok@example.com"] } });
720
+ },
721
+ },
722
+ });
723
+
724
+ // Actor with a mailbox set.
725
+ var sock = await _connect(s.port);
726
+ try {
727
+ await _readReply(sock);
728
+ await _send(sock, "EHLO client.example.com");
729
+ check("cleartext AUTH PLAIN accepted → 235",
730
+ /^235 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("ok", "pw"))));
731
+ check("AUTH again after success → 503",
732
+ /^503 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("ok", "pw"))));
733
+ // Identity binding: not in set → 553.
734
+ check("MAIL FROM not in actor set → 553",
735
+ /^553 /.test(await _send(sock, "MAIL FROM:<evil@example.com>")));
736
+ check("RSET → 250", /^250 /.test(await _send(sock, "RSET")));
737
+ // In set → 250.
738
+ check("MAIL FROM in actor set → 250",
739
+ /^250 /.test(await _send(sock, "MAIL FROM:<ok@example.com>")));
740
+ } finally { sock.destroy(); }
741
+
742
+ // Actor with NO mailboxes → every MAIL FROM refused.
743
+ var sock2 = await _connect(s.port);
744
+ try {
745
+ await _readReply(sock2);
746
+ await _send(sock2, "EHLO client.example.com");
747
+ await _send(sock2, "AUTH PLAIN " + _saslPlain("empty", "pw"));
748
+ check("MAIL FROM with no-mailbox actor → 553",
749
+ /^553 /.test(await _send(sock2, "MAIL FROM:<whatever@example.com>")));
750
+ } finally { sock2.destroy(); }
751
+
752
+ // Actor whose mailbox set is the single-string form.
753
+ var sock3 = await _connect(s.port);
754
+ try {
755
+ await _readReply(sock3);
756
+ await _send(sock3, "EHLO client.example.com");
757
+ await _send(sock3, "AUTH PLAIN " + _saslPlain("solo", "pw"));
758
+ check("MAIL FROM matching string-mailbox actor → 250",
759
+ /^250 /.test(await _send(sock3, "MAIL FROM:<solo@example.com>")));
760
+ } finally { sock3.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
761
+ }
762
+
763
+ // ---- AUTH failures: mech-not-advertised, verify-fail, verify-throw, multi-step ----
764
+
765
+ async function testAuthFailuresAndMultiStep(tls) {
766
+ var s = await _mk(tls, {
767
+ profile: "permissive",
768
+ auth: {
769
+ mechanisms: ["PLAIN", "LOGIN"],
770
+ verify: function (mech, creds) {
771
+ if (mech === "LOGIN") {
772
+ if (creds.step === 0) return Promise.resolve({ pending: true, challenge: Buffer.from("Username:", "utf8").toString("base64") });
773
+ return Promise.resolve({ ok: true, actor: { id: "u@example.com" } });
774
+ }
775
+ if (mech === "PLAIN") {
776
+ var parts = Buffer.from(creds.clientResponse || "", "base64").toString("utf8").split(NUL);
777
+ if (parts[2] === "boom") return Promise.reject(new Error("backend exploded"));
778
+ if (parts[2] === "good") return Promise.resolve({ ok: true, actor: { id: parts[1] } });
779
+ return Promise.resolve({ ok: false, reason: "bad-password" });
780
+ }
781
+ return Promise.resolve({ ok: false });
782
+ },
783
+ },
784
+ });
785
+ var sock = await _connect(s.port);
786
+ try {
787
+ await _readReply(sock);
788
+ await _send(sock, "EHLO client.example.com");
789
+ // Mechanism not advertised → 535.
790
+ check("AUTH unadvertised mech → 535", /^535 /.test(await _send(sock, "AUTH CRAM-MD5 abcd")));
791
+ // verify returns { ok:false } → 535.
792
+ check("AUTH verify-fail → 535", /^535 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("u", "nope"))));
793
+ // verify throws → 535.
794
+ check("AUTH verify-throw → 535", /^535 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("u", "boom"))));
795
+ // Multi-step LOGIN: 334 challenge then 235.
796
+ check("AUTH LOGIN issues 334 challenge", /^334 /.test(await _send(sock, "AUTH LOGIN")));
797
+ check("AUTH LOGIN completes → 235",
798
+ /^235 /.test(await _send(sock, Buffer.from("user", "utf8").toString("base64"))));
799
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
800
+ }
801
+
802
+ // ---- AUTH-failure per-IP rate-limit (421 + close) ----
803
+
804
+ async function testAuthRateLimit(tls) {
805
+ var s = await _mk(tls, {
806
+ profile: "permissive",
807
+ rateLimit: { authFailuresPerIpPer15Min: 1 },
808
+ auth: {
809
+ mechanisms: ["PLAIN"],
810
+ verify: function () { return Promise.resolve({ ok: false, reason: "always-fail" }); },
811
+ },
812
+ });
813
+ var sock = await _connect(s.port);
814
+ try {
815
+ await _readReply(sock);
816
+ await _send(sock, "EHLO client.example.com");
817
+ check("first AUTH fails → 535", /^535 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("u", "x"))));
818
+ // Second attempt trips the per-IP budget → 421 + close.
819
+ check("AUTH over budget → 421", /^421 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("u", "y"))));
820
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
821
+ }
822
+
823
+ // ---- cross-tenant refusal ----
824
+
825
+ async function testCrossTenant(tls) {
826
+ var tenantScope = {
827
+ check: function (actor, tid) {
828
+ if (!actor || actor.tenantId !== tid) {
829
+ var e = new Error("cross-tenant"); e.code = "tenant/mismatch"; throw e;
830
+ }
831
+ },
832
+ };
833
+ var s = await _mk(tls, {
834
+ profile: "permissive",
835
+ tenantScope: tenantScope,
836
+ agentTenantId: "t1",
837
+ auth: {
838
+ mechanisms: ["PLAIN"],
839
+ verify: function (mech, creds) {
840
+ var parts = Buffer.from(creds.clientResponse || "", "base64").toString("utf8").split(NUL);
841
+ return Promise.resolve({ ok: true, actor: { id: parts[1], tenantId: parts[1] === "right" ? "t1" : "t2" } });
842
+ },
843
+ },
844
+ });
845
+ var sock = await _connect(s.port);
846
+ try {
847
+ await _readReply(sock);
848
+ await _send(sock, "EHLO client.example.com");
849
+ check("wrong tenant → 535 cross-tenant",
850
+ /^535 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("wrong", "x"))));
851
+ } finally { sock.destroy(); }
852
+
853
+ var sock2 = await _connect(s.port);
854
+ try {
855
+ await _readReply(sock2);
856
+ await _send(sock2, "EHLO client.example.com");
857
+ check("right tenant → 235",
858
+ /^235 /.test(await _send(sock2, "AUTH PLAIN " + _saslPlain("right", "x"))));
859
+ } finally { sock2.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
860
+ }
861
+
862
+ // ---- strict profile: pre-TLS refusals, STARTTLS upgrade, DKIM-required ----
863
+
864
+ async function testStrictProfileStartTls(tls) {
865
+ var s = await _mk(tls, {
866
+ profile: "strict",
867
+ auth: {
868
+ mechanisms: ["PLAIN", "LOGIN"],
869
+ verify: function (mech, creds) {
870
+ var parts = Buffer.from(creds.clientResponse || "", "base64").toString("utf8").split(NUL);
871
+ return Promise.resolve({ ok: true, actor: { id: (parts[1] || "u") + "@example.com", mailboxes: ["ok@example.com"] } });
872
+ },
873
+ },
874
+ });
875
+ var raw = await _connect(s.port);
876
+ try {
877
+ await _readReply(raw);
878
+ var ehlo = await _send(raw, "EHLO client.example.com");
879
+ check("strict EHLO advertises STARTTLS", /250[ -]STARTTLS/.test(ehlo));
880
+ check("strict EHLO hides AUTH pre-TLS", !/AUTH /.test(ehlo));
881
+ check("AUTH before STARTTLS → 538", /^538 /.test(await _send(raw, "AUTH PLAIN " + _saslPlain("ok", "x"))));
882
+ check("MAIL before STARTTLS → 530", /^530 /.test(await _send(raw, "MAIL FROM:<ok@example.com>")));
883
+ check("STARTTLS → 220", /^220 /.test(await _send(raw, "STARTTLS")));
884
+
885
+ var tsock = await _tlsUpgrade(raw, s.caPem);
886
+ var ehlo2 = await _send(tsock, "EHLO client.example.com");
887
+ check("post-TLS EHLO advertises AUTH", /AUTH /.test(ehlo2));
888
+ check("post-TLS EHLO hides STARTTLS", !/250[ -]STARTTLS/.test(ehlo2));
889
+ check("STARTTLS after upgrade → 503", /^503 /.test(await _send(tsock, "STARTTLS")));
890
+ // Over TLS but not yet authenticated → strict profile still requires AUTH.
891
+ check("MAIL over TLS pre-AUTH (strict) → 530", /^530 /.test(await _send(tsock, "MAIL FROM:<ok@example.com>")));
892
+ check("AUTH over TLS succeeds → 235", /^235 /.test(await _send(tsock, "AUTH PLAIN " + _saslPlain("ok", "x"))));
893
+ // Identity binding (strict default): not-in-set 553, then in-set OK.
894
+ check("MAIL not-in-set over TLS → 553", /^553 /.test(await _send(tsock, "MAIL FROM:<evil@example.com>")));
895
+ await _send(tsock, "RSET");
896
+ check("MAIL in-set over TLS → 250", /^250 /.test(await _send(tsock, "MAIL FROM:<ok@example.com>")));
897
+ check("RCPT over TLS → 250", /^250 /.test(await _send(tsock, "RCPT TO:<b@example.com>")));
898
+ // strict requireDkim default true + no DKIM-Signature → 550.
899
+ check("DATA without DKIM (strict) → 550", /^550 /.test(await _dataDot(tsock, "From: ok@example.com\r\n\r\nno dkim here")));
900
+ tsock.destroy();
901
+ } finally { raw.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
902
+ }
903
+
904
+ // ---- implicit-TLS ----
905
+
906
+ async function testImplicitTls(tls) {
907
+ var s = await _mk(tls, { profile: "permissive", implicitTls: true });
908
+ var raw = await _connect(s.port);
909
+ var tsock = null;
910
+ try {
911
+ tsock = await _tlsUpgrade(raw, s.caPem);
912
+ check("implicit-TLS greeting is 220", /^220 /.test(await _readReply(tsock)));
913
+ var ehlo = await _send(tsock, "EHLO client.example.com");
914
+ check("implicit-TLS EHLO hides STARTTLS", !/250[ -]STARTTLS/.test(ehlo));
915
+ // On implicit-TLS, state.tls is already true, so STARTTLS is refused as
916
+ // "already active" (503) — the RFC 8314 502 branch is unreachable here.
917
+ // Either way STARTTLS is correctly refused.
918
+ check("STARTTLS on implicit-TLS refused (5xx)", /^5\d\d /.test(await _send(tsock, "STARTTLS")));
919
+ check("MAIL FROM over implicit-TLS → 250", /^250 /.test(await _send(tsock, "MAIL FROM:<a@example.com>")));
920
+ check("RCPT over implicit-TLS → 250", /^250 /.test(await _send(tsock, "RCPT TO:<b@example.com>")));
921
+ check("DATA over implicit-TLS → 250", /^250 /.test(await _dataDot(tsock, "From: a@example.com\r\n\r\nx")));
922
+ } finally { if (tsock) tsock.destroy(); raw.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
923
+ }
924
+
925
+ // ---- DKIM-required modes (any / self / mismatch / no header block) ----
926
+
927
+ async function _dkimTxn(port, body) {
928
+ var sock = await _connect(port);
929
+ await _readReply(sock);
930
+ await _send(sock, "EHLO client.example.com");
931
+ await _send(sock, "MAIL FROM:<a@example.com>");
932
+ await _send(sock, "RCPT TO:<b@example.com>");
933
+ var reply = await _dataDot(sock, body);
934
+ sock.destroy();
935
+ return reply;
936
+ }
937
+
938
+ async function testDkimModes(tls) {
939
+ // any: present → ok, absent → 550.
940
+ var sAny = await _mk(tls, { profile: "permissive", requireDkim: true, dkimRequireMode: "any" });
941
+ try {
942
+ check("dkim any: signature present → 250",
943
+ /^250 /.test(await _dkimTxn(sAny.port, "DKIM-Signature: v=1; d=example.com; b=zzz\r\nFrom: a@example.com\r\n\r\nbody")));
944
+ check("dkim any: no signature → 550",
945
+ /^550 /.test(await _dkimTxn(sAny.port, "From: a@example.com\r\n\r\nbody")));
946
+ // header block with no blank line (headerEnd === -1) still finds the sig.
947
+ check("dkim any: no header/body split still finds sig → 250",
948
+ /^250 /.test(await _dkimTxn(sAny.port, "DKIM-Signature: v=1; d=example.com; b=zzz")));
949
+ // Folded DKIM-Signature (continuation line begins with SP) is unfolded.
950
+ check("dkim any: folded signature accepted → 250",
951
+ /^250 /.test(await _dkimTxn(sAny.port, "DKIM-Signature: v=1;\r\n d=example.com;\r\n b=zzz\r\nFrom: a@example.com\r\n\r\nbody")));
952
+ } finally { await sAny.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
953
+
954
+ // self: d= must match envelope-sender domain (no auth → falls back to MAIL FROM domain).
955
+ var sSelf = await _mk(tls, { profile: "permissive", requireDkim: true, dkimRequireMode: "self" });
956
+ try {
957
+ check("dkim self: matching d= → 250",
958
+ /^250 /.test(await _dkimTxn(sSelf.port, "DKIM-Signature: v=1; d=example.com; b=zzz\r\nFrom: a@example.com\r\n\r\nbody")));
959
+ check("dkim self: mismatched d= → 550",
960
+ /^550 /.test(await _dkimTxn(sSelf.port, "DKIM-Signature: v=1; d=other.org; b=zzz\r\nFrom: a@example.com\r\n\r\nbody")));
961
+ } finally { await sSelf.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
962
+
963
+ // off: requireDkim forced false → DATA without sig accepted.
964
+ var sOff = await _mk(tls, { profile: "permissive", requireDkim: true, dkimRequireMode: "off" });
965
+ try {
966
+ check("dkim off: no signature accepted → 250",
967
+ /^250 /.test(await _dkimTxn(sOff.port, "From: a@example.com\r\n\r\nbody")));
968
+ } finally { await sOff.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
969
+ }
970
+
971
+ // ---- recipientPolicy accept / refuse / throw + rcpt cap ----
972
+
973
+ async function testRecipientPolicy(tls) {
974
+ var s = await _mk(tls, {
975
+ profile: "permissive",
976
+ maxRcptsPerMessage: 2,
977
+ recipientPolicy: function (ctx) {
978
+ if (ctx.rcptTo.indexOf("throw@") === 0) return Promise.reject(new Error("policy engine down"));
979
+ if (ctx.rcptTo.indexOf("deny@") === 0) return Promise.resolve({ ok: false, reason: "on deny list" });
980
+ return Promise.resolve({ ok: true });
981
+ },
982
+ });
983
+ var sock = await _connect(s.port);
984
+ try {
985
+ await _readReply(sock);
986
+ await _send(sock, "EHLO client.example.com");
987
+ await _send(sock, "MAIL FROM:<a@example.com>");
988
+ check("recipientPolicy accept → 250", /^250 /.test(await _send(sock, "RCPT TO:<ok@example.com>")));
989
+ check("recipientPolicy refuse → 550", /^550 /.test(await _send(sock, "RCPT TO:<deny@example.com>")));
990
+ check("recipientPolicy throw → 451", /^451 /.test(await _send(sock, "RCPT TO:<throw@example.com>")));
991
+ // Second accepted recipient reaches the cap (2); a third → 452.
992
+ check("second accepted rcpt → 250", /^250 /.test(await _send(sock, "RCPT TO:<ok2@example.com>")));
993
+ check("rcpt over cap → 452", /^452 /.test(await _send(sock, "RCPT TO:<ok3@example.com>")));
994
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
995
+ }
996
+
997
+ // ---- concurrent-connection rate-limit ----
998
+
999
+ async function testConnRateLimit(tls) {
1000
+ var s = await _mk(tls, { profile: "permissive", rateLimit: { maxConcurrentConnectionsPerIp: 1 } });
1001
+ var first = await _connect(s.port);
1002
+ try {
1003
+ check("first connection greeted 220", /^220 /.test(await _readReply(first)));
1004
+ var second = await _connect(s.port);
1005
+ check("second connection from same IP → 421", /^421 /.test(await _readReply(second)));
1006
+ second.destroy();
1007
+ } finally { first.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1008
+ }
1009
+
1010
+ // ---- line-too-long, body-too-large, DATA smuggling, SIZE-exceeds ----
1011
+
1012
+ async function testLimitsAndSmuggling(tls) {
1013
+ // Line too long: cap is maxLineBytes*4.
1014
+ var sLine = await _mk(tls, { profile: "permissive", maxLineBytes: b.constants.BYTES.bytes(16) });
1015
+ var lsock = await _connect(sLine.port);
1016
+ try {
1017
+ await _readReply(lsock);
1018
+ var longLine = "NOOP " + new Array(200).join("A"); // ~204 bytes > 16*4
1019
+ check("overlong command line → 500", /^500 /.test(await _send(lsock, longLine)));
1020
+ } finally { lsock.destroy(); await sLine.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1021
+
1022
+ // Body too large + SIZE-declared refusal + smuggling, tight maxMessageBytes.
1023
+ var sBody = await _mk(tls, { profile: "permissive", maxMessageBytes: b.constants.BYTES.kib(1) });
1024
+ var bsock = await _connect(sBody.port);
1025
+ try {
1026
+ await _readReply(bsock);
1027
+ await _send(bsock, "EHLO client.example.com");
1028
+ // SIZE param exceeds fixed maximum → 552.
1029
+ check("MAIL FROM SIZE over max → 552",
1030
+ /^552 /.test(await _send(bsock, "MAIL FROM:<a@example.com> SIZE=999999")));
1031
+ await _send(bsock, "MAIL FROM:<a@example.com>");
1032
+ await _send(bsock, "RCPT TO:<b@example.com>");
1033
+ // Over-cap DATA body → 552.
1034
+ var big = new Array(2100).join("A"); // ~2099 bytes > 1 KiB
1035
+ check("DATA body over max → 552", /^552 /.test(await _dataDot(bsock, big)));
1036
+ } finally { bsock.destroy(); await sBody.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1037
+
1038
+ // DATA-body bare-LF-dot smuggling → 554.
1039
+ var sSm = await _mk(tls, { profile: "permissive" });
1040
+ var ssock = await _connect(sSm.port);
1041
+ try {
1042
+ await _readReply(ssock);
1043
+ await _send(ssock, "EHLO client.example.com");
1044
+ await _send(ssock, "MAIL FROM:<a@example.com>");
1045
+ await _send(ssock, "RCPT TO:<b@example.com>");
1046
+ await _send(ssock, "DATA");
1047
+ // bare-LF dot line — CVE-2023-51764 smuggling shape.
1048
+ check("DATA bare-LF-dot smuggling → 554",
1049
+ /^554 /.test(await _writeRaw(ssock, "evil body" + LF + "." + LF + "injected")));
1050
+ } finally { ssock.destroy(); await sSm.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1051
+ }
1052
+
1053
+ // ---- AUTH not configured (permissive, no auth) ----
1054
+
1055
+ async function testAuthNotConfigured(tls) {
1056
+ var s = await _mk(tls, { profile: "permissive" });
1057
+ var sock = await _connect(s.port);
1058
+ try {
1059
+ await _readReply(sock);
1060
+ await _send(sock, "EHLO client.example.com");
1061
+ check("AUTH with no authenticator → 502", /^502 /.test(await _send(sock, "AUTH PLAIN " + _saslPlain("u", "p"))));
1062
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1063
+ }
1064
+
1065
+ // ---- idle timeout ----
1066
+
1067
+ async function testIdleTimeout(tls) {
1068
+ var s = await _mk(tls, { profile: "permissive", idleTimeoutMs: b.constants.TIME.seconds(1) });
1069
+ var sock = await _connect(s.port);
1070
+ try {
1071
+ await _readReply(sock); // greeting
1072
+ // No further traffic → server should fire the idle-timeout 421.
1073
+ var reply = await _readReply(sock);
1074
+ check("idle timeout → 421", /^421 /.test(reply));
1075
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1076
+ }
1077
+
1078
+ // ---- close() drain writes 421 to live sockets ----
1079
+
1080
+ async function testCloseDrain(tls) {
1081
+ var s = await _mk(tls, { profile: "permissive" });
1082
+ var sock = await _connect(s.port);
1083
+ await _readReply(sock);
1084
+ check("connectionCount is 1 with a live socket", s.srv.connectionCount() >= 1);
1085
+ var got421 = false;
1086
+ sock.on("data", function (c) { if (/421 /.test(c.toString("utf8"))) got421 = true; });
1087
+ var closing = s.srv.close({ timeoutMs: b.constants.TIME.seconds(5) });
1088
+ // Let the drain write its 421, then release the socket so close resolves fast.
1089
+ await helpers.waitUntil(function () { return got421; }, {
1090
+ timeoutMs: b.constants.TIME.seconds(3),
1091
+ label: "close-drain: 421 shutdown notice delivered",
1092
+ });
1093
+ sock.destroy();
1094
+ await closing;
1095
+ check("close() drained live socket with 421", got421 === true);
1096
+ check("connectionCount is 0 after close", s.srv.connectionCount() === 0);
1097
+ }
1098
+
1099
+ // ---- BDAT: non-final chunk ack, tail re-feed, empty-LAST, cumulative cap ----
1100
+
1101
+ async function testBdatMore(tls) {
1102
+ var h = [];
1103
+ var s = await _mk(tls, { profile: "permissive", agent: _agentCapturing(h, "accept") });
1104
+
1105
+ // Non-final non-zero chunk → "N octets received", then finalize.
1106
+ var sock = await _connect(s.port);
1107
+ try {
1108
+ await _readReply(sock);
1109
+ await _send(sock, "EHLO client.example.com");
1110
+ await _send(sock, "MAIL FROM:<a@example.com>");
1111
+ await _send(sock, "RCPT TO:<b@example.com>");
1112
+ var r1 = _readReply(sock);
1113
+ sock.write("BDAT 5\r\n");
1114
+ sock.write("abcde");
1115
+ check("BDAT non-final chunk → 250 N octets", /^250 .*octets/.test(await r1));
1116
+ // Tail re-feed: BDAT chunk + trailing command in one segment.
1117
+ var r2 = _readReply(sock);
1118
+ sock.write("BDAT 3\r\nxyzNOOP\r\n");
1119
+ check("BDAT chunk with pipelined tail → 250", /^250 /.test(await r2));
1120
+ // Zero-byte LAST after real chunks → finalizes the accumulated body.
1121
+ check("BDAT 0 LAST after chunks → 250", /^250 /.test(await _send(sock, "BDAT 0 LAST")));
1122
+ await helpers.waitUntil(function () { return h.length >= 1; },
1123
+ { timeoutMs: 5000, label: "submission BDAT: agent handoff received after BDAT 0 LAST" });
1124
+ check("agent received accumulated BDAT body", h.length === 1 && h[0].body.toString("utf8") === "abcdexyz");
1125
+ } finally { sock.destroy(); }
1126
+
1127
+ // BDAT 0 LAST as the only chunk → empty body finalized.
1128
+ var sock2 = await _connect(s.port);
1129
+ try {
1130
+ await _readReply(sock2);
1131
+ await _send(sock2, "EHLO client.example.com");
1132
+ await _send(sock2, "MAIL FROM:<a@example.com>");
1133
+ await _send(sock2, "RCPT TO:<b@example.com>");
1134
+ check("BDAT 0 LAST empty message → 250", /^250 /.test(await _send(sock2, "BDAT 0 LAST")));
1135
+ } finally { sock2.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1136
+
1137
+ // Cumulative-size cap up-front refusal.
1138
+ var sCap = await _mk(tls, { profile: "permissive", maxMessageBytes: b.constants.BYTES.kib(1) });
1139
+ var sock3 = await _connect(sCap.port);
1140
+ try {
1141
+ await _readReply(sock3);
1142
+ await _send(sock3, "EHLO client.example.com");
1143
+ await _send(sock3, "MAIL FROM:<a@example.com>");
1144
+ await _send(sock3, "RCPT TO:<b@example.com>");
1145
+ check("BDAT cumulative over cap → 552", /^552 /.test(await _send(sock3, "BDAT 99999 LAST")));
1146
+ } finally { sock3.destroy(); await sCap.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1147
+ }
1148
+
1149
+ // ---- PIPELINING: RCPT verdict still in-flight when DATA / BDAT arrives ----
1150
+
1151
+ async function testPipeliningRace(tls) {
1152
+ var s = await _mk(tls, {
1153
+ profile: "permissive",
1154
+ // Async accept: the verdict resolves on a microtask AFTER the pipelined
1155
+ // DATA / BDAT line is dispatched in the same ingest pass.
1156
+ recipientPolicy: function () { return Promise.resolve({ ok: true }); },
1157
+ });
1158
+
1159
+ var sock = await _connect(s.port);
1160
+ try {
1161
+ await _readReply(sock);
1162
+ await _send(sock, "EHLO client.example.com");
1163
+ await _send(sock, "MAIL FROM:<a@example.com>");
1164
+ await _send(sock, "RCPT TO:<committed@example.com>"); // one committed recipient
1165
+ // Pipeline a second RCPT (verdict pending) + DATA in one segment.
1166
+ var r = _readReply(sock);
1167
+ sock.write("RCPT TO:<pending@example.com>\r\nDATA\r\n");
1168
+ check("DATA while RCPT verdict pending → 451", /^451 /.test(await r));
1169
+ } finally { sock.destroy(); }
1170
+
1171
+ var sock2 = await _connect(s.port);
1172
+ try {
1173
+ await _readReply(sock2);
1174
+ await _send(sock2, "EHLO client.example.com");
1175
+ await _send(sock2, "MAIL FROM:<a@example.com>");
1176
+ await _send(sock2, "RCPT TO:<committed@example.com>");
1177
+ var r2 = _readReply(sock2);
1178
+ sock2.write("RCPT TO:<pending@example.com>\r\nBDAT 5 LAST\r\n");
1179
+ check("BDAT while RCPT verdict pending → 451", /^451 /.test(await r2));
1180
+ } finally { sock2.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1181
+ }
1182
+
1183
+ // ---- DKIM self mode with an authenticated actor (id-domain fallback) +
1184
+ // d-less signature + folded signature ----
1185
+
1186
+ async function testDkimSelfActor(tls) {
1187
+ var s = await _mk(tls, {
1188
+ profile: "permissive",
1189
+ identityBinding: "permissive", // allow MAIL FROM without a mailbox set
1190
+ requireDkim: true,
1191
+ dkimRequireMode: "self",
1192
+ auth: {
1193
+ mechanisms: ["PLAIN"],
1194
+ verify: function (mech, creds) {
1195
+ var parts = Buffer.from(creds.clientResponse || "", "base64").toString("utf8").split(NUL);
1196
+ // actor with an id carrying the domain but NO explicit .domain field
1197
+ // → _actorDomain falls back to the id's @-domain.
1198
+ return Promise.resolve({ ok: true, actor: { id: parts[1] + "@example.com" } });
1199
+ },
1200
+ },
1201
+ });
1202
+ var sock = await _connect(s.port);
1203
+ try {
1204
+ await _readReply(sock);
1205
+ await _send(sock, "EHLO client.example.com");
1206
+ await _send(sock, "AUTH PLAIN " + _saslPlain("u", "x"));
1207
+ await _send(sock, "MAIL FROM:<u@example.com>");
1208
+ await _send(sock, "RCPT TO:<b@example.com>");
1209
+ // d= matches the actor-id domain → accepted.
1210
+ check("dkim self (actor id-domain) matching d= → 250",
1211
+ /^250 /.test(await _dataDot(sock, "DKIM-Signature: v=1; d=example.com; b=z\r\nFrom: u@example.com\r\n\r\nx")));
1212
+ await _send(sock, "MAIL FROM:<u@example.com>");
1213
+ await _send(sock, "RCPT TO:<b@example.com>");
1214
+ // Signature present but no d= tag → no match → 550.
1215
+ check("dkim self signature without d= → 550",
1216
+ /^550 /.test(await _dataDot(sock, "DKIM-Signature: v=1; b=z\r\nFrom: u@example.com\r\n\r\nx")));
1217
+ } finally { sock.destroy(); await s.srv.close({ timeoutMs: b.constants.TIME.seconds(2) }); }
1218
+ }
1219
+
372
1220
  async function run() {
373
1221
  testSurface();
374
1222
  testCreateRequiresTlsContext();
@@ -384,6 +1232,34 @@ async function run() {
384
1232
  await testBdatBadArgs();
385
1233
  await testBdatBinaryBytesPreserved();
386
1234
  await testBdatOversizeRefused();
1235
+
1236
+ var tls;
1237
+ try { tls = await _makeTestTlsContextWithCa(); }
1238
+ catch (_e) { check("mail-server-submission error branches skipped (no TLS ctx)", true); return; }
1239
+
1240
+ testCreateValidation(tls);
1241
+ await testCloseBeforeListen(tls);
1242
+ await testDoubleListen(tls);
1243
+ await testPermissiveDispatch(tls);
1244
+ await testDomainRefusals(tls);
1245
+ await testDataPaths(tls);
1246
+ await testBdatBranches(tls);
1247
+ await testBdatMore(tls);
1248
+ await testPipeliningRace(tls);
1249
+ await testDkimSelfActor(tls);
1250
+ await testCleartextAuthAndIdentity(tls);
1251
+ await testAuthFailuresAndMultiStep(tls);
1252
+ await testAuthRateLimit(tls);
1253
+ await testCrossTenant(tls);
1254
+ await testStrictProfileStartTls(tls);
1255
+ await testImplicitTls(tls);
1256
+ await testDkimModes(tls);
1257
+ await testRecipientPolicy(tls);
1258
+ await testConnRateLimit(tls);
1259
+ await testLimitsAndSmuggling(tls);
1260
+ await testAuthNotConfigured(tls);
1261
+ await testIdleTimeout(tls);
1262
+ await testCloseDrain(tls);
387
1263
  }
388
1264
 
389
1265
  module.exports = { run: run };