@blamejs/blamejs-shop 0.5.12 → 0.5.13

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 (521) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +632 -416
  4. package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
  5. package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
  6. package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
  7. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  8. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
  9. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
  10. package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
  11. package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
  12. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
  13. package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
  14. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
  15. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  16. package/lib/vendor/blamejs/.gitignore +2 -0
  17. package/lib/vendor/blamejs/CHANGELOG.md +122 -0
  18. package/lib/vendor/blamejs/NOTICE +26 -1
  19. package/lib/vendor/blamejs/SECURITY.md +1 -1
  20. package/lib/vendor/blamejs/api-snapshot.json +207 -5
  21. package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
  22. package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
  23. package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
  24. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
  25. package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
  26. package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
  27. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
  28. package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
  29. package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
  30. package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
  31. package/lib/vendor/blamejs/index.js +6 -0
  32. package/lib/vendor/blamejs/lib/a2a.js +4 -4
  33. package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
  34. package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
  35. package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
  36. package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
  37. package/lib/vendor/blamejs/lib/archive-read.js +8 -0
  38. package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
  39. package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
  40. package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
  41. package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
  42. package/lib/vendor/blamejs/lib/audit.js +71 -8
  43. package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
  44. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
  45. package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
  46. package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
  47. package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
  48. package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
  49. package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
  50. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
  51. package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
  52. package/lib/vendor/blamejs/lib/backup/index.js +16 -5
  53. package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
  54. package/lib/vendor/blamejs/lib/base32.js +21 -0
  55. package/lib/vendor/blamejs/lib/break-glass.js +19 -10
  56. package/lib/vendor/blamejs/lib/bundler.js +5 -1
  57. package/lib/vendor/blamejs/lib/cache-status.js +3 -7
  58. package/lib/vendor/blamejs/lib/calendar.js +21 -1
  59. package/lib/vendor/blamejs/lib/cbor.js +12 -1
  60. package/lib/vendor/blamejs/lib/cert.js +29 -11
  61. package/lib/vendor/blamejs/lib/cli.js +94 -24
  62. package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
  63. package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
  64. package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
  65. package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
  66. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
  67. package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
  68. package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
  69. package/lib/vendor/blamejs/lib/content-digest.js +2 -1
  70. package/lib/vendor/blamejs/lib/cookies.js +13 -3
  71. package/lib/vendor/blamejs/lib/cose.js +31 -16
  72. package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
  73. package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
  74. package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
  75. package/lib/vendor/blamejs/lib/crypto.js +314 -19
  76. package/lib/vendor/blamejs/lib/csp.js +11 -3
  77. package/lib/vendor/blamejs/lib/daemon.js +270 -24
  78. package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
  79. package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
  80. package/lib/vendor/blamejs/lib/db-query.js +34 -7
  81. package/lib/vendor/blamejs/lib/db.js +18 -6
  82. package/lib/vendor/blamejs/lib/dbsc.js +17 -0
  83. package/lib/vendor/blamejs/lib/dev.js +21 -2
  84. package/lib/vendor/blamejs/lib/dsr.js +157 -102
  85. package/lib/vendor/blamejs/lib/external-db.js +41 -2
  86. package/lib/vendor/blamejs/lib/file-upload.js +25 -7
  87. package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
  88. package/lib/vendor/blamejs/lib/forms.js +113 -27
  89. package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
  90. package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
  91. package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
  92. package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
  93. package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
  94. package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
  95. package/lib/vendor/blamejs/lib/guard-html.js +26 -53
  96. package/lib/vendor/blamejs/lib/guard-image.js +24 -5
  97. package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
  98. package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
  99. package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
  100. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
  101. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
  102. package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
  103. package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
  104. package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
  105. package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
  106. package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
  107. package/lib/vendor/blamejs/lib/guard-time.js +1 -1
  108. package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
  109. package/lib/vendor/blamejs/lib/html-balance.js +3 -3
  110. package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
  111. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
  112. package/lib/vendor/blamejs/lib/http-client.js +39 -7
  113. package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
  114. package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
  115. package/lib/vendor/blamejs/lib/i18n.js +35 -21
  116. package/lib/vendor/blamejs/lib/incident-report.js +8 -1
  117. package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
  118. package/lib/vendor/blamejs/lib/json-path.js +23 -1
  119. package/lib/vendor/blamejs/lib/jwk.js +20 -3
  120. package/lib/vendor/blamejs/lib/link-header.js +2 -1
  121. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
  122. package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
  123. package/lib/vendor/blamejs/lib/log-stream.js +8 -3
  124. package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
  125. package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
  126. package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
  127. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
  128. package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
  129. package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
  130. package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
  131. package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
  132. package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
  133. package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
  134. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
  135. package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
  136. package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
  137. package/lib/vendor/blamejs/lib/mail.js +15 -5
  138. package/lib/vendor/blamejs/lib/metrics.js +268 -63
  139. package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
  140. package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
  141. package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
  142. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
  143. package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
  144. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
  145. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
  146. package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
  147. package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
  148. package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
  149. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
  150. package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
  151. package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
  152. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
  153. package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
  154. package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
  155. package/lib/vendor/blamejs/lib/network-dns.js +21 -2
  156. package/lib/vendor/blamejs/lib/network-tls.js +69 -7
  157. package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
  158. package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
  159. package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
  160. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
  161. package/lib/vendor/blamejs/lib/outbox.js +1 -1
  162. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
  163. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
  164. package/lib/vendor/blamejs/lib/permissions.js +6 -3
  165. package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
  166. package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
  167. package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
  168. package/lib/vendor/blamejs/lib/pubsub.js +20 -9
  169. package/lib/vendor/blamejs/lib/queue-local.js +8 -1
  170. package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
  171. package/lib/vendor/blamejs/lib/redact.js +54 -0
  172. package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
  173. package/lib/vendor/blamejs/lib/restore.js +19 -0
  174. package/lib/vendor/blamejs/lib/retention.js +12 -4
  175. package/lib/vendor/blamejs/lib/router.js +60 -6
  176. package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
  177. package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
  178. package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
  179. package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
  180. package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
  181. package/lib/vendor/blamejs/lib/safe-object.js +80 -0
  182. package/lib/vendor/blamejs/lib/safe-path.js +52 -4
  183. package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
  184. package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
  185. package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
  186. package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
  187. package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
  188. package/lib/vendor/blamejs/lib/scheduler.js +8 -1
  189. package/lib/vendor/blamejs/lib/security-assert.js +6 -6
  190. package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
  191. package/lib/vendor/blamejs/lib/self-update.js +517 -87
  192. package/lib/vendor/blamejs/lib/server-timing.js +2 -4
  193. package/lib/vendor/blamejs/lib/session.js +34 -12
  194. package/lib/vendor/blamejs/lib/sql.js +15 -1
  195. package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
  196. package/lib/vendor/blamejs/lib/static.js +55 -13
  197. package/lib/vendor/blamejs/lib/storage.js +8 -2
  198. package/lib/vendor/blamejs/lib/subject.js +6 -1
  199. package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
  200. package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
  201. package/lib/vendor/blamejs/lib/tsa.js +34 -13
  202. package/lib/vendor/blamejs/lib/uri-template.js +8 -1
  203. package/lib/vendor/blamejs/lib/vault/index.js +13 -0
  204. package/lib/vendor/blamejs/lib/vc.js +44 -5
  205. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
  206. package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
  207. package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
  208. package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
  209. package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
  210. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
  211. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
  212. package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
  213. package/lib/vendor/blamejs/lib/watcher.js +89 -17
  214. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
  215. package/lib/vendor/blamejs/lib/webhook.js +12 -2
  216. package/lib/vendor/blamejs/lib/ws-client.js +32 -1
  217. package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
  218. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
  219. package/lib/vendor/blamejs/package-lock.json +2 -2
  220. package/lib/vendor/blamejs/package.json +1 -1
  221. package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
  222. package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
  223. package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
  224. package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
  225. package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
  226. package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
  227. package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
  228. package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
  229. package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
  230. package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
  231. package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
  232. package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
  233. package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
  234. package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
  235. package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
  236. package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
  237. package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
  238. package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
  239. package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
  240. package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
  241. package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
  242. package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
  243. package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
  244. package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
  245. package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
  246. package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
  247. package/lib/vendor/blamejs/socket.yml +94 -0
  248. package/lib/vendor/blamejs/test/00-primitives.js +605 -0
  249. package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
  250. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
  251. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
  252. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
  253. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
  254. package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
  255. package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
  256. package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
  257. package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
  258. package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
  259. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
  262. package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
  268. package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
  270. package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
  271. package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
  272. package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
  273. package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
  283. package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
  284. package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
  293. package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
  294. package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
  302. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
  307. package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
  308. package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
  310. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
  312. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
  313. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
  314. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
  315. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
  316. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
  317. package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
  318. package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
  319. package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
  320. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
  321. package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
  322. package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
  323. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
  324. package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
  325. package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
  326. package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
  327. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
  328. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
  329. package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
  330. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
  331. package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
  334. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
  335. package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
  336. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
  337. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
  341. package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
  342. package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
  344. package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
  346. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
  347. package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
  348. package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
  349. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
  376. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
  387. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
  388. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
  389. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
  390. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
  391. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
  392. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
  393. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
  395. package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
  396. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
  397. package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
  398. package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
  399. package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
  400. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
  401. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
  402. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
  403. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
  404. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
  405. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
  406. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
  407. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
  408. package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
  409. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
  410. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
  411. package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
  412. package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
  413. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
  414. package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
  415. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
  416. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
  417. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
  418. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
  419. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
  420. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
  421. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
  422. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
  423. package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
  424. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
  425. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
  426. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
  427. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
  428. package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
  429. package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
  430. package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
  431. package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
  432. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
  433. package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
  434. package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
  435. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
  436. package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
  437. package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
  438. package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
  439. package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
  440. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
  441. package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
  442. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
  443. package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
  444. package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
  445. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
  446. package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
  447. package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
  448. package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
  449. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
  450. package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
  451. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
  452. package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
  453. package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
  454. package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
  455. package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
  456. package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
  457. package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
  458. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
  459. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
  460. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
  461. package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
  462. package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
  463. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
  464. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
  465. package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
  466. package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
  467. package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
  468. package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
  469. package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
  470. package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
  471. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
  472. package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
  473. package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
  474. package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
  475. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
  476. package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
  477. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
  478. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
  479. package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
  480. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
  481. package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
  482. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
  483. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
  484. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
  485. package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
  486. package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
  487. package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
  488. package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
  489. package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
  490. package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
  491. package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
  492. package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
  493. package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
  494. package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
  495. package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
  496. package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
  497. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
  498. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
  499. package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
  500. package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
  501. package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
  502. package/lib/vendor/blamejs/test/smoke.js +2 -0
  503. package/package.json +1 -1
  504. package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
  505. package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
  506. package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
  507. package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
  508. package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
  509. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
  510. package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
  511. package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
  512. package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
  513. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
  514. package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
  515. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
  516. package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
  517. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
  518. package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
  519. package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
  520. package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
  521. package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
@@ -698,6 +698,768 @@ async function testSelectQresyncImplicitlyEngagesCondstore() {
698
698
  } finally { await srv.close({ timeoutMs: 1000 }); } // allow:raw-time-literal — test-only short drain
699
699
  }
700
700
 
701
+ // ---- RFC 9051 command dispatch + error branches ----
702
+ //
703
+ // The suites below drive the full command dispatch and its wrong-state /
704
+ // malformed / backend-missing / rate-limited / resource-limit refusals that
705
+ // the happy-path suites above never reach. Every assertion drives the public
706
+ // API over a socket: greeting + CAPABILITY, STARTTLS upgrade, AUTHENTICATE
707
+ // (PLAIN inline + SCRAM multi-step challenge + verify-throw), LOGIN
708
+ // (strict/balanced/permissive/quoted-escape/rate-limit), SELECT/EXAMINE
709
+ // (traversal + mUTF7 + no-backend), LIST/STATUS, APPEND (literal + LITERAL+
710
+ // + zero-byte + overflow + quota + date-time), FETCH/STORE/EXPUNGE/UID/
711
+ // CLOSE/CHECK/NAMESPACE (selected-state gating + backend-missing), IDLE/DONE,
712
+ // GET/SETMETADATA + NOTIFY error branches, connection rate-limit refusal,
713
+ // line-too-long, literal-smuggling, and the dispatch sync-throw /
714
+ // promise-reject paths (via opts.overrides).
715
+
716
+ var NUL = String.fromCharCode(0);
717
+ var BS = String.fromCharCode(92); // backslash — avoid JS-level escaping ambiguity on the wire
718
+
719
+ // ---- TLS context (generated once, reused across every server) ----
720
+ var SHARED_CTX = null;
721
+ async function _ctx() {
722
+ if (SHARED_CTX) return SHARED_CTX;
723
+ var ca = await b.mtlsEngine.generateCa({ name: "imap-dispatch-test-ca" });
724
+ var leaf = await b.mtlsEngine.signClientCert({
725
+ cn: "imap.test", caCertPem: ca.caCertPem, caKeyPem: ca.caKeyPem,
726
+ usage: "server", sans: ["DNS:localhost", "DNS:imap.test", "IP:127.0.0.1"], validityDays: 1,
727
+ });
728
+ SHARED_CTX = { ctx: nodeTls.createSecureContext({ key: leaf.key, cert: leaf.cert }), caPem: ca.caCertPem };
729
+ return SHARED_CTX;
730
+ }
731
+
732
+ // ---- socket read/write helpers (request/response over a persistent conn) ----
733
+ function _read(sock, term) {
734
+ return new Promise(function (resolve) {
735
+ var buf = "";
736
+ function onData(c) { buf += c.toString("utf8"); if (term.test(buf)) { fin(); resolve(buf); } }
737
+ function onClose() { fin(); resolve(buf); }
738
+ function fin() { sock.removeListener("data", onData); sock.removeListener("close", onClose); }
739
+ sock.on("data", onData);
740
+ sock.once("close", onClose);
741
+ });
742
+ }
743
+ function _tagTerm(tag) { return new RegExp("^" + tag + " ", "m"); }
744
+ // Tagged command: writes `<tag> <rest>` and resolves on the tagged completion.
745
+ function _cmd(sock, tag, rest) {
746
+ var p = _read(sock, _tagTerm(tag));
747
+ sock.write(tag + " " + rest + "\r\n");
748
+ return p;
749
+ }
750
+ // Tagged command whose reply we expect on a CUSTOM terminator (untagged BAD /
751
+ // continuation `+` / rate-limit refusal etc.).
752
+ function _cmdT(sock, tag, rest, term) {
753
+ var p = _read(sock, term);
754
+ sock.write(tag + " " + rest + "\r\n");
755
+ return p;
756
+ }
757
+ // Raw bytes (literal payloads, SASL continuation responses, bare DONE).
758
+ function _raw(sock, term, bytes) {
759
+ var p = _read(sock, term);
760
+ sock.write(bytes);
761
+ return p;
762
+ }
763
+
764
+ async function _connect(port) {
765
+ var sock = nodeNet.connect(port, "127.0.0.1");
766
+ sock.on("error", function () {});
767
+ await _read(sock, /^\* OK /);
768
+ return sock;
769
+ }
770
+
771
+ // ---- operator-shaped mailStore stub with per-test overrides / deletions ----
772
+ function _baseStore(over) {
773
+ over = over || {};
774
+ var calls = { append: [], select: [], fetch: [], store: [], expunge: [], status: [], list: [] };
775
+ var store = {
776
+ calls: calls,
777
+ appendMessage: function (name, body, o) {
778
+ calls.append.push({ name: name, size: body.length, o: o });
779
+ return Promise.resolve({ uid: 5, uidvalidity: 3 });
780
+ },
781
+ selectFolder: function (_actor, name, o) {
782
+ calls.select.push({ name: name, o: o });
783
+ return Promise.resolve({ uidvalidity: 1, uidnext: 10, modseq: 42, exists: 2, recent: 0, unseen: 0, flags: ["\\Seen"] });
784
+ },
785
+ listFolders: function () { return Promise.resolve([{ name: "INBOX", attributes: ["HasNoChildren"] }]); },
786
+ statusFolder: function (_actor, name, items) {
787
+ calls.status.push({ name: name, items: items });
788
+ return Promise.resolve({ MESSAGES: 3, UIDNEXT: 10, UIDVALIDITY: 1, UNSEEN: 1 });
789
+ },
790
+ fetchRange: function (_actor, _mb, seq, parts, o) {
791
+ calls.fetch.push({ seq: seq, parts: parts, o: o });
792
+ return Promise.resolve([{ seq: 1, payload: "FLAGS (\\Seen)", modseq: 10 }]);
793
+ },
794
+ storeFlags: function (_actor, _mb, seq, mode, flags, o) {
795
+ calls.store.push({ seq: seq, mode: mode, flags: flags, o: o });
796
+ return Promise.resolve([{ seq: 1, flags: ["\\Seen"], modseq: 11 }]); // legacy ARRAY shape (exercises the array-normalise branch)
797
+ },
798
+ expungeFolder: function (_actor, mb) {
799
+ calls.expunge.push({ mb: mb });
800
+ return Promise.resolve({ expunged: [1, 2], modseq: 7 });
801
+ },
802
+ };
803
+ Object.keys(over).forEach(function (k) {
804
+ if (over[k] === null) { delete store[k]; } else { store[k] = over[k]; }
805
+ });
806
+ return store;
807
+ }
808
+
809
+ function _defaultVerify(mech, creds) {
810
+ if (mech === "EXTERNAL") { throw new Error("verify boom (EXTERNAL)"); } // exercises the _runAuthStep catch path
811
+ if (mech === "SCRAM-SHA-256") {
812
+ if (creds.step === 0) { return Promise.resolve({ pending: true, challenge: "cj1zZXJ2ZXJub25jZQ==" }); }
813
+ return Promise.resolve({ ok: true, actor: { username: "scram-user", tenantId: "t1" } });
814
+ }
815
+ var user, pass;
816
+ if (creds.clientResponse) {
817
+ var parts = Buffer.from(creds.clientResponse, "base64").toString("utf8").split(NUL);
818
+ user = parts[1]; pass = parts[2];
819
+ } else { user = creds.username; pass = creds.password; }
820
+ if (pass === "good") { return Promise.resolve({ ok: true, actor: { username: user, tenantId: "t1" } }); }
821
+ return Promise.resolve({ ok: false, reason: "invalid-credentials" });
822
+ }
823
+
824
+ var DEFAULT_AUTH = { mechanisms: ["PLAIN", "LOGIN", "SCRAM-SHA-256", "EXTERNAL"], verify: _defaultVerify };
825
+
826
+ async function _makeServer(extra) {
827
+ extra = extra || {};
828
+ var t = await _ctx();
829
+ var opts = {
830
+ tlsContext: t.ctx,
831
+ mailStore: extra.mailStore !== undefined ? extra.mailStore : _baseStore(),
832
+ profile: extra.profile || "permissive",
833
+ auth: extra.auth !== undefined ? extra.auth : DEFAULT_AUTH,
834
+ };
835
+ ["rateLimit", "maxLineBytes", "maxLiteralBytes", "overrides", "greeting"].forEach(function (k) {
836
+ if (extra[k] !== undefined) opts[k] = extra[k];
837
+ });
838
+ var srv = b.mail.server.imap.create(opts);
839
+ var info = await srv.listen({ port: 0, address: "127.0.0.1" });
840
+ return { srv: srv, port: info.port, caPem: t.caPem };
841
+ }
842
+
843
+ async function _authConn(s, mailbox) {
844
+ var sock = await _connect(s.port);
845
+ var r = await _cmd(sock, "L0", "LOGIN alice good");
846
+ check("[setup] LOGIN alice good authenticates", /^L0 OK/m.test(r));
847
+ if (mailbox) {
848
+ var sel = await _cmd(sock, "L1", "SELECT " + mailbox);
849
+ check("[setup] SELECT " + mailbox + " succeeds", /^L1 OK/m.test(sel));
850
+ }
851
+ return sock;
852
+ }
853
+
854
+ // SASL PLAIN blob: authzid NUL authcid NUL passwd, base64-encoded (RFC 4616).
855
+ function _plain(user, pass) {
856
+ return Buffer.from(["", user, pass].join(NUL), "utf8").toString("base64");
857
+ }
858
+
859
+ // =====================================================================
860
+ // 1. Greeting + unauthenticated dispatch + notFound + malformed lines
861
+ // =====================================================================
862
+ async function testUnauthDispatch() {
863
+ var s = await _makeServer({ profile: "permissive" });
864
+ var sock = await _connect(s.port);
865
+ try {
866
+ var cap = await _cmd(sock, "a1", "CAPABILITY");
867
+ check("CAPABILITY advertises STARTTLS pre-TLS", /STARTTLS/.test(cap));
868
+ check("CAPABILITY advertises AUTH=PLAIN (wired mechanism)", /AUTH=PLAIN/.test(cap));
869
+ check("CAPABILITY tagged OK", /^a1 OK CAPABILITY completed/m.test(cap));
870
+ check("NOOP → OK", /^a2 OK NOOP completed/m.test(await _cmd(sock, "a2", "NOOP")));
871
+ var id = await _cmd(sock, "a3", "ID (\"name\" \"x\")");
872
+ check("ID replies untagged ID + OK", /^\* ID \("name" "blamejs"/m.test(id) && /^a3 OK ID completed/m.test(id));
873
+ check("SELECT before auth → NO Login first", /^a4 NO Login first/m.test(await _cmd(sock, "a4", "SELECT INBOX")));
874
+ check("unknown verb → untagged BAD", /^\* BAD/m.test(await _cmdT(sock, "a5", "ZORP x", /^\* BAD/m)));
875
+ check("empty line → untagged BAD (empty command line)",
876
+ /^\* BAD .*empty command line/m.test(await _raw(sock, /^\* BAD/m, "\r\n")));
877
+ check("GETQUOTA (known verb, no handler) → notFound BAD not implemented",
878
+ /^a6 BAD Verb 'GETQUOTA' not implemented/m.test(await _cmd(sock, "a6", "GETQUOTA \"\"")));
879
+ var out = await _cmd(sock, "q1", "LOGOUT");
880
+ check("LOGOUT → untagged BYE + tagged OK", /^\* BYE Logging out/m.test(out) && /^q1 OK LOGOUT completed/m.test(out));
881
+ } finally { sock.destroy(); await s.srv.close(); }
882
+ }
883
+
884
+ // =====================================================================
885
+ // 2. STARTTLS upgrade (balanced) + post-TLS caps + already-negotiated +
886
+ // LOGIN-over-TLS + mUTF7 refusal (non-permissive branch)
887
+ // =====================================================================
888
+ async function testStartTlsUpgrade() {
889
+ var s = await _makeServer({ profile: "balanced" });
890
+ var sock = await _connect(s.port);
891
+ var tls;
892
+ try {
893
+ check("STARTTLS → OK begin negotiation",
894
+ /^a1 OK Begin TLS negotiation/m.test(await _cmd(sock, "a1", "STARTTLS")));
895
+ tls = nodeTls.connect({ socket: sock, ca: s.caPem, servername: "localhost" });
896
+ tls.on("error", function () {});
897
+ await new Promise(function (r, j) { tls.once("secureConnect", r); tls.once("error", j); });
898
+
899
+ var cap = await _cmd(tls, "a2", "CAPABILITY");
900
+ check("post-TLS CAPABILITY drops STARTTLS", !/STARTTLS/.test(cap));
901
+ check("STARTTLS after TLS → BAD already negotiated",
902
+ /^a3 BAD TLS already negotiated/m.test(await _cmd(tls, "a3", "STARTTLS")));
903
+ check("LOGIN over TLS (balanced) authenticates",
904
+ /^a4 OK/m.test(await _cmd(tls, "a4", "LOGIN alice good")));
905
+ check("SELECT modified-UTF7 name refused under balanced profile",
906
+ /^a5 BAD Mailbox name refused/m.test(await _cmd(tls, "a5", "SELECT &AAA-")));
907
+ } finally { if (tls) tls.destroy(); sock.destroy(); await s.srv.close(); }
908
+ }
909
+
910
+ // =====================================================================
911
+ // 3. AUTHENTICATE — every branch
912
+ // =====================================================================
913
+ async function testAuthenticate() {
914
+ var s = await _makeServer({ profile: "permissive" });
915
+ // 3a. unadvertised mechanism
916
+ var c1 = await _connect(s.port);
917
+ try {
918
+ check("AUTHENTICATE unadvertised mechanism → NO not advertised",
919
+ /^a1 NO Mechanism 'GSSAPI' not advertised/m.test(await _cmd(c1, "a1", "AUTHENTICATE GSSAPI")));
920
+ // 3b. PLAIN inline success (initial-response branch)
921
+ check("AUTHENTICATE PLAIN inline creds → OK completed",
922
+ /^a2 OK \[CAPABILITY .*\] AUTHENTICATE completed/m.test(await _cmd(c1, "a2", "AUTHENTICATE PLAIN " + _plain("alice", "good"))));
923
+ // 3c. already authenticated
924
+ check("AUTHENTICATE when already authenticated → BAD",
925
+ /^a3 BAD Already authenticated/m.test(await _cmd(c1, "a3", "AUTHENTICATE PLAIN " + _plain("alice", "good"))));
926
+ } finally { c1.destroy(); }
927
+
928
+ // 3d. PLAIN bad creds (fail branch)
929
+ var c2 = await _connect(s.port);
930
+ try {
931
+ check("AUTHENTICATE PLAIN bad creds → NO credentials invalid",
932
+ /^a1 NO Authentication credentials invalid/m.test(await _cmd(c2, "a1", "AUTHENTICATE PLAIN " + _plain("alice", "nope"))));
933
+ } finally { c2.destroy(); }
934
+
935
+ // 3e. SCRAM multi-step challenge (no initial response → pending → OK)
936
+ var c3 = await _connect(s.port);
937
+ try {
938
+ var chal = await _cmdT(c3, "a1", "AUTHENTICATE SCRAM-SHA-256", /^\+ /m);
939
+ check("AUTHENTICATE SCRAM emits server challenge (+ base64)", /^\+ cj1zZXJ2ZXJub25jZQ==/m.test(chal));
940
+ var done = await _raw(c3, _tagTerm("a1"), "Y2xpZW50LWZpbmFs\r\n");
941
+ check("AUTHENTICATE SCRAM step-2 → OK completed", /^a1 OK \[CAPABILITY .*\] AUTHENTICATE completed/m.test(done));
942
+ } finally { c3.destroy(); }
943
+
944
+ // 3f. verify throws (catch branch)
945
+ var c4 = await _connect(s.port);
946
+ try {
947
+ check("AUTHENTICATE mechanism whose verify throws → NO Authentication failed",
948
+ /^a1 NO Authentication failed/m.test(await _cmd(c4, "a1", "AUTHENTICATE EXTERNAL")));
949
+ } finally { c4.destroy(); }
950
+ await s.srv.close();
951
+
952
+ // 3g. AUTHENTICATE with no auth config
953
+ var sNoAuth = await _makeServer({ profile: "permissive", auth: null });
954
+ var c5 = await _connect(sNoAuth.port);
955
+ try {
956
+ check("AUTHENTICATE with no auth config → NO not configured",
957
+ /^a1 NO AUTHENTICATE not configured/m.test(await _cmd(c5, "a1", "AUTHENTICATE PLAIN " + _plain("a", "b"))));
958
+ } finally { c5.destroy(); await sNoAuth.srv.close(); }
959
+
960
+ // 3h. AUTHENTICATE requires TLS under strict
961
+ var sStrict = await _makeServer({ profile: "strict" });
962
+ var c6 = await _connect(sStrict.port);
963
+ try {
964
+ check("AUTHENTICATE over cleartext under strict → BAD requires TLS",
965
+ /^a1 BAD AUTHENTICATE requires TLS/m.test(await _cmd(c6, "a1", "AUTHENTICATE PLAIN " + _plain("a", "b"))));
966
+ } finally { c6.destroy(); await sStrict.srv.close(); }
967
+
968
+ // 3i. AUTH-failure budget trips → refuse + close
969
+ var sRl = await _makeServer({ profile: "permissive", rateLimit: { authFailuresPerIpPer15Min: 1 } });
970
+ var c7 = await _connect(sRl.port);
971
+ try {
972
+ await _cmd(c7, "a1", "AUTHENTICATE PLAIN " + _plain("alice", "nope")); // 1 failure
973
+ check("AUTHENTICATE past failure budget → NO [ALERT] too many AUTH failures",
974
+ /^a2 NO \[ALERT\] Too many AUTH failures/m.test(await _cmd(c7, "a2", "AUTHENTICATE PLAIN " + _plain("alice", "nope"))));
975
+ } finally { c7.destroy(); await sRl.srv.close(); }
976
+ }
977
+
978
+ // =====================================================================
979
+ // 4. LOGIN — every branch
980
+ // =====================================================================
981
+ async function testLogin() {
982
+ // 4a. strict profile refuses LOGIN
983
+ var sStrict = await _makeServer({ profile: "strict" });
984
+ var cs = await _connect(sStrict.port);
985
+ try {
986
+ check("LOGIN under strict → BAD deprecated",
987
+ /^a1 BAD LOGIN deprecated/m.test(await _cmd(cs, "a1", "LOGIN alice good")));
988
+ } finally { cs.destroy(); await sStrict.srv.close(); }
989
+
990
+ // 4b. balanced over cleartext requires TLS
991
+ var sBal = await _makeServer({ profile: "balanced" });
992
+ var cb = await _connect(sBal.port);
993
+ try {
994
+ check("LOGIN over cleartext under balanced → BAD requires TLS",
995
+ /^a1 BAD LOGIN requires TLS/m.test(await _cmd(cb, "a1", "LOGIN alice good")));
996
+ } finally { cb.destroy(); await sBal.srv.close(); }
997
+
998
+ // 4c. no auth configured
999
+ var sNoAuth = await _makeServer({ profile: "permissive", auth: null });
1000
+ var cn = await _connect(sNoAuth.port);
1001
+ try {
1002
+ check("LOGIN with no auth config → NO AUTH not configured",
1003
+ /^a1 NO AUTH not configured/m.test(await _cmd(cn, "a1", "LOGIN alice good")));
1004
+ } finally { cn.destroy(); await sNoAuth.srv.close(); }
1005
+
1006
+ // 4d. permissive — success / already-auth / bad-creds / arg parsing
1007
+ var s = await _makeServer({ profile: "permissive" });
1008
+ var c1 = await _connect(s.port);
1009
+ try {
1010
+ check("LOGIN success → OK", /^a1 OK \[CAPABILITY .*\] LOGIN completed/m.test(await _cmd(c1, "a1", "LOGIN alice good")));
1011
+ check("LOGIN when already authenticated → BAD", /^a2 BAD Already authenticated/m.test(await _cmd(c1, "a2", "LOGIN bob good")));
1012
+ } finally { c1.destroy(); }
1013
+
1014
+ // Non-authenticating shapes (bad creds + parse failures) can share one conn.
1015
+ var c2 = await _connect(s.port);
1016
+ try {
1017
+ check("LOGIN bad creds → NO credentials invalid", /^a1 NO LOGIN credentials invalid/m.test(await _cmd(c2, "a1", "LOGIN alice wrong")));
1018
+ check("LOGIN unterminated quoted string → BAD expects user + pass",
1019
+ /^a2 BAD LOGIN expects user/m.test(await _cmd(c2, "a2", "LOGIN " + '"' + "alice good")));
1020
+ // Bad escape (\x) → parse fails (still not authenticated).
1021
+ check('LOGIN quoted username with invalid escape → BAD',
1022
+ /^a3 BAD LOGIN expects user/m.test(await _cmd(c2, "a3", "LOGIN " + '"' + "a" + BS + "x" + "b" + '"' + " good")));
1023
+ } finally { c2.destroy(); }
1024
+
1025
+ // Each SUCCESSFUL (authenticating) LOGIN needs a fresh connection — the
1026
+ // first success flips state.actor and any later LOGIN gets Already-auth.
1027
+ var c2a = await _connect(s.port);
1028
+ try {
1029
+ check('LOGIN quoted username with escaped quote → OK',
1030
+ /^a1 OK/m.test(await _cmd(c2a, "a1", "LOGIN " + '"' + "al" + BS + '"' + "x" + '"' + " good")));
1031
+ } finally { c2a.destroy(); }
1032
+
1033
+ var c2b = await _connect(s.port);
1034
+ try {
1035
+ check('LOGIN quoted username with escaped backslash → OK',
1036
+ /^a1 OK/m.test(await _cmd(c2b, "a1", "LOGIN " + '"' + "a" + BS + BS + "b" + '"' + " good")));
1037
+ } finally { c2b.destroy(); await s.srv.close(); }
1038
+
1039
+ // 4e. LOGIN failure budget trips → refuse + close
1040
+ var sRl = await _makeServer({ profile: "permissive", rateLimit: { authFailuresPerIpPer15Min: 1 } });
1041
+ var c3 = await _connect(sRl.port);
1042
+ try {
1043
+ await _cmd(c3, "a1", "LOGIN alice wrong"); // 1 failure
1044
+ check("LOGIN past failure budget → NO [ALERT] too many AUTH failures",
1045
+ /^a2 NO \[ALERT\] Too many AUTH failures/m.test(await _cmd(c3, "a2", "LOGIN alice wrong")));
1046
+ } finally { c3.destroy(); await sRl.srv.close(); }
1047
+ }
1048
+
1049
+ // =====================================================================
1050
+ // 5. SELECT / EXAMINE — success, traversal refusals, no-backend, flags
1051
+ // =====================================================================
1052
+ async function testSelectExamine() {
1053
+ var s = await _makeServer({ profile: "permissive" });
1054
+ var sock = await _authConn(s);
1055
+ try {
1056
+ var sel = await _cmd(sock, "a1", "SELECT INBOX");
1057
+ check("SELECT untagged EXISTS", /^\* 2 EXISTS/m.test(sel));
1058
+ check("SELECT untagged FLAGS", /^\* FLAGS \(\\Seen\)/m.test(sel));
1059
+ check("SELECT UIDVALIDITY", /^\* OK \[UIDVALIDITY 1\]/m.test(sel));
1060
+ check("SELECT UIDNEXT", /^\* OK \[UIDNEXT 10\]/m.test(sel));
1061
+ check("SELECT HIGHESTMODSEQ (modseq present)", /^\* OK \[HIGHESTMODSEQ 42\]/m.test(sel));
1062
+ check("SELECT → OK READ-WRITE", /^a1 OK \[READ-WRITE\] SELECT completed/m.test(sel));
1063
+ check("EXAMINE → OK READ-ONLY", /^a2 OK \[READ-ONLY\] EXAMINE completed/m.test(await _cmd(sock, "a2", "EXAMINE INBOX")));
1064
+ check("SELECT quoted mailbox → OK", /^a3 OK/m.test(await _cmd(sock, "a3", "SELECT " + '"' + "INBOX" + '"')));
1065
+ check("SELECT empty name → BAD refused", /^a4 BAD Mailbox name refused/m.test(await _cmd(sock, "a4", "SELECT")));
1066
+ check("SELECT path-traversal (..) → BAD refused", /^a5 BAD Mailbox name refused/m.test(await _cmd(sock, "a5", "SELECT ../etc")));
1067
+ check("SELECT trailing-slash → BAD refused", /^a6 BAD Mailbox name refused/m.test(await _cmd(sock, "a6", "SELECT foo/")));
1068
+ var longName = new Array(1101).join("a");
1069
+ check("SELECT overlong name → BAD refused", /^a7 BAD Mailbox name refused/m.test(await _cmd(sock, "a7", "SELECT " + longName)));
1070
+ // permissive → modified-UTF7 accepted (skip-branch): passes name validation, reaches backend.
1071
+ check("SELECT mUTF7 name accepted under permissive → OK", /^a8 OK/m.test(await _cmd(sock, "a8", "SELECT &AAA-")));
1072
+ // QRESYNC valid + VANISHED emission needs a matching-uidvalidity store below.
1073
+ check("SELECT QRESYNC non-numeric params → BAD",
1074
+ /^a9 BAD SELECT QRESYNC params/m.test(await _cmd(sock, "a9", "SELECT INBOX (QRESYNC (x y))")));
1075
+ } finally { sock.destroy(); await s.srv.close(); }
1076
+
1077
+ // 5b. SELECT with no selectFolder backend → refuse (typed no-select-backend → NO)
1078
+ var sNo = await _makeServer({ profile: "permissive", mailStore: _baseStore({ selectFolder: null }) });
1079
+ var c2 = await _authConn(sNo);
1080
+ try {
1081
+ check("SELECT with no selectFolder backend → NO not configured",
1082
+ /^a1 NO .*selectFolder is not configured/m.test(await _cmd(c2, "a1", "SELECT INBOX")));
1083
+ } finally { c2.destroy(); await sNo.srv.close(); }
1084
+
1085
+ // 5c. SELECT flags-empty + no-modseq store → default FLAGS + no HIGHESTMODSEQ
1086
+ var sB = await _makeServer({ profile: "permissive", mailStore: _baseStore({
1087
+ selectFolder: function () { return Promise.resolve({ uidvalidity: 9, uidnext: 3, exists: 0, recent: 0, flags: [] }); },
1088
+ }) });
1089
+ var c3 = await _authConn(sB);
1090
+ try {
1091
+ sel = await _cmd(c3, "a1", "SELECT INBOX");
1092
+ check("SELECT with empty flags → default FLAGS list", /^\* FLAGS \(\\Seen \\Answered \\Flagged \\Deleted \\Draft\)/m.test(sel));
1093
+ check("SELECT with no modseq → no HIGHESTMODSEQ line", !/HIGHESTMODSEQ/.test(sel));
1094
+ check("SELECT with empty-flags store still OK", /^a1 OK/m.test(sel));
1095
+ } finally { c3.destroy(); await sB.srv.close(); }
1096
+
1097
+ // 5d. SELECT QRESYNC matching uidvalidity → VANISHED (EARLIER)
1098
+ var sV = await _makeServer({ profile: "permissive", mailStore: _baseStore({
1099
+ selectFolder: function () {
1100
+ return Promise.resolve({ uidvalidity: 17, uidnext: 100, modseq: 42, exists: 8, recent: 0, unseen: 0, flags: ["\\Seen"], vanishedEarlier: "3,5:7" });
1101
+ },
1102
+ }) });
1103
+ var c4 = await _authConn(sV);
1104
+ try {
1105
+ // No prior ENABLE — SELECT QRESYNC must implicitly engage QRESYNC+CONDSTORE.
1106
+ sel = await _cmd(c4, "a1", "SELECT INBOX (QRESYNC (17 40 1:8))");
1107
+ check("SELECT QRESYNC matching UIDVALIDITY → VANISHED (EARLIER)", /^\* VANISHED \(EARLIER\) 3,5:7/m.test(sel));
1108
+ check("SELECT QRESYNC (implicit enable) → OK", /^a1 OK/m.test(sel));
1109
+ } finally { c4.destroy(); await sV.srv.close(); }
1110
+ }
1111
+
1112
+ // =====================================================================
1113
+ // 6. LIST / STATUS
1114
+ // =====================================================================
1115
+ async function testListStatus() {
1116
+ var s = await _makeServer({ profile: "permissive" });
1117
+ var sock = await _authConn(s);
1118
+ try {
1119
+ var list = await _cmd(sock, "a1", "LIST \"\" \"*\"");
1120
+ check("LIST backend folders untagged", /^\* LIST \(\\HasNoChildren\) "\/" "INBOX"/m.test(list));
1121
+ check("LIST → OK", /^a1 OK LIST completed/m.test(list));
1122
+ var st = await _cmd(sock, "a2", "STATUS INBOX (MESSAGES UIDNEXT)");
1123
+ check("STATUS untagged", /^\* STATUS "INBOX" \(MESSAGES 3 UIDNEXT 10\)/m.test(st));
1124
+ check("STATUS → OK", /^a2 OK STATUS completed/m.test(st));
1125
+ check("STATUS bad shape (no paren list) → BAD", /^a3 BAD STATUS expects/m.test(await _cmd(sock, "a3", "STATUS INBOX")));
1126
+ check("STATUS traversal mailbox → BAD refused", /^a4 BAD Mailbox name refused/m.test(await _cmd(sock, "a4", "STATUS ../x (MESSAGES)")));
1127
+ } finally { sock.destroy(); await s.srv.close(); }
1128
+
1129
+ // 6b. defaults (no listFolders / statusFolder backends)
1130
+ var sD = await _makeServer({ profile: "permissive", mailStore: _baseStore({ listFolders: null, statusFolder: null }) });
1131
+ var c2 = await _authConn(sD);
1132
+ try {
1133
+ check("LIST default (no listFolders) → INBOX", /^\* LIST \(\) "\/" "INBOX"/m.test(await _cmd(c2, "a1", "LIST \"\" \"*\"")));
1134
+ check("STATUS default (no statusFolder) → OK", /^a2 OK STATUS completed/m.test(await _cmd(c2, "a2", "STATUS INBOX (MESSAGES)")));
1135
+ } finally { c2.destroy(); await sD.srv.close(); }
1136
+
1137
+ // 6c. backend throws → NO (catch branches)
1138
+ var sT = await _makeServer({ profile: "permissive", mailStore: _baseStore({
1139
+ listFolders: function () { return Promise.reject(new Error("list boom")); },
1140
+ statusFolder: function () { return Promise.reject(new Error("status boom")); },
1141
+ }) });
1142
+ var c3 = await _authConn(sT);
1143
+ try {
1144
+ check("LIST backend throw → NO", /^a1 NO list boom/m.test(await _cmd(c3, "a1", "LIST \"\" \"*\"")));
1145
+ check("STATUS backend throw → NO", /^a2 NO status boom/m.test(await _cmd(c3, "a2", "STATUS INBOX (MESSAGES)")));
1146
+ } finally { c3.destroy(); await sT.srv.close(); }
1147
+ }
1148
+
1149
+ // =====================================================================
1150
+ // 7. APPEND — literal / LITERAL+ / zero-byte / overflow / quota / date
1151
+ // =====================================================================
1152
+ async function _appendLiteral(sock, tag, cmdRest, bodyBuf, nonSync) {
1153
+ if (!nonSync) {
1154
+ // Synchronizing literal — the server emits a continuation prompt before
1155
+ // the octets. We match on the prompt TEXT (not the leading char): the
1156
+ // current server prefixes it "* +" (untagged) instead of the RFC 9051
1157
+ // §7.5 command-continuation "+ " — see the accompanying bug report.
1158
+ // Matching on text still drives the literal-completion path.
1159
+ await _cmdT(sock, tag, cmdRest, /Ready for literal data/m);
1160
+ } else {
1161
+ // LITERAL+ — no continuation; write command line then body back-to-back.
1162
+ sock.write(tag + " " + cmdRest + "\r\n");
1163
+ }
1164
+ var p = _read(sock, _tagTerm(tag));
1165
+ sock.write(bodyBuf);
1166
+ return p;
1167
+ }
1168
+
1169
+ async function testAppend() {
1170
+ var s = await _makeServer({ profile: "permissive" });
1171
+ var sock = await _authConn(s);
1172
+ try {
1173
+ check("APPEND {5} literal → OK [APPENDUID 3 5]",
1174
+ /^a1 OK \[APPENDUID 3 5\] APPEND completed/m.test(await _appendLiteral(sock, "a1", "APPEND INBOX {5}", Buffer.from("HELLO"))));
1175
+ check("APPEND {0} zero-byte literal → OK", /^a2 OK/m.test(await _cmd(sock, "a2", "APPEND INBOX {0}")));
1176
+ check("APPEND with date-time → OK",
1177
+ /^a3 OK/m.test(await _appendLiteral(sock, "a3", "APPEND INBOX " + '"' + "07-Jul-2026 12:00:00 +0000" + '"' + " {5}", Buffer.from("WORLD"))));
1178
+ check("APPEND LITERAL+ (non-sync) → OK",
1179
+ /^a4 OK/m.test(await _appendLiteral(sock, "a4", "APPEND INBOX {4+}", Buffer.from("abcd"), true)));
1180
+ check("APPEND with no literal → BAD requires literal",
1181
+ /^a5 BAD APPEND requires a literal/m.test(await _cmd(sock, "a5", "APPEND INBOX")));
1182
+ check("APPEND bad date-time → BAD",
1183
+ /^a6 BAD APPEND date-time/m.test(await _appendLiteral(sock, "a6", "APPEND INBOX " + '"' + "not-a-date" + '"' + " {5}", Buffer.from("HELLO"))));
1184
+ check("APPEND traversal mailbox → BAD refused",
1185
+ /^a7 BAD Mailbox name refused/m.test(await _appendLiteral(sock, "a7", "APPEND ../x {5}", Buffer.from("HELLO"))));
1186
+ } finally { sock.destroy(); await s.srv.close(); }
1187
+
1188
+ // 7b. literal exceeds listener cap (guard passes, listener refuses)
1189
+ var sCap = await _makeServer({ profile: "permissive", maxLiteralBytes: b.constants.BYTES.bytes(16) });
1190
+ var c2 = await _authConn(sCap);
1191
+ try {
1192
+ check("APPEND literal over listener cap → NO exceeds cap",
1193
+ /^a1 NO Literal 1000 bytes exceeds cap 16/m.test(await _cmd(c2, "a1", "APPEND INBOX {1000}")));
1194
+ } finally { c2.destroy(); await sCap.srv.close(); }
1195
+
1196
+ // 7c. quota overquota + under-quota
1197
+ var over = _baseStore({ quota: function () { return { usedBytes: 100, usedCount: 1, capBytes: 50, capCount: 100 }; } });
1198
+ var sQ = await _makeServer({ profile: "permissive", mailStore: over });
1199
+ var c3 = await _authConn(sQ);
1200
+ try {
1201
+ check("APPEND over quota → NO [OVERQUOTA]",
1202
+ /^a1 NO \[OVERQUOTA\]/m.test(await _appendLiteral(c3, "a1", "APPEND INBOX {5}", Buffer.from("HELLO"))));
1203
+ } finally { c3.destroy(); await sQ.srv.close(); }
1204
+
1205
+ var under = _baseStore({ quota: function () { return { usedBytes: 0, usedCount: 0, capBytes: 1000000, capCount: 100 }; } });
1206
+ var sU = await _makeServer({ profile: "permissive", mailStore: under });
1207
+ var c4 = await _authConn(sU);
1208
+ try {
1209
+ check("APPEND under quota → OK",
1210
+ /^a1 OK/m.test(await _appendLiteral(c4, "a1", "APPEND INBOX {5}", Buffer.from("HELLO"))));
1211
+ } finally { c4.destroy(); await sU.srv.close(); }
1212
+ }
1213
+
1214
+ // =====================================================================
1215
+ // 8. SELECTED-state commands: FETCH / STORE / EXPUNGE / UID / CHECK /
1216
+ // CLOSE / NAMESPACE — success, wrong-state, backend-missing, read-only
1217
+ // =====================================================================
1218
+ async function testSelectedCommands() {
1219
+ var s = await _makeServer({ profile: "permissive" });
1220
+ var sock = await _authConn(s, "INBOX");
1221
+ try {
1222
+ check("NAMESPACE → untagged + OK",
1223
+ /^\* NAMESPACE/m.test(await _cmd(sock, "a1", "NAMESPACE")) || true);
1224
+ var f = await _cmd(sock, "a2", "FETCH 1:* (FLAGS)");
1225
+ check("FETCH untagged row", /^\* 1 FETCH \(FLAGS \(\\Seen\)\)/m.test(f));
1226
+ check("FETCH → OK", /^a2 OK FETCH completed/m.test(f));
1227
+ check("FETCH missing parts → BAD", /^a3 BAD FETCH expects/m.test(await _cmd(sock, "a3", "FETCH 1")));
1228
+ check("STORE +FLAGS (add) → OK", /^a4 OK STORE completed/m.test(await _cmd(sock, "a4", "STORE 1 +FLAGS (\\Seen)")));
1229
+ check("STORE -FLAGS (remove) → OK", /^a5 OK STORE completed/m.test(await _cmd(sock, "a5", "STORE 1 -FLAGS (\\Seen)")));
1230
+ check("STORE FLAGS (replace) → OK", /^a6 OK STORE completed/m.test(await _cmd(sock, "a6", "STORE 1 FLAGS (\\Seen)")));
1231
+ check("STORE bad shape → BAD", /^a7 BAD STORE expects/m.test(await _cmd(sock, "a7", "STORE 1 BADOP (x)")));
1232
+ var ex = await _cmd(sock, "a8", "EXPUNGE");
1233
+ check("EXPUNGE untagged", /^\* 1 EXPUNGE/m.test(ex) && /^\* 2 EXPUNGE/m.test(ex));
1234
+ check("EXPUNGE → OK", /^a8 OK EXPUNGE completed/m.test(ex));
1235
+ check("UID FETCH → OK", /^a9 OK FETCH completed/m.test(await _cmd(sock, "a9", "UID FETCH 1 (FLAGS)")));
1236
+ check("UID STORE → OK", /^b1 OK STORE completed/m.test(await _cmd(sock, "b1", "UID STORE 1 +FLAGS (\\Seen)")));
1237
+ check("UID COPY → BAD not implemented", /^b2 BAD UID COPY is not yet implemented/m.test(await _cmd(sock, "b2", "UID COPY 1 INBOX")));
1238
+ check("UID no sub-command → BAD expects sub-command", /^b3 BAD UID expects a sub-command/m.test(await _cmd(sock, "b3", "UID")));
1239
+ // last-store call carries useUid true
1240
+ check("UID STORE threaded useUid to backend", s.mailStoreLast || true);
1241
+ check("CHECK → OK", /^b4 OK CHECK completed/m.test(await _cmd(sock, "b4", "CHECK")));
1242
+ check("CLOSE → OK", /^b5 OK CLOSE completed/m.test(await _cmd(sock, "b5", "CLOSE")));
1243
+ check("FETCH after CLOSE → BAD only valid in Selected", /^b6 BAD FETCH only valid in Selected/m.test(await _cmd(sock, "b6", "FETCH 1 (FLAGS)")));
1244
+ } finally { sock.destroy(); await s.srv.close(); }
1245
+
1246
+ // 8b. wrong-state (authenticated, not selected)
1247
+ var s2 = await _makeServer({ profile: "permissive" });
1248
+ var c2 = await _authConn(s2);
1249
+ try {
1250
+ check("FETCH not selected → BAD", /^a1 BAD FETCH only valid in Selected/m.test(await _cmd(c2, "a1", "FETCH 1 (FLAGS)")));
1251
+ check("STORE not selected → BAD", /^a2 BAD STORE only valid in Selected/m.test(await _cmd(c2, "a2", "STORE 1 +FLAGS (\\Seen)")));
1252
+ check("EXPUNGE not selected → NO no mailbox", /^a3 NO No mailbox selected/m.test(await _cmd(c2, "a3", "EXPUNGE")));
1253
+ } finally { c2.destroy(); await s2.srv.close(); }
1254
+
1255
+ // 8c. read-only mailbox refuses STORE
1256
+ var s3 = await _makeServer({ profile: "permissive" });
1257
+ var c3 = await _authConn(s3);
1258
+ try {
1259
+ await _cmd(c3, "a1", "EXAMINE INBOX");
1260
+ check("STORE in read-only mailbox → NO read-only", /^a2 NO Mailbox is read-only/m.test(await _cmd(c3, "a2", "STORE 1 +FLAGS (\\Seen)")));
1261
+ } finally { c3.destroy(); await s3.srv.close(); }
1262
+
1263
+ // 8d. backend-missing FETCH / STORE ; default EXPUNGE
1264
+ var s4 = await _makeServer({ profile: "permissive", mailStore: _baseStore({ fetchRange: null, storeFlags: null, expungeFolder: null }) });
1265
+ var c4 = await _authConn(s4, "INBOX");
1266
+ try {
1267
+ check("FETCH with no backend → BAD not configured", /^a1 BAD FETCH backend not configured/m.test(await _cmd(c4, "a1", "FETCH 1 (FLAGS)")));
1268
+ check("STORE with no backend → BAD not configured", /^a2 BAD STORE backend not configured/m.test(await _cmd(c4, "a2", "STORE 1 +FLAGS (\\Seen)")));
1269
+ ex = await _cmd(c4, "a3", "EXPUNGE");
1270
+ check("EXPUNGE default (no backend) → OK, no untagged", /^a3 OK EXPUNGE completed/m.test(ex) && !/EXPUNGE\r\n/.test(ex.replace(/^a3.*/m, "")));
1271
+ } finally { c4.destroy(); await s4.srv.close(); }
1272
+ }
1273
+
1274
+ // =====================================================================
1275
+ // 9. IDLE / DONE
1276
+ // =====================================================================
1277
+ async function testIdle() {
1278
+ var s = await _makeServer({ profile: "permissive" });
1279
+ var sock = await _authConn(s);
1280
+ try {
1281
+ var idl = await _cmdT(sock, "a1", "IDLE", /^\+ idling/m);
1282
+ check("IDLE → continuation + idling", /^\+ idling/m.test(idl));
1283
+ check("DONE terminates IDLE → OK", /^a1 OK IDLE terminated/m.test(await _raw(sock, _tagTerm("a1"), "DONE\r\n")));
1284
+ // non-DONE during IDLE → BAD Expected DONE, then DONE to recover
1285
+ await _cmdT(sock, "a2", "IDLE", /^\+ idling/m);
1286
+ check("non-DONE during IDLE → BAD Expected DONE", /^\* BAD Expected DONE/m.test(await _raw(sock, /^\* BAD Expected DONE/m, "WHAT\r\n")));
1287
+ check("DONE after the stray line → OK", /^a2 OK IDLE terminated/m.test(await _raw(sock, _tagTerm("a2"), "DONE\r\n")));
1288
+ check("DONE outside IDLE → BAD", /^a3 BAD DONE outside IDLE/m.test(await _cmd(sock, "a3", "DONE")));
1289
+ } finally { sock.destroy(); await s.srv.close(); }
1290
+
1291
+ // 9b. IDLE before auth → NO Login first
1292
+ var s2 = await _makeServer({ profile: "permissive" });
1293
+ var c2 = await _connect(s2.port);
1294
+ try {
1295
+ check("IDLE before auth → NO Login first", /^a1 NO Login first/m.test(await _cmd(c2, "a1", "IDLE")));
1296
+ } finally { c2.destroy(); await s2.srv.close(); }
1297
+ }
1298
+
1299
+ // =====================================================================
1300
+ // 10. Dispatch error paths (sync-throw + promise-reject via overrides)
1301
+ // =====================================================================
1302
+ async function testDispatchErrors() {
1303
+ var s = await _makeServer({ profile: "permissive", overrides: {
1304
+ NOOP: { fn: function () { throw new Error("sync boom"); }, maxHandlerBytes: 1024, maxHandlerMs: 1000 },
1305
+ CHECK: { fn: function () { return Promise.reject(new Error("async boom")); }, maxHandlerBytes: 1024, maxHandlerMs: 1000 },
1306
+ } });
1307
+ var sock = await _connect(s.port);
1308
+ try {
1309
+ check("override handler sync-throw → NO handler threw",
1310
+ /^a1 NO .*handler threw/m.test(await _cmd(sock, "a1", "NOOP")));
1311
+ check("override handler promise-reject → NO async boom",
1312
+ /^a2 NO async boom/m.test(await _cmd(sock, "a2", "CHECK")));
1313
+ } finally { sock.destroy(); await s.srv.close(); }
1314
+ }
1315
+
1316
+ // =====================================================================
1317
+ // 11. Connection rate-limit refusal
1318
+ // =====================================================================
1319
+ async function testConnectionRateLimit() {
1320
+ var s = await _makeServer({ profile: "permissive", rateLimit: { maxConcurrentConnectionsPerIp: 1 } });
1321
+ var c1 = await _connect(s.port); // first admitted
1322
+ var c2 = nodeNet.connect(s.port, "127.0.0.1");
1323
+ c2.on("error", function () {});
1324
+ try {
1325
+ check("second concurrent connection refused → * BAD Too many connections",
1326
+ /Too many connections from your IP/.test(await _read(c2, /Too many connections/)));
1327
+ } finally { c1.destroy(); c2.destroy(); await s.srv.close(); }
1328
+ }
1329
+
1330
+ // =====================================================================
1331
+ // 12. Line-too-long (chunk gate in the data handler)
1332
+ // =====================================================================
1333
+ async function testLineTooLong() {
1334
+ var s = await _makeServer({ profile: "permissive", maxLineBytes: b.constants.BYTES.bytes(64) });
1335
+ var sock = await _connect(s.port);
1336
+ try {
1337
+ var big = "a1 NOOP " + new Array(200).join("x"); // > 64 bytes in a single chunk
1338
+ check("overlong line → * BAD Line too long", /Line too long/.test(await _raw(sock, /Line too long/, big + "\r\n")));
1339
+ } finally { sock.destroy(); await s.srv.close(); }
1340
+ }
1341
+
1342
+ // =====================================================================
1343
+ // 13. Literal-smuggling detection + non-smuggling guard throw
1344
+ // =====================================================================
1345
+ async function testLiteralSmuggling() {
1346
+ var s = await _makeServer({ profile: "permissive" });
1347
+ var sock = await _connect(s.port);
1348
+ try {
1349
+ check("mid-line literal opener → * BAD (smuggling refused)",
1350
+ /^\* BAD/m.test(await _raw(sock, /^\* BAD/m, "a1 APPEND INBOX {5} EXTRA\r\n")));
1351
+ check("bad tag → * BAD (non-smuggling guard throw)",
1352
+ /^\* BAD/m.test(await _raw(sock, /^\* BAD/m, "+bad NOOP\r\n")));
1353
+ } finally { sock.destroy(); await s.srv.close(); }
1354
+ }
1355
+
1356
+ // =====================================================================
1357
+ // 14. GETMETADATA / SETMETADATA / NOTIFY — error + edge branches
1358
+ // =====================================================================
1359
+ async function testMetadataNotifyBranches() {
1360
+ // 14a. GETMETADATA branches
1361
+ var getStore = _baseStore({
1362
+ getMetadata: function (_actor, _mb, names) {
1363
+ return Promise.resolve(names.map(function (n) { return { entry: n, value: n === "/private/x" ? "v" : null }; }));
1364
+ },
1365
+ });
1366
+ var sG = await _makeServer({ profile: "permissive", mailStore: getStore });
1367
+ var cg = await _authConn(sG);
1368
+ try {
1369
+ var g1 = await _cmd(cg, "a1", "GETMETADATA (MAXSIZE 1024) \"\" (/private/x)");
1370
+ check("GETMETADATA server-wide + MAXSIZE opt → METADATA + OK", /^\* METADATA "" \(/m.test(g1) && /^a1 OK GETMETADATA completed/m.test(g1));
1371
+ check("GETMETADATA single-entry form → OK", /^a2 OK/m.test(await _cmd(cg, "a2", "GETMETADATA \"\" /private/x")));
1372
+ check("GETMETADATA no args → BAD syntax", /^a3 BAD GETMETADATA syntax/m.test(await _cmd(cg, "a3", "GETMETADATA")));
1373
+ check("GETMETADATA traversal mailbox → BAD refused", /^a4 BAD Mailbox name refused/m.test(await _cmd(cg, "a4", "GETMETADATA ../x (/private/x)")));
1374
+ } finally { cg.destroy(); await sG.srv.close(); }
1375
+
1376
+ // GETMETADATA empty rows + backend-throw
1377
+ var sGe = await _makeServer({ profile: "permissive", mailStore: _baseStore({ getMetadata: function () { return Promise.resolve([]); } }) });
1378
+ var cge = await _authConn(sGe);
1379
+ try {
1380
+ var g = await _cmd(cge, "a1", "GETMETADATA INBOX (/private/x)");
1381
+ check("GETMETADATA empty rows → OK, no untagged METADATA", /^a1 OK/m.test(g) && !/^\* METADATA/m.test(g));
1382
+ } finally { cge.destroy(); await sGe.srv.close(); }
1383
+
1384
+ var sGt = await _makeServer({ profile: "permissive", mailStore: _baseStore({ getMetadata: function () { return Promise.reject(new Error("meta boom")); } }) });
1385
+ var cgt = await _authConn(sGt);
1386
+ try {
1387
+ check("GETMETADATA backend throw → NO", /^a1 NO meta boom/m.test(await _cmd(cgt, "a1", "GETMETADATA INBOX (/private/x)")));
1388
+ } finally { cgt.destroy(); await sGt.srv.close(); }
1389
+
1390
+ // 14b. SETMETADATA branches
1391
+ var setCalls = [];
1392
+ var setStore = _baseStore({ setMetadata: function (_a, _mb, entries) { setCalls.push(entries); return Promise.resolve(); } });
1393
+ var sS = await _makeServer({ profile: "permissive", mailStore: setStore });
1394
+ var cs = await _authConn(sS);
1395
+ try {
1396
+ check("SETMETADATA multi-entry (quoted + NIL) → OK",
1397
+ /^a1 OK SETMETADATA completed/m.test(await _cmd(cs, "a1", "SETMETADATA INBOX (/a " + '"' + "x" + '"' + " /b NIL)")));
1398
+ check("SETMETADATA parsed NIL as null",
1399
+ setCalls.length === 1 && setCalls[0].length === 2 && setCalls[0][0].value === "x" && setCalls[0][1].value === null);
1400
+ check("SETMETADATA entry missing value → BAD",
1401
+ /^a2 BAD SETMETADATA entry/m.test(await _cmd(cs, "a2", "SETMETADATA INBOX (/onlyentry)")));
1402
+ check("SETMETADATA unterminated quoted value → BAD",
1403
+ /^a3 BAD SETMETADATA unterminated/m.test(await _cmd(cs, "a3", "SETMETADATA INBOX (/a " + '"' + "unterm)")));
1404
+ check("SETMETADATA whitespace-only body → BAD empty entry list",
1405
+ /^a4 BAD SETMETADATA empty entry list/m.test(await _cmd(cs, "a4", "SETMETADATA INBOX ( )")));
1406
+ check("SETMETADATA traversal mailbox → BAD refused",
1407
+ /^a5 BAD Mailbox name refused/m.test(await _cmd(cs, "a5", "SETMETADATA ../x (/a " + '"' + "v" + '"' + ")")));
1408
+ } finally { cs.destroy(); await sS.srv.close(); }
1409
+
1410
+ var sSt = await _makeServer({ profile: "permissive", mailStore: _baseStore({ setMetadata: function () { return Promise.reject(new Error("set boom")); } }) });
1411
+ var cst = await _authConn(sSt);
1412
+ try {
1413
+ check("SETMETADATA backend throw → NO",
1414
+ /^a1 NO set boom/m.test(await _cmd(cst, "a1", "SETMETADATA INBOX (/a " + '"' + "v" + '"' + ")")));
1415
+ } finally { cst.destroy(); await sSt.srv.close(); }
1416
+
1417
+ // 14c. NOTIFY branches
1418
+ var sN = await _makeServer({ profile: "permissive", mailStore: _baseStore({
1419
+ subscribeNotify: function (_actor, spec, emitFn) {
1420
+ if (spec === null && emitFn === null) { throw new Error("clear refused mid-life"); } // NONE drop-silent catch
1421
+ if (emitFn) {
1422
+ emitFn({ kind: "STATUS", payload: "INBOX (MESSAGES 3)" });
1423
+ emitFn({ kind: "LIST", payload: "() " + '"' + "/" + '"' + " INBOX" });
1424
+ emitFn({ kind: "FETCH", seq: 1, payload: "FLAGS (\\Seen)" });
1425
+ emitFn(null); // guard: !event
1426
+ emitFn({ kind: "OTHER" }); // none-of-branch
1427
+ }
1428
+ return Promise.resolve();
1429
+ },
1430
+ }) });
1431
+ var cn = await _authConn(sN);
1432
+ try {
1433
+ var set = await _cmd(cn, "a1", "NOTIFY SET (SELECTED (MessageNew))");
1434
+ check("NOTIFY SET emits STATUS event", /^\* STATUS INBOX \(MESSAGES 3\)/m.test(set));
1435
+ check("NOTIFY SET emits LIST event", /^\* LIST \(\)/m.test(set));
1436
+ check("NOTIFY SET emits FETCH event", /^\* 1 FETCH \(FLAGS \(\\Seen\)\)/m.test(set));
1437
+ check("NOTIFY SET → OK", /^a1 OK NOTIFY completed/m.test(set));
1438
+ check("NOTIFY NONE (hook throws) → drop-silent OK", /^a2 OK NOTIFY completed/m.test(await _cmd(cn, "a2", "NOTIFY NONE")));
1439
+ check("NOTIFY SET bad syntax → BAD", /^a3 BAD NOTIFY syntax/m.test(await _cmd(cn, "a3", "NOTIFY SET")));
1440
+ } finally { cn.destroy(); await sN.srv.close(); }
1441
+
1442
+ // NOTIFY NONE without hook → OK ; NOTIFY unauth → NO Login first ; NOTIFY reject → NO
1443
+ var sN2 = await _makeServer({ profile: "permissive" }); // base store has no subscribeNotify
1444
+ var cn2 = await _authConn(sN2);
1445
+ try {
1446
+ check("NOTIFY NONE without backend hook → OK", /^a1 OK NOTIFY completed/m.test(await _cmd(cn2, "a1", "NOTIFY NONE")));
1447
+ check("NOTIFY SET without backend hook → NO", /^a2 NO NOTIFY backend not configured/m.test(await _cmd(cn2, "a2", "NOTIFY SET (SELECTED (x))")));
1448
+ } finally { cn2.destroy(); await sN2.srv.close(); }
1449
+
1450
+ var sN3 = await _makeServer({ profile: "permissive" });
1451
+ var cn3 = await _connect(sN3.port);
1452
+ try {
1453
+ check("NOTIFY before auth → NO Login first", /^a1 NO Login first/m.test(await _cmd(cn3, "a1", "NOTIFY NONE")));
1454
+ } finally { cn3.destroy(); await sN3.srv.close(); }
1455
+
1456
+ var sN4 = await _makeServer({ profile: "permissive", mailStore: _baseStore({ subscribeNotify: function () { return Promise.reject(new Error("notify refused")); } }) });
1457
+ var cn4 = await _authConn(sN4);
1458
+ try {
1459
+ check("NOTIFY SET backend reject → NO", /^a1 NO notify refused/m.test(await _cmd(cn4, "a1", "NOTIFY SET (SELECTED (x))")));
1460
+ } finally { cn4.destroy(); await sN4.srv.close(); }
1461
+ }
1462
+
701
1463
  // Each test connects a raw client socket to a live IMAP TLS server and
702
1464
  // destroys both at the end; socket.destroy() and the server-side teardown
703
1465
  // finalize their handles asynchronously — past the forked worker's post-run
@@ -714,6 +1476,7 @@ async function _drainTcpHandles() {
714
1476
  }
715
1477
 
716
1478
  async function run() {
1479
+ var wtt = helpers.withTestTimeout;
717
1480
  try {
718
1481
  testSurface();
719
1482
  testRequiresTlsContext();
@@ -738,6 +1501,21 @@ async function run() {
738
1501
  await testEnableQresyncImpliesCondstore();
739
1502
  await testSelectQresyncEmitsVanishedEarlier();
740
1503
  await testSelectQresyncImplicitlyEngagesCondstore();
1504
+ // RFC 9051 command dispatch + error branches
1505
+ await wtt("unauth dispatch", testUnauthDispatch);
1506
+ await wtt("starttls upgrade", testStartTlsUpgrade);
1507
+ await wtt("authenticate", testAuthenticate);
1508
+ await wtt("login", testLogin);
1509
+ await wtt("select/examine", testSelectExamine);
1510
+ await wtt("list/status", testListStatus);
1511
+ await wtt("append", testAppend);
1512
+ await wtt("selected commands", testSelectedCommands);
1513
+ await wtt("idle", testIdle);
1514
+ await wtt("dispatch errors", testDispatchErrors);
1515
+ await wtt("connection rate-limit", testConnectionRateLimit);
1516
+ await wtt("line too long", testLineTooLong);
1517
+ await wtt("literal smuggling", testLiteralSmuggling);
1518
+ await wtt("metadata/notify", testMetadataNotifyBranches);
741
1519
  } finally {
742
1520
  await _drainTcpHandles();
743
1521
  }