@blamejs/blamejs-shop 0.0.44

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 (1220) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +17 -0
  3. package/README.md +117 -0
  4. package/SECURITY.md +139 -0
  5. package/lib/admin.js +952 -0
  6. package/lib/analytics.js +267 -0
  7. package/lib/cart.js +279 -0
  8. package/lib/catalog-import.js +344 -0
  9. package/lib/catalog.js +769 -0
  10. package/lib/checkout.js +320 -0
  11. package/lib/config.js +151 -0
  12. package/lib/customers.js +322 -0
  13. package/lib/email.js +242 -0
  14. package/lib/externaldb-d1.js +283 -0
  15. package/lib/index.js +57 -0
  16. package/lib/inventory-alerts.js +198 -0
  17. package/lib/newsletter.js +142 -0
  18. package/lib/order.js +380 -0
  19. package/lib/payment.js +318 -0
  20. package/lib/pricing.js +185 -0
  21. package/lib/r2-bridge.js +169 -0
  22. package/lib/shipping.js +185 -0
  23. package/lib/storefront.js +2160 -0
  24. package/lib/subscriptions.js +410 -0
  25. package/lib/tax.js +161 -0
  26. package/lib/theme.js +194 -0
  27. package/lib/vendor/MANIFEST.json +19 -0
  28. package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +23 -0
  29. package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +34 -0
  30. package/lib/vendor/blamejs/.clusterfuzzlite/project.yaml +16 -0
  31. package/lib/vendor/blamejs/.dockerignore +45 -0
  32. package/lib/vendor/blamejs/.gitattributes +42 -0
  33. package/lib/vendor/blamejs/.github/CODEOWNERS +4 -0
  34. package/lib/vendor/blamejs/.github/FUNDING.yml +2 -0
  35. package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/bug_report.md +58 -0
  36. package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/config.yml +8 -0
  37. package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/feature_request.md +99 -0
  38. package/lib/vendor/blamejs/.github/PULL_REQUEST_TEMPLATE.md +77 -0
  39. package/lib/vendor/blamejs/.github/dependabot.yml +37 -0
  40. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +148 -0
  41. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +107 -0
  42. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +122 -0
  43. package/lib/vendor/blamejs/.github/workflows/ci.yml +511 -0
  44. package/lib/vendor/blamejs/.github/workflows/codeql.yml +50 -0
  45. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +655 -0
  46. package/lib/vendor/blamejs/.github/workflows/release-container.yml +406 -0
  47. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +101 -0
  48. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +134 -0
  49. package/lib/vendor/blamejs/.gitignore +102 -0
  50. package/lib/vendor/blamejs/.gitleaks.toml +166 -0
  51. package/lib/vendor/blamejs/.hadolint.yaml +18 -0
  52. package/lib/vendor/blamejs/.npmrc +5 -0
  53. package/lib/vendor/blamejs/.pinact.yaml +17 -0
  54. package/lib/vendor/blamejs/ARCHITECTURE.md +158 -0
  55. package/lib/vendor/blamejs/CHANGELOG.md +1351 -0
  56. package/lib/vendor/blamejs/CODE_OF_CONDUCT.md +86 -0
  57. package/lib/vendor/blamejs/CONTRIBUTING.md +156 -0
  58. package/lib/vendor/blamejs/GOVERNANCE.md +201 -0
  59. package/lib/vendor/blamejs/LICENSE +201 -0
  60. package/lib/vendor/blamejs/LTS-CALENDAR.md +29 -0
  61. package/lib/vendor/blamejs/MIGRATING.md +29 -0
  62. package/lib/vendor/blamejs/NOTICE +81 -0
  63. package/lib/vendor/blamejs/README.md +304 -0
  64. package/lib/vendor/blamejs/SECURITY.md +432 -0
  65. package/lib/vendor/blamejs/api-snapshot.json +48709 -0
  66. package/lib/vendor/blamejs/assets/BlameJS_Logo.png +0 -0
  67. package/lib/vendor/blamejs/assets/BlameJS_Logo.svg +129 -0
  68. package/lib/vendor/blamejs/bench/README.md +77 -0
  69. package/lib/vendor/blamejs/bench/_helpers.js +70 -0
  70. package/lib/vendor/blamejs/bench/baseline.json +183 -0
  71. package/lib/vendor/blamejs/bench/crypto-hash.bench.js +19 -0
  72. package/lib/vendor/blamejs/bench/crypto-symmetric.bench.js +28 -0
  73. package/lib/vendor/blamejs/bench/run.js +140 -0
  74. package/lib/vendor/blamejs/bench/safe-json.bench.js +31 -0
  75. package/lib/vendor/blamejs/bin/blamejs.js +13 -0
  76. package/lib/vendor/blamejs/docker/caddy/Caddyfile +46 -0
  77. package/lib/vendor/blamejs/docker/coredns/Corefile +37 -0
  78. package/lib/vendor/blamejs/docker/haproxy/haproxy.cfg +52 -0
  79. package/lib/vendor/blamejs/docker/init/generate-certs.sh +118 -0
  80. package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +87 -0
  81. package/lib/vendor/blamejs/docker/mitmproxy/config.yaml +16 -0
  82. package/lib/vendor/blamejs/docker/mongo/init-tls.sh +17 -0
  83. package/lib/vendor/blamejs/docker/mysql/my.cnf +12 -0
  84. package/lib/vendor/blamejs/docker/nats/nats.conf +33 -0
  85. package/lib/vendor/blamejs/docker/postgres/init-tls.sh +17 -0
  86. package/lib/vendor/blamejs/docker/postgres/postgresql.conf +18 -0
  87. package/lib/vendor/blamejs/docker/rabbitmq/rabbitmq.conf +18 -0
  88. package/lib/vendor/blamejs/docker/redis/redis.conf +15 -0
  89. package/lib/vendor/blamejs/docker/squid/squid.conf +24 -0
  90. package/lib/vendor/blamejs/docker/syslog/syslog-ng.conf +34 -0
  91. package/lib/vendor/blamejs/docker-compose.test.yml +545 -0
  92. package/lib/vendor/blamejs/docs/cis-postgres-crosswalk.md +102 -0
  93. package/lib/vendor/blamejs/docs/cis-sqlite-equivalent.md +92 -0
  94. package/lib/vendor/blamejs/eslint.config.mjs +204 -0
  95. package/lib/vendor/blamejs/examples/wiki/Caddyfile +40 -0
  96. package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +218 -0
  97. package/lib/vendor/blamejs/examples/wiki/Dockerfile +120 -0
  98. package/lib/vendor/blamejs/examples/wiki/README.md +157 -0
  99. package/lib/vendor/blamejs/examples/wiki/cli-snapshot.json +250 -0
  100. package/lib/vendor/blamejs/examples/wiki/docker-compose.prod.yml +231 -0
  101. package/lib/vendor/blamejs/examples/wiki/docker-compose.yml +166 -0
  102. package/lib/vendor/blamejs/examples/wiki/env-snapshot.json +217 -0
  103. package/lib/vendor/blamejs/examples/wiki/lib/auto-site-entries.js +139 -0
  104. package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +555 -0
  105. package/lib/vendor/blamejs/examples/wiki/lib/harvest-cli.js +507 -0
  106. package/lib/vendor/blamejs/examples/wiki/lib/harvest-env-vars.js +435 -0
  107. package/lib/vendor/blamejs/examples/wiki/lib/harvest-errors.js +282 -0
  108. package/lib/vendor/blamejs/examples/wiki/lib/harvest-vendored-deps.js +321 -0
  109. package/lib/vendor/blamejs/examples/wiki/lib/nav.js +15 -0
  110. package/lib/vendor/blamejs/examples/wiki/lib/opts-resolver.js +75 -0
  111. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +508 -0
  112. package/lib/vendor/blamejs/examples/wiki/lib/section.js +276 -0
  113. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +587 -0
  114. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +318 -0
  115. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +122 -0
  116. package/lib/vendor/blamejs/examples/wiki/migrations/0001-pages-schema.js +74 -0
  117. package/lib/vendor/blamejs/examples/wiki/package.json +18 -0
  118. package/lib/vendor/blamejs/examples/wiki/public/img/blamejs-logo.png +0 -0
  119. package/lib/vendor/blamejs/examples/wiki/public/img/blamejs-logo.svg +129 -0
  120. package/lib/vendor/blamejs/examples/wiki/public/robots.txt +5 -0
  121. package/lib/vendor/blamejs/examples/wiki/public/vendor/MANIFEST.json +30 -0
  122. package/lib/vendor/blamejs/examples/wiki/public/vendor/prism.css +1 -0
  123. package/lib/vendor/blamejs/examples/wiki/public/vendor/prism.js +15 -0
  124. package/lib/vendor/blamejs/examples/wiki/public/wiki.css +1250 -0
  125. package/lib/vendor/blamejs/examples/wiki/routes/admin.js +366 -0
  126. package/lib/vendor/blamejs/examples/wiki/routes/integration.js +230 -0
  127. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +266 -0
  128. package/lib/vendor/blamejs/examples/wiki/scripts/backfill-module-metadata.js +214 -0
  129. package/lib/vendor/blamejs/examples/wiki/seeders/prod/0001-default-pages.js +35 -0
  130. package/lib/vendor/blamejs/examples/wiki/seeders/prod/pages/_index.js +34 -0
  131. package/lib/vendor/blamejs/examples/wiki/seeders/prod/pages/api.js +76 -0
  132. package/lib/vendor/blamejs/examples/wiki/server.js +129 -0
  133. package/lib/vendor/blamejs/examples/wiki/site.config.js +197 -0
  134. package/lib/vendor/blamejs/examples/wiki/snippets/README.md +38 -0
  135. package/lib/vendor/blamejs/examples/wiki/snippets/auth/password-hash.example.js +15 -0
  136. package/lib/vendor/blamejs/examples/wiki/src/editor.js +103 -0
  137. package/lib/vendor/blamejs/examples/wiki/src/wiki.js +349 -0
  138. package/lib/vendor/blamejs/examples/wiki/test/AUDIT.md +155 -0
  139. package/lib/vendor/blamejs/examples/wiki/test/codebase-patterns.test.js +594 -0
  140. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +741 -0
  141. package/lib/vendor/blamejs/examples/wiki/test/find-missing-pages.js +254 -0
  142. package/lib/vendor/blamejs/examples/wiki/test/integration.js +391 -0
  143. package/lib/vendor/blamejs/examples/wiki/test/validate-cli-snapshot.js +379 -0
  144. package/lib/vendor/blamejs/examples/wiki/test/validate-env-snapshot.js +346 -0
  145. package/lib/vendor/blamejs/examples/wiki/test/validate-nav-coverage.js +212 -0
  146. package/lib/vendor/blamejs/examples/wiki/test/validate-site-coverage.js +252 -0
  147. package/lib/vendor/blamejs/examples/wiki/test/validate-source-comment-blocks.js +107 -0
  148. package/lib/vendor/blamejs/examples/wiki/views/_layout.html +115 -0
  149. package/lib/vendor/blamejs/examples/wiki/views/admin/api-keys.html +51 -0
  150. package/lib/vendor/blamejs/examples/wiki/views/admin/dashboard.html +22 -0
  151. package/lib/vendor/blamejs/examples/wiki/views/admin/edit.html +17 -0
  152. package/lib/vendor/blamejs/examples/wiki/views/home.html +85 -0
  153. package/lib/vendor/blamejs/examples/wiki/views/login.html +18 -0
  154. package/lib/vendor/blamejs/examples/wiki/views/page.html +5 -0
  155. package/lib/vendor/blamejs/examples/wiki/views/partials/nav.html +13 -0
  156. package/lib/vendor/blamejs/examples/wiki/views/search.html +19 -0
  157. package/lib/vendor/blamejs/examples/wiki/wiki.config.js +15 -0
  158. package/lib/vendor/blamejs/fuzz/README.md +137 -0
  159. package/lib/vendor/blamejs/fuzz/_expected.js +35 -0
  160. package/lib/vendor/blamejs/fuzz/guard-agent-registry.fuzz.js +22 -0
  161. package/lib/vendor/blamejs/fuzz/guard-csv.fuzz.js +16 -0
  162. package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/01-basic.csv +3 -0
  163. package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/02-formula.csv +1 -0
  164. package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/03-hyperlink.csv +1 -0
  165. package/lib/vendor/blamejs/fuzz/guard-dsn.fuzz.js +22 -0
  166. package/lib/vendor/blamejs/fuzz/guard-email.fuzz.js +16 -0
  167. package/lib/vendor/blamejs/fuzz/guard-email_seed_corpus/01-basic.eml +5 -0
  168. package/lib/vendor/blamejs/fuzz/guard-envelope.fuzz.js +24 -0
  169. package/lib/vendor/blamejs/fuzz/guard-event-bus-payload.fuzz.js +24 -0
  170. package/lib/vendor/blamejs/fuzz/guard-event-bus-topic.fuzz.js +20 -0
  171. package/lib/vendor/blamejs/fuzz/guard-html.fuzz.js +16 -0
  172. package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/01-basic.html +1 -0
  173. package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/02-script.html +1 -0
  174. package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/03-event.html +1 -0
  175. package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/04-jsurl.html +1 -0
  176. package/lib/vendor/blamejs/fuzz/guard-idempotency-key.fuzz.js +20 -0
  177. package/lib/vendor/blamejs/fuzz/guard-imap-command.fuzz.js +35 -0
  178. package/lib/vendor/blamejs/fuzz/guard-jmap.fuzz.js +41 -0
  179. package/lib/vendor/blamejs/fuzz/guard-json.fuzz.js +16 -0
  180. package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/01-basic.json +1 -0
  181. package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/02-proto.json +1 -0
  182. package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/03-dupkey.json +1 -0
  183. package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/04-nan.json +1 -0
  184. package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/05-bom.json +1 -0
  185. package/lib/vendor/blamejs/fuzz/guard-list-id.fuzz.js +21 -0
  186. package/lib/vendor/blamejs/fuzz/guard-list-unsubscribe.fuzz.js +25 -0
  187. package/lib/vendor/blamejs/fuzz/guard-mail-compose.fuzz.js +22 -0
  188. package/lib/vendor/blamejs/fuzz/guard-mail-move.fuzz.js +22 -0
  189. package/lib/vendor/blamejs/fuzz/guard-mail-query.fuzz.js +27 -0
  190. package/lib/vendor/blamejs/fuzz/guard-mail-reply.fuzz.js +23 -0
  191. package/lib/vendor/blamejs/fuzz/guard-mail-sieve.fuzz.js +36 -0
  192. package/lib/vendor/blamejs/fuzz/guard-managesieve-command.fuzz.js +26 -0
  193. package/lib/vendor/blamejs/fuzz/guard-markdown.fuzz.js +16 -0
  194. package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/01-basic.md +2 -0
  195. package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/02-jsurl.md +1 -0
  196. package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/03-jsimg.md +1 -0
  197. package/lib/vendor/blamejs/fuzz/guard-message-id.fuzz.js +26 -0
  198. package/lib/vendor/blamejs/fuzz/guard-pop3-command.fuzz.js +23 -0
  199. package/lib/vendor/blamejs/fuzz/guard-posture-chain.fuzz.js +22 -0
  200. package/lib/vendor/blamejs/fuzz/guard-saga-config.fuzz.js +32 -0
  201. package/lib/vendor/blamejs/fuzz/guard-smtp-command.fuzz.js +27 -0
  202. package/lib/vendor/blamejs/fuzz/guard-snapshot-envelope.fuzz.js +22 -0
  203. package/lib/vendor/blamejs/fuzz/guard-stream-args.fuzz.js +22 -0
  204. package/lib/vendor/blamejs/fuzz/guard-svg.fuzz.js +16 -0
  205. package/lib/vendor/blamejs/fuzz/guard-svg_seed_corpus/01-basic.svg +1 -0
  206. package/lib/vendor/blamejs/fuzz/guard-svg_seed_corpus/02-script.svg +1 -0
  207. package/lib/vendor/blamejs/fuzz/guard-tenant-id.fuzz.js +20 -0
  208. package/lib/vendor/blamejs/fuzz/guard-trace-context.fuzz.js +30 -0
  209. package/lib/vendor/blamejs/fuzz/guard-xml.fuzz.js +16 -0
  210. package/lib/vendor/blamejs/fuzz/guard-xml_seed_corpus/01-basic.xml +1 -0
  211. package/lib/vendor/blamejs/fuzz/guard-xml_seed_corpus/02-xxe.xml +1 -0
  212. package/lib/vendor/blamejs/fuzz/guard-yaml.fuzz.js +16 -0
  213. package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/01-basic.yaml +2 -0
  214. package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/02-anchor.yaml +2 -0
  215. package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/03-norway.yaml +1 -0
  216. package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/04-multidoc.yaml +4 -0
  217. package/lib/vendor/blamejs/fuzz/parsers__safe-ini.fuzz.js +16 -0
  218. package/lib/vendor/blamejs/fuzz/parsers__safe-ini_seed_corpus/01-basic.ini +2 -0
  219. package/lib/vendor/blamejs/fuzz/parsers__safe-toml.fuzz.js +16 -0
  220. package/lib/vendor/blamejs/fuzz/parsers__safe-toml_seed_corpus/01-basic.toml +4 -0
  221. package/lib/vendor/blamejs/fuzz/parsers__safe-xml.fuzz.js +16 -0
  222. package/lib/vendor/blamejs/fuzz/parsers__safe-xml_seed_corpus/01-basic.xml +1 -0
  223. package/lib/vendor/blamejs/fuzz/parsers__safe-yaml.fuzz.js +16 -0
  224. package/lib/vendor/blamejs/fuzz/parsers__safe-yaml_seed_corpus/01-basic.yaml +4 -0
  225. package/lib/vendor/blamejs/fuzz/safe-decompress.fuzz.js +49 -0
  226. package/lib/vendor/blamejs/fuzz/safe-dns.fuzz.js +29 -0
  227. package/lib/vendor/blamejs/fuzz/safe-ical.fuzz.js +16 -0
  228. package/lib/vendor/blamejs/fuzz/safe-icap.fuzz.js +42 -0
  229. package/lib/vendor/blamejs/fuzz/safe-json.fuzz.js +25 -0
  230. package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/01-object.txt +1 -0
  231. package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/02-array.txt +1 -0
  232. package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/03-string.txt +1 -0
  233. package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/04-proto.txt +1 -0
  234. package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/05-deep.txt +1 -0
  235. package/lib/vendor/blamejs/fuzz/safe-jsonpath.fuzz.js +16 -0
  236. package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/01-basic.txt +1 -0
  237. package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/02-filter.txt +1 -0
  238. package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/03-deepscan.txt +1 -0
  239. package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/04-slice.txt +1 -0
  240. package/lib/vendor/blamejs/fuzz/safe-mime.fuzz.js +27 -0
  241. package/lib/vendor/blamejs/fuzz/safe-mount-info.fuzz.js +33 -0
  242. package/lib/vendor/blamejs/fuzz/safe-sieve.fuzz.js +28 -0
  243. package/lib/vendor/blamejs/fuzz/safe-smtp.fuzz.js +64 -0
  244. package/lib/vendor/blamejs/fuzz/safe-url.fuzz.js +16 -0
  245. package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/01-basic.txt +1 -0
  246. package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/02-userinfo.txt +1 -0
  247. package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/03-dangerous.txt +1 -0
  248. package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/04-data.txt +1 -0
  249. package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/05-ipv6.txt +1 -0
  250. package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/06-idn.txt +1 -0
  251. package/lib/vendor/blamejs/fuzz/safe-vcard.fuzz.js +16 -0
  252. package/lib/vendor/blamejs/index.js +678 -0
  253. package/lib/vendor/blamejs/keys/release-pqc-pub.json +7 -0
  254. package/lib/vendor/blamejs/lib/_test/crypto-fixtures.js +67 -0
  255. package/lib/vendor/blamejs/lib/a2a-tasks.js +598 -0
  256. package/lib/vendor/blamejs/lib/a2a.js +407 -0
  257. package/lib/vendor/blamejs/lib/acme.js +1448 -0
  258. package/lib/vendor/blamejs/lib/agent-audit.js +45 -0
  259. package/lib/vendor/blamejs/lib/agent-event-bus.js +382 -0
  260. package/lib/vendor/blamejs/lib/agent-idempotency.js +497 -0
  261. package/lib/vendor/blamejs/lib/agent-orchestrator.js +717 -0
  262. package/lib/vendor/blamejs/lib/agent-posture-chain.js +366 -0
  263. package/lib/vendor/blamejs/lib/agent-saga.js +321 -0
  264. package/lib/vendor/blamejs/lib/agent-snapshot.js +676 -0
  265. package/lib/vendor/blamejs/lib/agent-stream.js +269 -0
  266. package/lib/vendor/blamejs/lib/agent-tenant.js +632 -0
  267. package/lib/vendor/blamejs/lib/agent-trace.js +281 -0
  268. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +184 -0
  269. package/lib/vendor/blamejs/lib/ai-content-detect.js +268 -0
  270. package/lib/vendor/blamejs/lib/ai-input.js +201 -0
  271. package/lib/vendor/blamejs/lib/ai-model-manifest.js +363 -0
  272. package/lib/vendor/blamejs/lib/ai-pref.js +340 -0
  273. package/lib/vendor/blamejs/lib/api-key.js +721 -0
  274. package/lib/vendor/blamejs/lib/api-snapshot.js +458 -0
  275. package/lib/vendor/blamejs/lib/app-shutdown.js +557 -0
  276. package/lib/vendor/blamejs/lib/app.js +365 -0
  277. package/lib/vendor/blamejs/lib/archive.js +547 -0
  278. package/lib/vendor/blamejs/lib/arg-parser.js +697 -0
  279. package/lib/vendor/blamejs/lib/argon2-builtin.js +173 -0
  280. package/lib/vendor/blamejs/lib/asn1-der.js +424 -0
  281. package/lib/vendor/blamejs/lib/asyncapi-bindings.js +160 -0
  282. package/lib/vendor/blamejs/lib/asyncapi-traits.js +143 -0
  283. package/lib/vendor/blamejs/lib/asyncapi.js +575 -0
  284. package/lib/vendor/blamejs/lib/atomic-file.js +1023 -0
  285. package/lib/vendor/blamejs/lib/audit-chain.js +266 -0
  286. package/lib/vendor/blamejs/lib/audit-daily-review.js +389 -0
  287. package/lib/vendor/blamejs/lib/audit-sign.js +751 -0
  288. package/lib/vendor/blamejs/lib/audit-tools.js +1113 -0
  289. package/lib/vendor/blamejs/lib/audit.js +1671 -0
  290. package/lib/vendor/blamejs/lib/auth/aal.js +169 -0
  291. package/lib/vendor/blamejs/lib/auth/access-lock.js +220 -0
  292. package/lib/vendor/blamejs/lib/auth/acr-vocabulary.js +265 -0
  293. package/lib/vendor/blamejs/lib/auth/ato-kill-switch.js +112 -0
  294. package/lib/vendor/blamejs/lib/auth/auth-time-tracker.js +111 -0
  295. package/lib/vendor/blamejs/lib/auth/bot-challenge.js +573 -0
  296. package/lib/vendor/blamejs/lib/auth/ciba.js +637 -0
  297. package/lib/vendor/blamejs/lib/auth/dpop.js +516 -0
  298. package/lib/vendor/blamejs/lib/auth/elevation-grant.js +306 -0
  299. package/lib/vendor/blamejs/lib/auth/fal.js +229 -0
  300. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +681 -0
  301. package/lib/vendor/blamejs/lib/auth/jwt-external.js +519 -0
  302. package/lib/vendor/blamejs/lib/auth/jwt.js +430 -0
  303. package/lib/vendor/blamejs/lib/auth/lockout.js +449 -0
  304. package/lib/vendor/blamejs/lib/auth/oauth.js +2141 -0
  305. package/lib/vendor/blamejs/lib/auth/oid4vci.js +657 -0
  306. package/lib/vendor/blamejs/lib/auth/oid4vp.js +531 -0
  307. package/lib/vendor/blamejs/lib/auth/openid-federation.js +600 -0
  308. package/lib/vendor/blamejs/lib/auth/passkey.js +676 -0
  309. package/lib/vendor/blamejs/lib/auth/password.js +693 -0
  310. package/lib/vendor/blamejs/lib/auth/saml.js +2109 -0
  311. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-disclosure.js +95 -0
  312. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +225 -0
  313. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +197 -0
  314. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +728 -0
  315. package/lib/vendor/blamejs/lib/auth/status-list.js +272 -0
  316. package/lib/vendor/blamejs/lib/auth/step-up-policy.js +335 -0
  317. package/lib/vendor/blamejs/lib/auth/step-up.js +454 -0
  318. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +505 -0
  319. package/lib/vendor/blamejs/lib/auth-header.js +148 -0
  320. package/lib/vendor/blamejs/lib/backup/bundle.js +265 -0
  321. package/lib/vendor/blamejs/lib/backup/crypto.js +176 -0
  322. package/lib/vendor/blamejs/lib/backup/index.js +1001 -0
  323. package/lib/vendor/blamejs/lib/backup/manifest.js +443 -0
  324. package/lib/vendor/blamejs/lib/boot-gates.js +174 -0
  325. package/lib/vendor/blamejs/lib/breach-deadline.js +272 -0
  326. package/lib/vendor/blamejs/lib/break-glass.js +1753 -0
  327. package/lib/vendor/blamejs/lib/budr.js +205 -0
  328. package/lib/vendor/blamejs/lib/bundler.js +461 -0
  329. package/lib/vendor/blamejs/lib/cache-redis.js +256 -0
  330. package/lib/vendor/blamejs/lib/cache-status.js +288 -0
  331. package/lib/vendor/blamejs/lib/cache.js +1331 -0
  332. package/lib/vendor/blamejs/lib/calendar.js +1240 -0
  333. package/lib/vendor/blamejs/lib/canonical-json.js +143 -0
  334. package/lib/vendor/blamejs/lib/cdn-cache-control.js +473 -0
  335. package/lib/vendor/blamejs/lib/cert.js +763 -0
  336. package/lib/vendor/blamejs/lib/chain-writer.js +259 -0
  337. package/lib/vendor/blamejs/lib/circuit-breaker.js +101 -0
  338. package/lib/vendor/blamejs/lib/cli-helpers.js +237 -0
  339. package/lib/vendor/blamejs/lib/cli.js +2328 -0
  340. package/lib/vendor/blamejs/lib/client-hints.js +318 -0
  341. package/lib/vendor/blamejs/lib/cloud-events.js +277 -0
  342. package/lib/vendor/blamejs/lib/cluster-provider-db.js +317 -0
  343. package/lib/vendor/blamejs/lib/cluster-storage.js +351 -0
  344. package/lib/vendor/blamejs/lib/cluster.js +1017 -0
  345. package/lib/vendor/blamejs/lib/cms-codec.js +826 -0
  346. package/lib/vendor/blamejs/lib/codepoint-class.js +262 -0
  347. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +190 -0
  348. package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +205 -0
  349. package/lib/vendor/blamejs/lib/compliance-ai-act-risk.js +189 -0
  350. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +200 -0
  351. package/lib/vendor/blamejs/lib/compliance-ai-act.js +821 -0
  352. package/lib/vendor/blamejs/lib/compliance-eaa.js +204 -0
  353. package/lib/vendor/blamejs/lib/compliance-sanctions-aliases.js +167 -0
  354. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +206 -0
  355. package/lib/vendor/blamejs/lib/compliance-sanctions-fuzzy.js +297 -0
  356. package/lib/vendor/blamejs/lib/compliance-sanctions.js +569 -0
  357. package/lib/vendor/blamejs/lib/compliance.js +1558 -0
  358. package/lib/vendor/blamejs/lib/config-drift.js +426 -0
  359. package/lib/vendor/blamejs/lib/config.js +446 -0
  360. package/lib/vendor/blamejs/lib/consent.js +369 -0
  361. package/lib/vendor/blamejs/lib/constants.js +209 -0
  362. package/lib/vendor/blamejs/lib/content-credentials.js +704 -0
  363. package/lib/vendor/blamejs/lib/cookies.js +560 -0
  364. package/lib/vendor/blamejs/lib/cra-report.js +299 -0
  365. package/lib/vendor/blamejs/lib/credential-hash.js +394 -0
  366. package/lib/vendor/blamejs/lib/crypto-field.js +1017 -0
  367. package/lib/vendor/blamejs/lib/crypto-hpke-pq.js +187 -0
  368. package/lib/vendor/blamejs/lib/crypto-hpke.js +256 -0
  369. package/lib/vendor/blamejs/lib/crypto.js +1908 -0
  370. package/lib/vendor/blamejs/lib/csp.js +271 -0
  371. package/lib/vendor/blamejs/lib/csv.js +418 -0
  372. package/lib/vendor/blamejs/lib/daemon.js +481 -0
  373. package/lib/vendor/blamejs/lib/dark-patterns.js +488 -0
  374. package/lib/vendor/blamejs/lib/data-act.js +328 -0
  375. package/lib/vendor/blamejs/lib/db-collection.js +587 -0
  376. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +267 -0
  377. package/lib/vendor/blamejs/lib/db-declare-view.js +420 -0
  378. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +333 -0
  379. package/lib/vendor/blamejs/lib/db-query.js +802 -0
  380. package/lib/vendor/blamejs/lib/db-role-context.js +50 -0
  381. package/lib/vendor/blamejs/lib/db-schema.js +322 -0
  382. package/lib/vendor/blamejs/lib/db.js +3111 -0
  383. package/lib/vendor/blamejs/lib/dbsc.js +299 -0
  384. package/lib/vendor/blamejs/lib/ddl-change-control.js +523 -0
  385. package/lib/vendor/blamejs/lib/deprecate.js +377 -0
  386. package/lib/vendor/blamejs/lib/dev.js +405 -0
  387. package/lib/vendor/blamejs/lib/dora.js +402 -0
  388. package/lib/vendor/blamejs/lib/dr-runbook.js +368 -0
  389. package/lib/vendor/blamejs/lib/dsr.js +1188 -0
  390. package/lib/vendor/blamejs/lib/dual-control.js +526 -0
  391. package/lib/vendor/blamejs/lib/early-hints.js +212 -0
  392. package/lib/vendor/blamejs/lib/error-page.js +420 -0
  393. package/lib/vendor/blamejs/lib/events.js +214 -0
  394. package/lib/vendor/blamejs/lib/external-db-migrate.js +659 -0
  395. package/lib/vendor/blamejs/lib/external-db.js +1877 -0
  396. package/lib/vendor/blamejs/lib/fapi2.js +394 -0
  397. package/lib/vendor/blamejs/lib/fda-21cfr11.js +395 -0
  398. package/lib/vendor/blamejs/lib/fdx.js +370 -0
  399. package/lib/vendor/blamejs/lib/fedcm.js +264 -0
  400. package/lib/vendor/blamejs/lib/file-type.js +360 -0
  401. package/lib/vendor/blamejs/lib/file-upload.js +1256 -0
  402. package/lib/vendor/blamejs/lib/flag-cache.js +136 -0
  403. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +135 -0
  404. package/lib/vendor/blamejs/lib/flag-providers.js +279 -0
  405. package/lib/vendor/blamejs/lib/flag-targeting.js +210 -0
  406. package/lib/vendor/blamejs/lib/flag.js +346 -0
  407. package/lib/vendor/blamejs/lib/forms.js +525 -0
  408. package/lib/vendor/blamejs/lib/framework-error.js +724 -0
  409. package/lib/vendor/blamejs/lib/framework-schema.js +845 -0
  410. package/lib/vendor/blamejs/lib/framework-sha1-hibp.js +34 -0
  411. package/lib/vendor/blamejs/lib/fsm.js +469 -0
  412. package/lib/vendor/blamejs/lib/gate-contract.js +1661 -0
  413. package/lib/vendor/blamejs/lib/gdpr-ropa.js +261 -0
  414. package/lib/vendor/blamejs/lib/graphql-federation.js +234 -0
  415. package/lib/vendor/blamejs/lib/guard-agent-registry.js +179 -0
  416. package/lib/vendor/blamejs/lib/guard-all.js +555 -0
  417. package/lib/vendor/blamejs/lib/guard-archive.js +901 -0
  418. package/lib/vendor/blamejs/lib/guard-auth.js +451 -0
  419. package/lib/vendor/blamejs/lib/guard-cidr.js +676 -0
  420. package/lib/vendor/blamejs/lib/guard-csv.js +1176 -0
  421. package/lib/vendor/blamejs/lib/guard-domain.js +814 -0
  422. package/lib/vendor/blamejs/lib/guard-dsn.js +382 -0
  423. package/lib/vendor/blamejs/lib/guard-email.js +951 -0
  424. package/lib/vendor/blamejs/lib/guard-envelope.js +294 -0
  425. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +217 -0
  426. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +150 -0
  427. package/lib/vendor/blamejs/lib/guard-filename.js +956 -0
  428. package/lib/vendor/blamejs/lib/guard-graphql.js +731 -0
  429. package/lib/vendor/blamejs/lib/guard-html-wcag-aria.js +164 -0
  430. package/lib/vendor/blamejs/lib/guard-html-wcag-forms.js +144 -0
  431. package/lib/vendor/blamejs/lib/guard-html-wcag-tables.js +154 -0
  432. package/lib/vendor/blamejs/lib/guard-html-wcag-tagwalk.js +44 -0
  433. package/lib/vendor/blamejs/lib/guard-html-wcag.js +470 -0
  434. package/lib/vendor/blamejs/lib/guard-html.js +1209 -0
  435. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +151 -0
  436. package/lib/vendor/blamejs/lib/guard-image.js +584 -0
  437. package/lib/vendor/blamejs/lib/guard-imap-command.js +337 -0
  438. package/lib/vendor/blamejs/lib/guard-jmap.js +321 -0
  439. package/lib/vendor/blamejs/lib/guard-json.js +935 -0
  440. package/lib/vendor/blamejs/lib/guard-jsonpath.js +512 -0
  441. package/lib/vendor/blamejs/lib/guard-jwt.js +772 -0
  442. package/lib/vendor/blamejs/lib/guard-list-id.js +318 -0
  443. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +412 -0
  444. package/lib/vendor/blamejs/lib/guard-mail-compose.js +282 -0
  445. package/lib/vendor/blamejs/lib/guard-mail-move.js +202 -0
  446. package/lib/vendor/blamejs/lib/guard-mail-query.js +310 -0
  447. package/lib/vendor/blamejs/lib/guard-mail-reply.js +172 -0
  448. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +207 -0
  449. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +566 -0
  450. package/lib/vendor/blamejs/lib/guard-markdown.js +768 -0
  451. package/lib/vendor/blamejs/lib/guard-message-id.js +267 -0
  452. package/lib/vendor/blamejs/lib/guard-mime.js +609 -0
  453. package/lib/vendor/blamejs/lib/guard-oauth.js +650 -0
  454. package/lib/vendor/blamejs/lib/guard-pdf.js +569 -0
  455. package/lib/vendor/blamejs/lib/guard-pop3-command.js +317 -0
  456. package/lib/vendor/blamejs/lib/guard-posture-chain.js +201 -0
  457. package/lib/vendor/blamejs/lib/guard-regex.js +632 -0
  458. package/lib/vendor/blamejs/lib/guard-saga-config.js +157 -0
  459. package/lib/vendor/blamejs/lib/guard-shell.js +522 -0
  460. package/lib/vendor/blamejs/lib/guard-smtp-command.js +594 -0
  461. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +168 -0
  462. package/lib/vendor/blamejs/lib/guard-stream-args.js +166 -0
  463. package/lib/vendor/blamejs/lib/guard-svg.js +1163 -0
  464. package/lib/vendor/blamejs/lib/guard-template.js +490 -0
  465. package/lib/vendor/blamejs/lib/guard-tenant-id.js +138 -0
  466. package/lib/vendor/blamejs/lib/guard-time.js +586 -0
  467. package/lib/vendor/blamejs/lib/guard-trace-context.js +172 -0
  468. package/lib/vendor/blamejs/lib/guard-uuid.js +548 -0
  469. package/lib/vendor/blamejs/lib/guard-xml.js +666 -0
  470. package/lib/vendor/blamejs/lib/guard-yaml.js +726 -0
  471. package/lib/vendor/blamejs/lib/hal.js +125 -0
  472. package/lib/vendor/blamejs/lib/handlers.js +350 -0
  473. package/lib/vendor/blamejs/lib/honeytoken.js +168 -0
  474. package/lib/vendor/blamejs/lib/html-balance.js +347 -0
  475. package/lib/vendor/blamejs/lib/http-client-cache.js +923 -0
  476. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +519 -0
  477. package/lib/vendor/blamejs/lib/http-client.js +2152 -0
  478. package/lib/vendor/blamejs/lib/http-message-signature.js +589 -0
  479. package/lib/vendor/blamejs/lib/http2-teardown.js +34 -0
  480. package/lib/vendor/blamejs/lib/i18n-messageformat.js +398 -0
  481. package/lib/vendor/blamejs/lib/i18n.js +931 -0
  482. package/lib/vendor/blamejs/lib/iab-mspa.js +257 -0
  483. package/lib/vendor/blamejs/lib/iab-tcf.js +461 -0
  484. package/lib/vendor/blamejs/lib/importmap-integrity.js +90 -0
  485. package/lib/vendor/blamejs/lib/inbox.js +435 -0
  486. package/lib/vendor/blamejs/lib/incident-report.js +314 -0
  487. package/lib/vendor/blamejs/lib/ip-utils.js +102 -0
  488. package/lib/vendor/blamejs/lib/jobs.js +185 -0
  489. package/lib/vendor/blamejs/lib/jose-jwe-experimental.js +228 -0
  490. package/lib/vendor/blamejs/lib/jsonapi.js +230 -0
  491. package/lib/vendor/blamejs/lib/keychain.js +865 -0
  492. package/lib/vendor/blamejs/lib/lazy-require.js +48 -0
  493. package/lib/vendor/blamejs/lib/legal-hold.js +374 -0
  494. package/lib/vendor/blamejs/lib/local-db-thin.js +321 -0
  495. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +369 -0
  496. package/lib/vendor/blamejs/lib/log-stream-local.js +146 -0
  497. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +410 -0
  498. package/lib/vendor/blamejs/lib/log-stream-otlp.js +286 -0
  499. package/lib/vendor/blamejs/lib/log-stream-syslog.js +310 -0
  500. package/lib/vendor/blamejs/lib/log-stream-webhook.js +199 -0
  501. package/lib/vendor/blamejs/lib/log-stream.js +584 -0
  502. package/lib/vendor/blamejs/lib/log.js +625 -0
  503. package/lib/vendor/blamejs/lib/lro.js +200 -0
  504. package/lib/vendor/blamejs/lib/mail-agent.js +786 -0
  505. package/lib/vendor/blamejs/lib/mail-arc-sign.js +417 -0
  506. package/lib/vendor/blamejs/lib/mail-arf.js +343 -0
  507. package/lib/vendor/blamejs/lib/mail-auth.js +2144 -0
  508. package/lib/vendor/blamejs/lib/mail-bimi.js +1047 -0
  509. package/lib/vendor/blamejs/lib/mail-bounce.js +955 -0
  510. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +1286 -0
  511. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +789 -0
  512. package/lib/vendor/blamejs/lib/mail-crypto.js +108 -0
  513. package/lib/vendor/blamejs/lib/mail-dav.js +1224 -0
  514. package/lib/vendor/blamejs/lib/mail-deploy.js +1119 -0
  515. package/lib/vendor/blamejs/lib/mail-dkim.js +1250 -0
  516. package/lib/vendor/blamejs/lib/mail-greylist.js +448 -0
  517. package/lib/vendor/blamejs/lib/mail-helo.js +473 -0
  518. package/lib/vendor/blamejs/lib/mail-journal.js +435 -0
  519. package/lib/vendor/blamejs/lib/mail-mdn.js +424 -0
  520. package/lib/vendor/blamejs/lib/mail-rbl.js +392 -0
  521. package/lib/vendor/blamejs/lib/mail-require-tls.js +198 -0
  522. package/lib/vendor/blamejs/lib/mail-scan.js +502 -0
  523. package/lib/vendor/blamejs/lib/mail-send-deliver.js +629 -0
  524. package/lib/vendor/blamejs/lib/mail-server-imap.js +1858 -0
  525. package/lib/vendor/blamejs/lib/mail-server-jmap.js +1565 -0
  526. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +908 -0
  527. package/lib/vendor/blamejs/lib/mail-server-mx.js +969 -0
  528. package/lib/vendor/blamejs/lib/mail-server-pop3.js +915 -0
  529. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +315 -0
  530. package/lib/vendor/blamejs/lib/mail-server-registry.js +378 -0
  531. package/lib/vendor/blamejs/lib/mail-server-submission.js +1396 -0
  532. package/lib/vendor/blamejs/lib/mail-server-tls.js +445 -0
  533. package/lib/vendor/blamejs/lib/mail-sieve.js +557 -0
  534. package/lib/vendor/blamejs/lib/mail-spam-score.js +284 -0
  535. package/lib/vendor/blamejs/lib/mail-srs.js +248 -0
  536. package/lib/vendor/blamejs/lib/mail-store-fts.js +394 -0
  537. package/lib/vendor/blamejs/lib/mail-store.js +929 -0
  538. package/lib/vendor/blamejs/lib/mail-unsubscribe.js +400 -0
  539. package/lib/vendor/blamejs/lib/mail.js +1971 -0
  540. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +473 -0
  541. package/lib/vendor/blamejs/lib/mcp.js +950 -0
  542. package/lib/vendor/blamejs/lib/metrics.js +1503 -0
  543. package/lib/vendor/blamejs/lib/middleware/age-gate.js +177 -0
  544. package/lib/vendor/blamejs/lib/middleware/ai-act-disclosure.js +203 -0
  545. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +981 -0
  546. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +137 -0
  547. package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +171 -0
  548. package/lib/vendor/blamejs/lib/middleware/attach-user.js +220 -0
  549. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +293 -0
  550. package/lib/vendor/blamejs/lib/middleware/body-parser.js +1519 -0
  551. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +183 -0
  552. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +217 -0
  553. package/lib/vendor/blamejs/lib/middleware/clear-site-data.js +122 -0
  554. package/lib/vendor/blamejs/lib/middleware/compose-pipeline.js +355 -0
  555. package/lib/vendor/blamejs/lib/middleware/compression.js +489 -0
  556. package/lib/vendor/blamejs/lib/middleware/cookies.js +130 -0
  557. package/lib/vendor/blamejs/lib/middleware/cors.js +386 -0
  558. package/lib/vendor/blamejs/lib/middleware/csp-nonce.js +388 -0
  559. package/lib/vendor/blamejs/lib/middleware/csp-report.js +167 -0
  560. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +499 -0
  561. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +243 -0
  562. package/lib/vendor/blamejs/lib/middleware/db-role-for.js +304 -0
  563. package/lib/vendor/blamejs/lib/middleware/dpop.js +402 -0
  564. package/lib/vendor/blamejs/lib/middleware/error-handler.js +69 -0
  565. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +168 -0
  566. package/lib/vendor/blamejs/lib/middleware/flag-context.js +110 -0
  567. package/lib/vendor/blamejs/lib/middleware/gpc.js +153 -0
  568. package/lib/vendor/blamejs/lib/middleware/headers.js +242 -0
  569. package/lib/vendor/blamejs/lib/middleware/health.js +438 -0
  570. package/lib/vendor/blamejs/lib/middleware/host-allowlist.js +189 -0
  571. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +964 -0
  572. package/lib/vendor/blamejs/lib/middleware/index.js +183 -0
  573. package/lib/vendor/blamejs/lib/middleware/nel.js +214 -0
  574. package/lib/vendor/blamejs/lib/middleware/network-allowlist.js +237 -0
  575. package/lib/vendor/blamejs/lib/middleware/no-cache.js +106 -0
  576. package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +177 -0
  577. package/lib/vendor/blamejs/lib/middleware/protected-resource-metadata.js +277 -0
  578. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +556 -0
  579. package/lib/vendor/blamejs/lib/middleware/request-id.js +79 -0
  580. package/lib/vendor/blamejs/lib/middleware/request-log.js +205 -0
  581. package/lib/vendor/blamejs/lib/middleware/require-aal.js +138 -0
  582. package/lib/vendor/blamejs/lib/middleware/require-auth.js +144 -0
  583. package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +290 -0
  584. package/lib/vendor/blamejs/lib/middleware/require-content-type.js +113 -0
  585. package/lib/vendor/blamejs/lib/middleware/require-methods.js +97 -0
  586. package/lib/vendor/blamejs/lib/middleware/require-mtls.js +212 -0
  587. package/lib/vendor/blamejs/lib/middleware/require-step-up.js +226 -0
  588. package/lib/vendor/blamejs/lib/middleware/scim-server.js +375 -0
  589. package/lib/vendor/blamejs/lib/middleware/security-headers.js +285 -0
  590. package/lib/vendor/blamejs/lib/middleware/security-txt.js +170 -0
  591. package/lib/vendor/blamejs/lib/middleware/span-http-server.js +280 -0
  592. package/lib/vendor/blamejs/lib/middleware/speculation-rules.js +323 -0
  593. package/lib/vendor/blamejs/lib/middleware/sse.js +200 -0
  594. package/lib/vendor/blamejs/lib/middleware/trace-log-correlation.js +167 -0
  595. package/lib/vendor/blamejs/lib/middleware/trace-propagate.js +148 -0
  596. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +749 -0
  597. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +164 -0
  598. package/lib/vendor/blamejs/lib/migration-files.js +37 -0
  599. package/lib/vendor/blamejs/lib/migrations.js +385 -0
  600. package/lib/vendor/blamejs/lib/mime-parse.js +198 -0
  601. package/lib/vendor/blamejs/lib/money.js +699 -0
  602. package/lib/vendor/blamejs/lib/mtls-ca.js +572 -0
  603. package/lib/vendor/blamejs/lib/mtls-engine-default.js +501 -0
  604. package/lib/vendor/blamejs/lib/network-byte-quota.js +308 -0
  605. package/lib/vendor/blamejs/lib/network-dns-resolver.js +533 -0
  606. package/lib/vendor/blamejs/lib/network-dns.js +1930 -0
  607. package/lib/vendor/blamejs/lib/network-heartbeat.js +425 -0
  608. package/lib/vendor/blamejs/lib/network-nts.js +574 -0
  609. package/lib/vendor/blamejs/lib/network-proxy.js +265 -0
  610. package/lib/vendor/blamejs/lib/network-smtp-policy.js +836 -0
  611. package/lib/vendor/blamejs/lib/network-tls.js +3126 -0
  612. package/lib/vendor/blamejs/lib/network.js +346 -0
  613. package/lib/vendor/blamejs/lib/nis2-report.js +181 -0
  614. package/lib/vendor/blamejs/lib/nist-crosswalk.js +293 -0
  615. package/lib/vendor/blamejs/lib/nonce-store.js +177 -0
  616. package/lib/vendor/blamejs/lib/notify.js +683 -0
  617. package/lib/vendor/blamejs/lib/ntp-check.js +458 -0
  618. package/lib/vendor/blamejs/lib/numeric-bounds.js +111 -0
  619. package/lib/vendor/blamejs/lib/numeric-checks.js +40 -0
  620. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +349 -0
  621. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +488 -0
  622. package/lib/vendor/blamejs/lib/object-store/gcs-bucket-ops.js +351 -0
  623. package/lib/vendor/blamejs/lib/object-store/gcs.js +515 -0
  624. package/lib/vendor/blamejs/lib/object-store/http-put.js +153 -0
  625. package/lib/vendor/blamejs/lib/object-store/http-request.js +38 -0
  626. package/lib/vendor/blamejs/lib/object-store/index.js +197 -0
  627. package/lib/vendor/blamejs/lib/object-store/local.js +163 -0
  628. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +1133 -0
  629. package/lib/vendor/blamejs/lib/object-store/sigv4.js +957 -0
  630. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +420 -0
  631. package/lib/vendor/blamejs/lib/observability-tracer.js +395 -0
  632. package/lib/vendor/blamejs/lib/observability.js +720 -0
  633. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +248 -0
  634. package/lib/vendor/blamejs/lib/openapi-schema-walk.js +192 -0
  635. package/lib/vendor/blamejs/lib/openapi-security.js +169 -0
  636. package/lib/vendor/blamejs/lib/openapi-yaml.js +154 -0
  637. package/lib/vendor/blamejs/lib/openapi.js +489 -0
  638. package/lib/vendor/blamejs/lib/otel-export.js +278 -0
  639. package/lib/vendor/blamejs/lib/outbox.js +547 -0
  640. package/lib/vendor/blamejs/lib/pagination.js +542 -0
  641. package/lib/vendor/blamejs/lib/parsers/index.js +91 -0
  642. package/lib/vendor/blamejs/lib/parsers/safe-env.js +642 -0
  643. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +293 -0
  644. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +784 -0
  645. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +390 -0
  646. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +1015 -0
  647. package/lib/vendor/blamejs/lib/permissions.js +793 -0
  648. package/lib/vendor/blamejs/lib/pick.js +105 -0
  649. package/lib/vendor/blamejs/lib/pqc-agent.js +351 -0
  650. package/lib/vendor/blamejs/lib/pqc-gate.js +279 -0
  651. package/lib/vendor/blamejs/lib/pqc-software.js +271 -0
  652. package/lib/vendor/blamejs/lib/problem-details.js +482 -0
  653. package/lib/vendor/blamejs/lib/process-spawn.js +196 -0
  654. package/lib/vendor/blamejs/lib/promise-pool.js +162 -0
  655. package/lib/vendor/blamejs/lib/protobuf-encoder.js +190 -0
  656. package/lib/vendor/blamejs/lib/protocol-dispatcher.js +161 -0
  657. package/lib/vendor/blamejs/lib/public-suffix.js +403 -0
  658. package/lib/vendor/blamejs/lib/pubsub-cluster.js +154 -0
  659. package/lib/vendor/blamejs/lib/pubsub-redis.js +167 -0
  660. package/lib/vendor/blamejs/lib/pubsub.js +463 -0
  661. package/lib/vendor/blamejs/lib/queue-local.js +476 -0
  662. package/lib/vendor/blamejs/lib/queue-redis.js +745 -0
  663. package/lib/vendor/blamejs/lib/queue-sqs.js +319 -0
  664. package/lib/vendor/blamejs/lib/queue.js +1016 -0
  665. package/lib/vendor/blamejs/lib/redact.js +1007 -0
  666. package/lib/vendor/blamejs/lib/redis-client.js +520 -0
  667. package/lib/vendor/blamejs/lib/render.js +285 -0
  668. package/lib/vendor/blamejs/lib/request-helpers.js +767 -0
  669. package/lib/vendor/blamejs/lib/resource-access-lock.js +116 -0
  670. package/lib/vendor/blamejs/lib/restore-bundle.js +340 -0
  671. package/lib/vendor/blamejs/lib/restore-rollback.js +365 -0
  672. package/lib/vendor/blamejs/lib/restore.js +409 -0
  673. package/lib/vendor/blamejs/lib/retention.js +640 -0
  674. package/lib/vendor/blamejs/lib/retry.js +523 -0
  675. package/lib/vendor/blamejs/lib/router.js +1289 -0
  676. package/lib/vendor/blamejs/lib/safe-async.js +1184 -0
  677. package/lib/vendor/blamejs/lib/safe-buffer.js +562 -0
  678. package/lib/vendor/blamejs/lib/safe-decompress.js +297 -0
  679. package/lib/vendor/blamejs/lib/safe-dns.js +665 -0
  680. package/lib/vendor/blamejs/lib/safe-ical.js +634 -0
  681. package/lib/vendor/blamejs/lib/safe-icap.js +502 -0
  682. package/lib/vendor/blamejs/lib/safe-json.js +946 -0
  683. package/lib/vendor/blamejs/lib/safe-jsonpath.js +285 -0
  684. package/lib/vendor/blamejs/lib/safe-mime.js +831 -0
  685. package/lib/vendor/blamejs/lib/safe-mount-info.js +306 -0
  686. package/lib/vendor/blamejs/lib/safe-path.js +254 -0
  687. package/lib/vendor/blamejs/lib/safe-redirect.js +106 -0
  688. package/lib/vendor/blamejs/lib/safe-schema.js +1810 -0
  689. package/lib/vendor/blamejs/lib/safe-sieve.js +684 -0
  690. package/lib/vendor/blamejs/lib/safe-smtp.js +185 -0
  691. package/lib/vendor/blamejs/lib/safe-sql.js +363 -0
  692. package/lib/vendor/blamejs/lib/safe-url.js +428 -0
  693. package/lib/vendor/blamejs/lib/safe-vcard.js +473 -0
  694. package/lib/vendor/blamejs/lib/sandbox-worker.js +135 -0
  695. package/lib/vendor/blamejs/lib/sandbox.js +358 -0
  696. package/lib/vendor/blamejs/lib/scheduler.js +827 -0
  697. package/lib/vendor/blamejs/lib/sd-notify.js +269 -0
  698. package/lib/vendor/blamejs/lib/sec-cyber.js +214 -0
  699. package/lib/vendor/blamejs/lib/security-assert.js +395 -0
  700. package/lib/vendor/blamejs/lib/seeders.js +620 -0
  701. package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +309 -0
  702. package/lib/vendor/blamejs/lib/self-update.js +804 -0
  703. package/lib/vendor/blamejs/lib/server-timing.js +174 -0
  704. package/lib/vendor/blamejs/lib/session-device-binding.js +431 -0
  705. package/lib/vendor/blamejs/lib/session-stores.js +138 -0
  706. package/lib/vendor/blamejs/lib/session.js +1162 -0
  707. package/lib/vendor/blamejs/lib/slug.js +381 -0
  708. package/lib/vendor/blamejs/lib/sse.js +349 -0
  709. package/lib/vendor/blamejs/lib/ssrf-guard.js +792 -0
  710. package/lib/vendor/blamejs/lib/standard-webhooks.js +183 -0
  711. package/lib/vendor/blamejs/lib/static.js +1249 -0
  712. package/lib/vendor/blamejs/lib/storage.js +1272 -0
  713. package/lib/vendor/blamejs/lib/stream-throttle.js +235 -0
  714. package/lib/vendor/blamejs/lib/structured-fields.js +244 -0
  715. package/lib/vendor/blamejs/lib/subject.js +667 -0
  716. package/lib/vendor/blamejs/lib/tcpa-10dlc.js +175 -0
  717. package/lib/vendor/blamejs/lib/template.js +931 -0
  718. package/lib/vendor/blamejs/lib/tenant-quota.js +545 -0
  719. package/lib/vendor/blamejs/lib/test-harness.js +275 -0
  720. package/lib/vendor/blamejs/lib/testing.js +1185 -0
  721. package/lib/vendor/blamejs/lib/time.js +578 -0
  722. package/lib/vendor/blamejs/lib/tls-exporter.js +239 -0
  723. package/lib/vendor/blamejs/lib/totp.js +318 -0
  724. package/lib/vendor/blamejs/lib/tracing.js +546 -0
  725. package/lib/vendor/blamejs/lib/uuid.js +207 -0
  726. package/lib/vendor/blamejs/lib/validate-opts.js +381 -0
  727. package/lib/vendor/blamejs/lib/vault/index.js +638 -0
  728. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +311 -0
  729. package/lib/vendor/blamejs/lib/vault/passphrase-source.js +198 -0
  730. package/lib/vendor/blamejs/lib/vault/rotate.js +803 -0
  731. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +471 -0
  732. package/lib/vendor/blamejs/lib/vault/wrap.js +296 -0
  733. package/lib/vendor/blamejs/lib/vault-aad.js +259 -0
  734. package/lib/vendor/blamejs/lib/vendor/.vendor-data-pubkey +4 -0
  735. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +161 -0
  736. package/lib/vendor/blamejs/lib/vendor/bimi-trust-anchors.data.js +68 -0
  737. package/lib/vendor/blamejs/lib/vendor/bimi-trust-anchors.pem +33 -0
  738. package/lib/vendor/blamejs/lib/vendor/common-passwords-top-10000.data.js +1325 -0
  739. package/lib/vendor/blamejs/lib/vendor/common-passwords-top-10000.txt +10002 -0
  740. package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +9 -0
  741. package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +18 -0
  742. package/lib/vendor/blamejs/lib/vendor/pki.cjs +181 -0
  743. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +16382 -0
  744. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5881 -0
  745. package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +328 -0
  746. package/lib/vendor/blamejs/lib/vendor/vendor-data-pubkey.js +16 -0
  747. package/lib/vendor/blamejs/lib/vendor-data.js +520 -0
  748. package/lib/vendor/blamejs/lib/vex.js +630 -0
  749. package/lib/vendor/blamejs/lib/watcher.js +608 -0
  750. package/lib/vendor/blamejs/lib/web-push-vapid.js +322 -0
  751. package/lib/vendor/blamejs/lib/webhook.js +977 -0
  752. package/lib/vendor/blamejs/lib/websocket-channels.js +327 -0
  753. package/lib/vendor/blamejs/lib/websocket.js +1561 -0
  754. package/lib/vendor/blamejs/lib/wiki-concepts.js +338 -0
  755. package/lib/vendor/blamejs/lib/worker-pool.js +464 -0
  756. package/lib/vendor/blamejs/lib/ws-client.js +978 -0
  757. package/lib/vendor/blamejs/lib/xml-c14n.js +506 -0
  758. package/lib/vendor/blamejs/memory/specs/node-26-map-getorinsert-migration.md +164 -0
  759. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +19 -0
  760. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/README.md +88 -0
  761. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/build.sh +26 -0
  762. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/project.yaml +28 -0
  763. package/lib/vendor/blamejs/package.json +81 -0
  764. package/lib/vendor/blamejs/release-notes/v0.0.x.json +310 -0
  765. package/lib/vendor/blamejs/release-notes/v0.1.x.json +1798 -0
  766. package/lib/vendor/blamejs/release-notes/v0.10.x.json +1288 -0
  767. package/lib/vendor/blamejs/release-notes/v0.11.x.json +2551 -0
  768. package/lib/vendor/blamejs/release-notes/v0.12.0.json +64 -0
  769. package/lib/vendor/blamejs/release-notes/v0.12.1.json +32 -0
  770. package/lib/vendor/blamejs/release-notes/v0.12.2.json +45 -0
  771. package/lib/vendor/blamejs/release-notes/v0.2.x.json +706 -0
  772. package/lib/vendor/blamejs/release-notes/v0.3.x.json +786 -0
  773. package/lib/vendor/blamejs/release-notes/v0.4.x.json +588 -0
  774. package/lib/vendor/blamejs/release-notes/v0.5.x.json +390 -0
  775. package/lib/vendor/blamejs/release-notes/v0.6.x.json +1947 -0
  776. package/lib/vendor/blamejs/release-notes/v0.7.x.json +3811 -0
  777. package/lib/vendor/blamejs/release-notes/v0.8.x.json +3318 -0
  778. package/lib/vendor/blamejs/release-notes/v0.9.x.json +2257 -0
  779. package/lib/vendor/blamejs/scripts/build-vendored-sbom.js +325 -0
  780. package/lib/vendor/blamejs/scripts/check-api-snapshot.js +62 -0
  781. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +108 -0
  782. package/lib/vendor/blamejs/scripts/check-pack-against-gitignore.js +83 -0
  783. package/lib/vendor/blamejs/scripts/check-services.js +483 -0
  784. package/lib/vendor/blamejs/scripts/check-vendor-currency.js +349 -0
  785. package/lib/vendor/blamejs/scripts/consolidate-release-notes.js +216 -0
  786. package/lib/vendor/blamejs/scripts/gen-migrating.js +275 -0
  787. package/lib/vendor/blamejs/scripts/generate-changelog-entry.js +577 -0
  788. package/lib/vendor/blamejs/scripts/generate-release-signing-key.js +79 -0
  789. package/lib/vendor/blamejs/scripts/publish-dep-confusion-placeholder.sh +101 -0
  790. package/lib/vendor/blamejs/scripts/refresh-api-snapshot.js +31 -0
  791. package/lib/vendor/blamejs/scripts/refresh-vendor-manifest.js +132 -0
  792. package/lib/vendor/blamejs/scripts/release.js +652 -0
  793. package/lib/vendor/blamejs/scripts/sha3-digest.js +62 -0
  794. package/lib/vendor/blamejs/scripts/sign-release-artifact.js +92 -0
  795. package/lib/vendor/blamejs/scripts/test-integration.js +181 -0
  796. package/lib/vendor/blamejs/scripts/test-wiki-integration.js +126 -0
  797. package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +77 -0
  798. package/lib/vendor/blamejs/scripts/vendor-data-gen.js +186 -0
  799. package/lib/vendor/blamejs/scripts/vendor-data-keygen.js +101 -0
  800. package/lib/vendor/blamejs/scripts/vendor-update.sh +278 -0
  801. package/lib/vendor/blamejs/test/00-primitives.js +19075 -0
  802. package/lib/vendor/blamejs/test/10-state.js +622 -0
  803. package/lib/vendor/blamejs/test/20-db.js +561 -0
  804. package/lib/vendor/blamejs/test/30-chain.js +2110 -0
  805. package/lib/vendor/blamejs/test/40-consumers.js +2453 -0
  806. package/lib/vendor/blamejs/test/50-integration.js +486 -0
  807. package/lib/vendor/blamejs/test/_helpers.js +10 -0
  808. package/lib/vendor/blamejs/test/_smoke-worker.js +69 -0
  809. package/lib/vendor/blamejs/test/fixtures/exploit-corpus/corpus.json +368 -0
  810. package/lib/vendor/blamejs/test/fixtures/http-client-stream-payload.txt +2 -0
  811. package/lib/vendor/blamejs/test/fixtures/worker-pool/echo.js +52 -0
  812. package/lib/vendor/blamejs/test/helpers/_codebase-shingle-worker.js +24 -0
  813. package/lib/vendor/blamejs/test/helpers/_codebase-shingle.js +203 -0
  814. package/lib/vendor/blamejs/test/helpers/_shape-match.js +513 -0
  815. package/lib/vendor/blamejs/test/helpers/check.js +36 -0
  816. package/lib/vendor/blamejs/test/helpers/cluster.js +70 -0
  817. package/lib/vendor/blamejs/test/helpers/db.js +143 -0
  818. package/lib/vendor/blamejs/test/helpers/drivers.js +207 -0
  819. package/lib/vendor/blamejs/test/helpers/fs-watch.js +101 -0
  820. package/lib/vendor/blamejs/test/helpers/http.js +14 -0
  821. package/lib/vendor/blamejs/test/helpers/index.js +93 -0
  822. package/lib/vendor/blamejs/test/helpers/json-round-trip.js +120 -0
  823. package/lib/vendor/blamejs/test/helpers/mocks.js +20 -0
  824. package/lib/vendor/blamejs/test/helpers/otel.js +13 -0
  825. package/lib/vendor/blamejs/test/helpers/services.js +380 -0
  826. package/lib/vendor/blamejs/test/helpers/wait.js +206 -0
  827. package/lib/vendor/blamejs/test/integration/cache.test.js +235 -0
  828. package/lib/vendor/blamejs/test/integration/cluster-provider-mysql.test.js +174 -0
  829. package/lib/vendor/blamejs/test/integration/federation-auth.test.js +611 -0
  830. package/lib/vendor/blamejs/test/integration/http-client.test.js +129 -0
  831. package/lib/vendor/blamejs/test/integration/log-stream.test.js +219 -0
  832. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +181 -0
  833. package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +152 -0
  834. package/lib/vendor/blamejs/test/integration/mail-smtp.test.js +161 -0
  835. package/lib/vendor/blamejs/test/integration/mtls-ca.test.js +289 -0
  836. package/lib/vendor/blamejs/test/integration/network-dns.test.js +123 -0
  837. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +101 -0
  838. package/lib/vendor/blamejs/test/integration/ntp-check.test.js +89 -0
  839. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +403 -0
  840. package/lib/vendor/blamejs/test/integration/pqc-pkcs8-forward-compat.test.js +271 -0
  841. package/lib/vendor/blamejs/test/integration/pubsub.test.js +137 -0
  842. package/lib/vendor/blamejs/test/integration/queue-redis.test.js +352 -0
  843. package/lib/vendor/blamejs/test/integration/redis-client-tls.test.js +96 -0
  844. package/lib/vendor/blamejs/test/integration/ssrf-guard.test.js +98 -0
  845. package/lib/vendor/blamejs/test/integration/websocket-permessage-deflate.test.js +261 -0
  846. package/lib/vendor/blamejs/test/integration/ws-client-roundtrip.test.js +230 -0
  847. package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +211 -0
  848. package/lib/vendor/blamejs/test/layer-0-primitives/a2a.test.js +59 -0
  849. package/lib/vendor/blamejs/test/layer-0-primitives/access-lock.test.js +136 -0
  850. package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +219 -0
  851. package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +69 -0
  852. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +266 -0
  853. package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +262 -0
  854. package/lib/vendor/blamejs/test/layer-0-primitives/agent-orchestrator.test.js +390 -0
  855. package/lib/vendor/blamejs/test/layer-0-primitives/agent-posture-chain.test.js +174 -0
  856. package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +279 -0
  857. package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +322 -0
  858. package/lib/vendor/blamejs/test/layer-0-primitives/agent-stream.test.js +227 -0
  859. package/lib/vendor/blamejs/test/layer-0-primitives/agent-tenant.test.js +302 -0
  860. package/lib/vendor/blamejs/test/layer-0-primitives/agent-trace.test.js +150 -0
  861. package/lib/vendor/blamejs/test/layer-0-primitives/ai-adverse-decision.test.js +44 -0
  862. package/lib/vendor/blamejs/test/layer-0-primitives/ai-content-detect.test.js +150 -0
  863. package/lib/vendor/blamejs/test/layer-0-primitives/ai-input.test.js +50 -0
  864. package/lib/vendor/blamejs/test/layer-0-primitives/ai-model-manifest.test.js +96 -0
  865. package/lib/vendor/blamejs/test/layer-0-primitives/ai-pref.test.js +76 -0
  866. package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +1080 -0
  867. package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +311 -0
  868. package/lib/vendor/blamejs/test/layer-0-primitives/archive-zip-stream.test.js +291 -0
  869. package/lib/vendor/blamejs/test/layer-0-primitives/archive.test.js +140 -0
  870. package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +267 -0
  871. package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +108 -0
  872. package/lib/vendor/blamejs/test/layer-0-primitives/asyncapi.test.js +929 -0
  873. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-conflict-path.test.js +80 -0
  874. package/lib/vendor/blamejs/test/layer-0-primitives/audit-cve-defensive.test.js +176 -0
  875. package/lib/vendor/blamejs/test/layer-0-primitives/audit-daily-review.test.js +132 -0
  876. package/lib/vendor/blamejs/test/layer-0-primitives/audit-export-cadf.test.js +97 -0
  877. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +141 -0
  878. package/lib/vendor/blamejs/test/layer-0-primitives/audit-segregation.test.js +115 -0
  879. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-ml-dsa-65.test.js +163 -0
  880. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +246 -0
  881. package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge-verifier.test.js +485 -0
  882. package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge.test.js +331 -0
  883. package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +352 -0
  884. package/lib/vendor/blamejs/test/layer-0-primitives/auth-lockout.test.js +572 -0
  885. package/lib/vendor/blamejs/test/layer-0-primitives/auth-password-audit.test.js +61 -0
  886. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-bucket-ops.test.js +258 -0
  887. package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +105 -0
  888. package/lib/vendor/blamejs/test/layer-0-primitives/backup-worker.test.js +34 -0
  889. package/lib/vendor/blamejs/test/layer-0-primitives/bearer-auth.test.js +107 -0
  890. package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-chunked-malformed.test.js +131 -0
  891. package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-smuggling.test.js +118 -0
  892. package/lib/vendor/blamejs/test/layer-0-primitives/boot-gates.test.js +85 -0
  893. package/lib/vendor/blamejs/test/layer-0-primitives/breach-deadline.test.js +38 -0
  894. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +861 -0
  895. package/lib/vendor/blamejs/test/layer-0-primitives/budr.test.js +55 -0
  896. package/lib/vendor/blamejs/test/layer-0-primitives/bundler-engine.test.js +209 -0
  897. package/lib/vendor/blamejs/test/layer-0-primitives/cache-status.test.js +129 -0
  898. package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +871 -0
  899. package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +891 -0
  900. package/lib/vendor/blamejs/test/layer-0-primitives/canonical-json-jcs.test.js +43 -0
  901. package/lib/vendor/blamejs/test/layer-0-primitives/cdn-cache-control.test.js +243 -0
  902. package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +550 -0
  903. package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +107 -0
  904. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +147 -0
  905. package/lib/vendor/blamejs/test/layer-0-primitives/cli-audit-verify-chain.test.js +104 -0
  906. package/lib/vendor/blamejs/test/layer-0-primitives/cli-backup.test.js +135 -0
  907. package/lib/vendor/blamejs/test/layer-0-primitives/cli-config-drift.test.js +67 -0
  908. package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +75 -0
  909. package/lib/vendor/blamejs/test/layer-0-primitives/cli-file-type.test.js +98 -0
  910. package/lib/vendor/blamejs/test/layer-0-primitives/cli-helpers.test.js +145 -0
  911. package/lib/vendor/blamejs/test/layer-0-primitives/cli-mtls.test.js +133 -0
  912. package/lib/vendor/blamejs/test/layer-0-primitives/cli-password.test.js +97 -0
  913. package/lib/vendor/blamejs/test/layer-0-primitives/cli-restore.test.js +160 -0
  914. package/lib/vendor/blamejs/test/layer-0-primitives/cli-retention.test.js +84 -0
  915. package/lib/vendor/blamejs/test/layer-0-primitives/cli-security.test.js +69 -0
  916. package/lib/vendor/blamejs/test/layer-0-primitives/cli-vault.test.js +142 -0
  917. package/lib/vendor/blamejs/test/layer-0-primitives/client-hints.test.js +133 -0
  918. package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +237 -0
  919. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +9600 -0
  920. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +575 -0
  921. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-cascade.test.js +89 -0
  922. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-eaa.test.js +36 -0
  923. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +712 -0
  924. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +278 -0
  925. package/lib/vendor/blamejs/test/layer-0-primitives/config-drift.test.js +97 -0
  926. package/lib/vendor/blamejs/test/layer-0-primitives/config.test.js +424 -0
  927. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +94 -0
  928. package/lib/vendor/blamejs/test/layer-0-primitives/cors.test.js +357 -0
  929. package/lib/vendor/blamejs/test/layer-0-primitives/cra-report.test.js +31 -0
  930. package/lib/vendor/blamejs/test/layer-0-primitives/credential-hash.test.js +226 -0
  931. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +86 -0
  932. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-envelope.test.js +85 -0
  933. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +193 -0
  934. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +98 -0
  935. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hpke-pq.test.js +132 -0
  936. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hpke.test.js +155 -0
  937. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-mlkem768-x25519.test.js +129 -0
  938. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-namespace-hash.test.js +0 -0
  939. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-random-int.test.js +72 -0
  940. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +96 -0
  941. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +401 -0
  942. package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +34 -0
  943. package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +180 -0
  944. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +210 -0
  945. package/lib/vendor/blamejs/test/layer-0-primitives/daily-byte-quota.test.js +153 -0
  946. package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +66 -0
  947. package/lib/vendor/blamejs/test/layer-0-primitives/data-act.test.js +74 -0
  948. package/lib/vendor/blamejs/test/layer-0-primitives/db-collection-extensions.test.js +226 -0
  949. package/lib/vendor/blamejs/test/layer-0-primitives/db-collection.test.js +136 -0
  950. package/lib/vendor/blamejs/test/layer-0-primitives/db-init-extensions.test.js +165 -0
  951. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +150 -0
  952. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-extensions.test.js +191 -0
  953. package/lib/vendor/blamejs/test/layer-0-primitives/db-role-for.test.js +228 -0
  954. package/lib/vendor/blamejs/test/layer-0-primitives/db-vacuum.test.js +55 -0
  955. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +89 -0
  956. package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +184 -0
  957. package/lib/vendor/blamejs/test/layer-0-primitives/declare-row-policy.test.js +203 -0
  958. package/lib/vendor/blamejs/test/layer-0-primitives/declare-view.test.js +303 -0
  959. package/lib/vendor/blamejs/test/layer-0-primitives/dns-dnssec-algorithm.test.js +163 -0
  960. package/lib/vendor/blamejs/test/layer-0-primitives/dns-null-mx.test.js +39 -0
  961. package/lib/vendor/blamejs/test/layer-0-primitives/dora.test.js +165 -0
  962. package/lib/vendor/blamejs/test/layer-0-primitives/dr-runbook.test.js +59 -0
  963. package/lib/vendor/blamejs/test/layer-0-primitives/dsr-state-rules.test.js +55 -0
  964. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +786 -0
  965. package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +105 -0
  966. package/lib/vendor/blamejs/test/layer-0-primitives/early-hints.test.js +147 -0
  967. package/lib/vendor/blamejs/test/layer-0-primitives/events.test.js +105 -0
  968. package/lib/vendor/blamejs/test/layer-0-primitives/exploit-replay.test.js +243 -0
  969. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +181 -0
  970. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +190 -0
  971. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-routing.test.js +531 -0
  972. package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +118 -0
  973. package/lib/vendor/blamejs/test/layer-0-primitives/fapi2.test.js +89 -0
  974. package/lib/vendor/blamejs/test/layer-0-primitives/fda-21cfr11.test.js +156 -0
  975. package/lib/vendor/blamejs/test/layer-0-primitives/fdx.test.js +79 -0
  976. package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +216 -0
  977. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +434 -0
  978. package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +432 -0
  979. package/lib/vendor/blamejs/test/layer-0-primitives/file-type.test.js +81 -0
  980. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +887 -0
  981. package/lib/vendor/blamejs/test/layer-0-primitives/forensic-snapshot.test.js +51 -0
  982. package/lib/vendor/blamejs/test/layer-0-primitives/fsm.test.js +375 -0
  983. package/lib/vendor/blamejs/test/layer-0-primitives/gcs-bucket-ops.test.js +321 -0
  984. package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +41 -0
  985. package/lib/vendor/blamejs/test/layer-0-primitives/graphql-federation.test.js +32 -0
  986. package/lib/vendor/blamejs/test/layer-0-primitives/guard-agent-registry.test.js +87 -0
  987. package/lib/vendor/blamejs/test/layer-0-primitives/guard-all.test.js +328 -0
  988. package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +339 -0
  989. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +694 -0
  990. package/lib/vendor/blamejs/test/layer-0-primitives/guard-dsn.test.js +296 -0
  991. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +234 -0
  992. package/lib/vendor/blamejs/test/layer-0-primitives/guard-envelope.test.js +192 -0
  993. package/lib/vendor/blamejs/test/layer-0-primitives/guard-event-bus-payload.test.js +89 -0
  994. package/lib/vendor/blamejs/test/layer-0-primitives/guard-event-bus-topic.test.js +71 -0
  995. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +386 -0
  996. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html-wcag.test.js +859 -0
  997. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +357 -0
  998. package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +92 -0
  999. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  1000. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +174 -0
  1001. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +317 -0
  1002. package/lib/vendor/blamejs/test/layer-0-primitives/guard-list-id.test.js +199 -0
  1003. package/lib/vendor/blamejs/test/layer-0-primitives/guard-list-unsubscribe.test.js +214 -0
  1004. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-compose.test.js +111 -0
  1005. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-move.test.js +110 -0
  1006. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-query.test.js +112 -0
  1007. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-reply.test.js +86 -0
  1008. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-sieve.test.js +92 -0
  1009. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +301 -0
  1010. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +265 -0
  1011. package/lib/vendor/blamejs/test/layer-0-primitives/guard-message-id.test.js +0 -0
  1012. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +161 -0
  1013. package/lib/vendor/blamejs/test/layer-0-primitives/guard-posture-chain.test.js +100 -0
  1014. package/lib/vendor/blamejs/test/layer-0-primitives/guard-saga-config.test.js +79 -0
  1015. package/lib/vendor/blamejs/test/layer-0-primitives/guard-smtp-command.test.js +269 -0
  1016. package/lib/vendor/blamejs/test/layer-0-primitives/guard-snapshot-envelope.test.js +89 -0
  1017. package/lib/vendor/blamejs/test/layer-0-primitives/guard-stream-args.test.js +78 -0
  1018. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +288 -0
  1019. package/lib/vendor/blamejs/test/layer-0-primitives/guard-tenant-id.test.js +69 -0
  1020. package/lib/vendor/blamejs/test/layer-0-primitives/guard-trace-context.test.js +102 -0
  1021. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +202 -0
  1022. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +203 -0
  1023. package/lib/vendor/blamejs/test/layer-0-primitives/hal.test.js +51 -0
  1024. package/lib/vendor/blamejs/test/layer-0-primitives/honeytoken.test.js +50 -0
  1025. package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +37 -0
  1026. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +692 -0
  1027. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +280 -0
  1028. package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +225 -0
  1029. package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +203 -0
  1030. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +991 -0
  1031. package/lib/vendor/blamejs/test/layer-0-primitives/iab-mspa.test.js +63 -0
  1032. package/lib/vendor/blamejs/test/layer-0-primitives/iab-tcf.test.js +73 -0
  1033. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +612 -0
  1034. package/lib/vendor/blamejs/test/layer-0-primitives/importmap-integrity.test.js +56 -0
  1035. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +166 -0
  1036. package/lib/vendor/blamejs/test/layer-0-primitives/incident-report.test.js +29 -0
  1037. package/lib/vendor/blamejs/test/layer-0-primitives/jose-jwe-experimental.test.js +121 -0
  1038. package/lib/vendor/blamejs/test/layer-0-primitives/json-api.test.js +58 -0
  1039. package/lib/vendor/blamejs/test/layer-0-primitives/json-round-trip-helper.test.js +110 -0
  1040. package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +159 -0
  1041. package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
  1042. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +118 -0
  1043. package/lib/vendor/blamejs/test/layer-0-primitives/local-db-thin.test.js +150 -0
  1044. package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-cloudwatch.test.js +489 -0
  1045. package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp-grpc.test.js +207 -0
  1046. package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp.test.js +283 -0
  1047. package/lib/vendor/blamejs/test/layer-0-primitives/lro.test.js +65 -0
  1048. package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +417 -0
  1049. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +208 -0
  1050. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +910 -0
  1051. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +502 -0
  1052. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +680 -0
  1053. package/lib/vendor/blamejs/test/layer-0-primitives/mail-canspam.test.js +128 -0
  1054. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +149 -0
  1055. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +323 -0
  1056. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +297 -0
  1057. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +514 -0
  1058. package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy-tlsrpt.test.js +369 -0
  1059. package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +199 -0
  1060. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +627 -0
  1061. package/lib/vendor/blamejs/test/layer-0-primitives/mail-feedback-id.test.js +56 -0
  1062. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +217 -0
  1063. package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +283 -0
  1064. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +217 -0
  1065. package/lib/vendor/blamejs/test/layer-0-primitives/mail-mdn.test.js +334 -0
  1066. package/lib/vendor/blamejs/test/layer-0-primitives/mail-rbl.test.js +271 -0
  1067. package/lib/vendor/blamejs/test/layer-0-primitives/mail-require-tls.test.js +128 -0
  1068. package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +215 -0
  1069. package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +336 -0
  1070. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +732 -0
  1071. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +840 -0
  1072. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +130 -0
  1073. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +285 -0
  1074. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +74 -0
  1075. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +112 -0
  1076. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +229 -0
  1077. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +394 -0
  1078. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +147 -0
  1079. package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +151 -0
  1080. package/lib/vendor/blamejs/test/layer-0-primitives/mail-spam-score.test.js +204 -0
  1081. package/lib/vendor/blamejs/test/layer-0-primitives/mail-srs.test.js +152 -0
  1082. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +279 -0
  1083. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +323 -0
  1084. package/lib/vendor/blamejs/test/layer-0-primitives/mail-unsubscribe.test.js +165 -0
  1085. package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +439 -0
  1086. package/lib/vendor/blamejs/test/layer-0-primitives/mcp-tool-registry.test.js +202 -0
  1087. package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +155 -0
  1088. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-shadow-registry.test.js +112 -0
  1089. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +224 -0
  1090. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-compose-pipeline.test.js +278 -0
  1091. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +376 -0
  1092. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-paths.test.js +89 -0
  1093. package/lib/vendor/blamejs/test/layer-0-primitives/nel.test.js +200 -0
  1094. package/lib/vendor/blamejs/test/layer-0-primitives/network-allowlist.test.js +106 -0
  1095. package/lib/vendor/blamejs/test/layer-0-primitives/network-byte-quota.test.js +133 -0
  1096. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +372 -0
  1097. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +635 -0
  1098. package/lib/vendor/blamejs/test/layer-0-primitives/network-heartbeat-passive.test.js +128 -0
  1099. package/lib/vendor/blamejs/test/layer-0-primitives/network-tls-build-options.test.js +130 -0
  1100. package/lib/vendor/blamejs/test/layer-0-primitives/network-tls-ct-inclusion.test.js +179 -0
  1101. package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +447 -0
  1102. package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +369 -0
  1103. package/lib/vendor/blamejs/test/layer-0-primitives/nis2-report.test.js +21 -0
  1104. package/lib/vendor/blamejs/test/layer-0-primitives/nist-crosswalk.test.js +42 -0
  1105. package/lib/vendor/blamejs/test/layer-0-primitives/no-cache.test.js +98 -0
  1106. package/lib/vendor/blamejs/test/layer-0-primitives/notify.test.js +707 -0
  1107. package/lib/vendor/blamejs/test/layer-0-primitives/numeric-bounds.test.js +142 -0
  1108. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +72 -0
  1109. package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +597 -0
  1110. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +190 -0
  1111. package/lib/vendor/blamejs/test/layer-0-primitives/openapi.test.js +877 -0
  1112. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +257 -0
  1113. package/lib/vendor/blamejs/test/layer-0-primitives/pagination.test.js +522 -0
  1114. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +216 -0
  1115. package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +324 -0
  1116. package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +546 -0
  1117. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +153 -0
  1118. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-software.test.js +94 -0
  1119. package/lib/vendor/blamejs/test/layer-0-primitives/problem-details.test.js +195 -0
  1120. package/lib/vendor/blamejs/test/layer-0-primitives/process-spawn.test.js +62 -0
  1121. package/lib/vendor/blamejs/test/layer-0-primitives/promise-pool.test.js +93 -0
  1122. package/lib/vendor/blamejs/test/layer-0-primitives/protected-resource-metadata.test.js +68 -0
  1123. package/lib/vendor/blamejs/test/layer-0-primitives/protobuf-encoder.test.js +138 -0
  1124. package/lib/vendor/blamejs/test/layer-0-primitives/protocol-dispatcher.test.js +174 -0
  1125. package/lib/vendor/blamejs/test/layer-0-primitives/public-suffix.test.js +197 -0
  1126. package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +232 -0
  1127. package/lib/vendor/blamejs/test/layer-0-primitives/queue-dlq-extend-lease.test.js +178 -0
  1128. package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +322 -0
  1129. package/lib/vendor/blamejs/test/layer-0-primitives/queue-priority-rate-progress.test.js +266 -0
  1130. package/lib/vendor/blamejs/test/layer-0-primitives/queue-sqs.test.js +300 -0
  1131. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-cluster.test.js +338 -0
  1132. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-registry.test.js +75 -0
  1133. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +246 -0
  1134. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +130 -0
  1135. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +335 -0
  1136. package/lib/vendor/blamejs/test/layer-0-primitives/request-log.test.js +170 -0
  1137. package/lib/vendor/blamejs/test/layer-0-primitives/require-auth-cache-control.test.js +93 -0
  1138. package/lib/vendor/blamejs/test/layer-0-primitives/require-mtls.test.js +34 -0
  1139. package/lib/vendor/blamejs/test/layer-0-primitives/resource-access-lock.test.js +52 -0
  1140. package/lib/vendor/blamejs/test/layer-0-primitives/retention-floor.test.js +67 -0
  1141. package/lib/vendor/blamejs/test/layer-0-primitives/retry.test.js +535 -0
  1142. package/lib/vendor/blamejs/test/layer-0-primitives/router-cross-origin-redirect.test.js +0 -0
  1143. package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +128 -0
  1144. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +163 -0
  1145. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-parallel.test.js +170 -0
  1146. package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +248 -0
  1147. package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +451 -0
  1148. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +289 -0
  1149. package/lib/vendor/blamejs/test/layer-0-primitives/safe-icap.test.js +206 -0
  1150. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +104 -0
  1151. package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +339 -0
  1152. package/lib/vendor/blamejs/test/layer-0-primitives/safe-mount-info.test.js +180 -0
  1153. package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +78 -0
  1154. package/lib/vendor/blamejs/test/layer-0-primitives/safe-sieve.test.js +123 -0
  1155. package/lib/vendor/blamejs/test/layer-0-primitives/safe-smtp.test.js +95 -0
  1156. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-idn-homograph.test.js +77 -0
  1157. package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +257 -0
  1158. package/lib/vendor/blamejs/test/layer-0-primitives/saml-slo.test.js +249 -0
  1159. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +228 -0
  1160. package/lib/vendor/blamejs/test/layer-0-primitives/scheduler-exactly-once.test.js +238 -0
  1161. package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +92 -0
  1162. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +700 -0
  1163. package/lib/vendor/blamejs/test/layer-0-primitives/sd-notify.test.js +67 -0
  1164. package/lib/vendor/blamejs/test/layer-0-primitives/sec-cyber.test.js +85 -0
  1165. package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +107 -0
  1166. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +175 -0
  1167. package/lib/vendor/blamejs/test/layer-0-primitives/seeders.test.js +816 -0
  1168. package/lib/vendor/blamejs/test/layer-0-primitives/self-update-standalone-verifier.test.js +168 -0
  1169. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +302 -0
  1170. package/lib/vendor/blamejs/test/layer-0-primitives/server-timing.test.js +93 -0
  1171. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +247 -0
  1172. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +295 -0
  1173. package/lib/vendor/blamejs/test/layer-0-primitives/shape-match.test.js +142 -0
  1174. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +952 -0
  1175. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-multipart-sse.test.js +441 -0
  1176. package/lib/vendor/blamejs/test/layer-0-primitives/slug.test.js +330 -0
  1177. package/lib/vendor/blamejs/test/layer-0-primitives/smtp-policy.test.js +233 -0
  1178. package/lib/vendor/blamejs/test/layer-0-primitives/source-comment-blocks.test.js +105 -0
  1179. package/lib/vendor/blamejs/test/layer-0-primitives/speculation-rules.test.js +319 -0
  1180. package/lib/vendor/blamejs/test/layer-0-primitives/sse.test.js +148 -0
  1181. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +283 -0
  1182. package/lib/vendor/blamejs/test/layer-0-primitives/standard-webhooks.test.js +67 -0
  1183. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +266 -0
  1184. package/lib/vendor/blamejs/test/layer-0-primitives/step-up.test.js +487 -0
  1185. package/lib/vendor/blamejs/test/layer-0-primitives/storage-chunk-scratch.test.js +0 -0
  1186. package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +773 -0
  1187. package/lib/vendor/blamejs/test/layer-0-primitives/stream-throttle.test.js +173 -0
  1188. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +180 -0
  1189. package/lib/vendor/blamejs/test/layer-0-primitives/tcpa-10dlc.test.js +66 -0
  1190. package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +89 -0
  1191. package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +571 -0
  1192. package/lib/vendor/blamejs/test/layer-0-primitives/test-harness.test.js +190 -0
  1193. package/lib/vendor/blamejs/test/layer-0-primitives/testing-request.test.js +119 -0
  1194. package/lib/vendor/blamejs/test/layer-0-primitives/testing.test.js +522 -0
  1195. package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +151 -0
  1196. package/lib/vendor/blamejs/test/layer-0-primitives/tls-exporter.test.js +168 -0
  1197. package/lib/vendor/blamejs/test/layer-0-primitives/tls-ocsp-ct.test.js +275 -0
  1198. package/lib/vendor/blamejs/test/layer-0-primitives/tls-ocsp-verify.test.js +105 -0
  1199. package/lib/vendor/blamejs/test/layer-0-primitives/tls-pinset-drift.test.js +35 -0
  1200. package/lib/vendor/blamejs/test/layer-0-primitives/tls-preferred-groups.test.js +81 -0
  1201. package/lib/vendor/blamejs/test/layer-0-primitives/tracing.test.js +280 -0
  1202. package/lib/vendor/blamejs/test/layer-0-primitives/uuid.test.js +93 -0
  1203. package/lib/vendor/blamejs/test/layer-0-primitives/vault-aad.test.js +277 -0
  1204. package/lib/vendor/blamejs/test/layer-0-primitives/vault-seal-pem-file.test.js +252 -0
  1205. package/lib/vendor/blamejs/test/layer-0-primitives/vendor-data.test.js +149 -0
  1206. package/lib/vendor/blamejs/test/layer-0-primitives/vendor-manifest.test.js +92 -0
  1207. package/lib/vendor/blamejs/test/layer-0-primitives/vex.test.js +661 -0
  1208. package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +308 -0
  1209. package/lib/vendor/blamejs/test/layer-0-primitives/web-push-vapid.test.js +144 -0
  1210. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +674 -0
  1211. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-channels.test.js +360 -0
  1212. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool.test.js +302 -0
  1213. package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +349 -0
  1214. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +717 -0
  1215. package/lib/vendor/blamejs/test/layer-5-integration/bundler-output.test.js +444 -0
  1216. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +597 -0
  1217. package/lib/vendor/blamejs/test/layer-5-integration/security-chaos.test.js +308 -0
  1218. package/lib/vendor/blamejs/test/smoke.js +431 -0
  1219. package/lib/webhooks.js +305 -0
  1220. package/package.json +43 -0
@@ -0,0 +1,1858 @@
1
+ "use strict";
2
+ /**
3
+ * @module b.mail.server.imap
4
+ * @nav Mail
5
+ * @title Mail IMAP Server
6
+ * @order 546
7
+ *
8
+ * @intro
9
+ * IMAP4rev2 mailbox-access listener (RFC 9051; obsoletes RFC 3501).
10
+ * Modern MUAs (Thunderbird, Apple Mail, mutt, K-9, FairEmail,
11
+ * etc.) connect here to read + manage messages without operators
12
+ * running dovecot / cyrus alongside. Composes the framework's
13
+ * existing substrates:
14
+ *
15
+ * - `b.guardImapCommand` for wire-protocol shape + smuggling
16
+ * defense (literal-injection, bare-CR/LF refusal, per-verb
17
+ * shape, RFC 9051 §2.2.2 literal framing)
18
+ * - `b.mail.server.rateLimit` for per-IP DoS defense (concurrent
19
+ * + rate + AUTH-failure budget + slow-loris)
20
+ * - `b.mailStore` (operator-supplied backend) for the actual
21
+ * mail storage + UIDVALIDITY + modseq tracking
22
+ * - operator-supplied authenticator for SASL credential verify
23
+ * - `b.mail.server.tls` recommended for cert + key loading +
24
+ * rotation
25
+ *
26
+ * ## State machine (RFC 9051 §3)
27
+ *
28
+ * ```
29
+ * NOT-AUTHENTICATED → [STARTTLS → NOT-AUTH-TLS] → AUTH/LOGIN →
30
+ * AUTHENTICATED ↔ SELECTED → LOGOUT
31
+ * ↑ EXAMINE ↓ CLOSE / UNSELECT
32
+ * ```
33
+ *
34
+ * Commands gated by state:
35
+ *
36
+ * - NOT-AUTHENTICATED: STARTTLS / AUTHENTICATE / LOGIN / NOOP /
37
+ * CAPABILITY / LOGOUT / ID
38
+ * - AUTHENTICATED: SELECT / EXAMINE / CREATE / DELETE / RENAME /
39
+ * SUBSCRIBE / UNSUBSCRIBE / LIST / STATUS / APPEND / NAMESPACE /
40
+ * IDLE / ENABLE / NOOP / CAPABILITY / LOGOUT / ID
41
+ * - SELECTED: CHECK / CLOSE / UNSELECT / EXPUNGE / SEARCH / FETCH /
42
+ * STORE / COPY / MOVE / UID … / IDLE / NOOP / CAPABILITY /
43
+ * LOGOUT + every AUTHENTICATED command
44
+ *
45
+ * Tagged response model: every client command carries a tag
46
+ * (`A001 LOGIN …`); server replies with one or more untagged
47
+ * responses (`* …`) then `A001 OK …` / `A001 NO …` / `A001 BAD …`.
48
+ *
49
+ * ## Wire-protocol defenses
50
+ *
51
+ * - **STARTTLS stripping (CVE-2021-33515 Dovecot class)** —
52
+ * STARTTLS upgrade clears pre-handshake receive buffer; any
53
+ * pipelined command queued before TLS is refused with
54
+ * `BAD Pipelined post-STARTTLS not permitted`.
55
+ *
56
+ * - **Literal-injection (CVE-2018-19518 INC IMAP class)** —
57
+ * `{n}` literal continuation MUST come on a line of its own
58
+ * (per `b.guardImapCommand.detectLiteralSmuggling`); oversize
59
+ * literals refused (default 64 MiB); LITERAL+ (RFC 7888) non-
60
+ * synchronizing literals only honored post-AUTH.
61
+ *
62
+ * - **Mailbox-name traversal** — mailbox path components
63
+ * validated through `_validateMailboxName`: refuses `..`, NUL,
64
+ * control chars, oversize. UTF-8 mailbox names (RFC 9051 §5.1)
65
+ * accepted; modified-UTF7 (RFC 3501 §5.1.3 legacy) refused unless
66
+ * `allowLegacyMUtf7: true`.
67
+ *
68
+ * - **APPEND-flood** — per-tenant byte/sec cap surfaces via the
69
+ * `b.mail.server.rateLimit`'s `minBytesPerSecond` floor on the
70
+ * APPEND-literal-body phase (same shape the MX listener uses for
71
+ * DATA-body).
72
+ *
73
+ * - **Resource exhaustion** — per-line cap (default 8 KiB sans
74
+ * literal payload), per-literal cap (64 MiB), per-connection idle
75
+ * cap (default 30 min when not in IDLE; IDLE itself capped at
76
+ * 29 min per RFC 2177 §3 to force re-issue).
77
+ *
78
+ * - **Connection-rate + AUTH-failure budget** — composes
79
+ * `b.mail.server.rateLimit`. Each AUTH failure increments the
80
+ * budget; trip the cap and new AUTH attempts get
81
+ * `* BAD Too many AUTH failures` + connection close.
82
+ *
83
+ * ## Audit lifecycle
84
+ *
85
+ * - `mail.server.imap.connect` — IP, TLS state
86
+ * - `mail.server.imap.auth_attempt` — mechanism, actor-hash
87
+ * - `mail.server.imap.auth_success` — mechanism, tenantId, scopes
88
+ * - `mail.server.imap.auth_failed` — mechanism, reason
89
+ * - `mail.server.imap.select` — mailbox, modseq, exists count
90
+ * - `mail.server.imap.append` — mailbox, size, flags
91
+ * - `mail.server.imap.fetch_bulk` — sequence-set size, BODY parts
92
+ * - `mail.server.imap.expunge` — count, modseq
93
+ * - `mail.server.imap.literal_overflow_refused` — attempt size, cap
94
+ * - `mail.server.imap.rate_limit_refused` — IP, reason
95
+ * - `mail.server.imap.smtp_smuggling_detected` — literal-injection
96
+ *
97
+ * ## What v1 does NOT ship
98
+ *
99
+ * - **SEARCH** — operator wires `opts.search(actor, mailbox, query)`
100
+ * when ready; the listener emits `BAD search-not-configured`
101
+ * until then. SEARCH expressions are operator-domain logic
102
+ * against the mailStore index.
103
+ * - **NOTIFY (RFC 5465)**, **METADATA (RFC 5464)**, **CATENATE
104
+ * (RFC 4469)**, **URLAUTH (RFC 4467)**, **IMAPSIEVE (RFC 6785)**,
105
+ * **COMPRESS=DEFLATE (RFC 4978)** — opt-in / refused.
106
+ * - **CONDSTORE / QRESYNC (RFC 7162)** — modseq is exposed via
107
+ * STATUS but per-FETCH CHANGEDSINCE delta is operator-side
108
+ * follow-up.
109
+ *
110
+ * @card
111
+ * IMAP4rev2 mailbox-access listener (RFC 9051; obsoletes RFC 3501).
112
+ * State machine NOT-AUTH → STARTTLS → AUTH → SELECTED → LOGOUT.
113
+ * Composes b.guardImapCommand (wire-protocol gate), b.mail.server.
114
+ * rateLimit (DoS defense), operator-supplied mailStore + SASL
115
+ * authenticator. Default-on per-IP rate-limit + literal-injection
116
+ * refusal + mailbox-traversal refusal.
117
+ */
118
+
119
+ var net = require("node:net");
120
+ var lazyRequire = require("./lazy-require");
121
+ var C = require("./constants");
122
+ var bCrypto = require("./crypto");
123
+ var numericBounds = require("./numeric-bounds");
124
+ var validateOpts = require("./validate-opts");
125
+ var guardImapCommand = require("./guard-imap-command");
126
+ var mailServerRateLimit = require("./mail-server-rate-limit");
127
+ var mailServerRegistry = require("./mail-server-registry");
128
+ var mailServerTls = require("./mail-server-tls");
129
+ var { defineClass } = require("./framework-error");
130
+
131
+ var audit = lazyRequire(function () { return require("./audit"); });
132
+
133
+ var MailServerImapError = defineClass("MailServerImapError", { alwaysPermanent: true });
134
+
135
+ var DEFAULT_MAX_LINE_BYTES = C.BYTES.kib(8);
136
+ var DEFAULT_MAX_LITERAL = C.BYTES.mib(64);
137
+ var DEFAULT_IDLE_TIMEOUT_MS = C.TIME.minutes(30);
138
+ var IDLE_BANDWIDTH_TIMEOUT_MS = C.TIME.minutes(29); // RFC 2177 §3 — re-issue before 30
139
+ var DEFAULT_GREETING_VENDOR = "blamejs IMAP4rev2";
140
+ var pkgVersion = require("../package.json").version;
141
+
142
+ // Error-message clamp bytes — protocol-string clamp, not a byte count.
143
+ // Centralized so the allow:raw-byte-literal marker lives in one place
144
+ // and the per-call sites read cleanly.
145
+ var ERR_CLAMP = 200; // allow:raw-byte-literal — protocol-reply error-message clamp
146
+ var LINE_PREVIEW = 80; // allow:raw-byte-literal — audit-line preview clamp
147
+
148
+ // RFC 9051 §6.3.12 + RFC 5322 §3.3 date-time parser for IMAP APPEND.
149
+ // Format: `DD-Mon-YYYY HH:MM:SS ±HHMM` where Mon is the 3-letter
150
+ // English month abbreviation (case-insensitive on parse, but the IMAP
151
+ // spec emits canonical mixed-case `Jan`/`Feb`/...). Returns the
152
+ // millisecond epoch, or null on any parse failure — the caller emits
153
+ // `BAD` rather than silently using `Date.now()`.
154
+ var IMAP_MONTHS = Object.freeze({
155
+ jan: 0, feb: 1, mar: 2, apr: 3, may: 4, jun: 5, // allow:raw-byte-literal — month-index table (0-5)
156
+ jul: 6, aug: 7, sep: 8, oct: 9, nov: 10, dec: 11, // allow:raw-byte-literal — month-index table (6-11)
157
+ });
158
+ var IMAP_DT_RE = /^\s*(\d{1,2})-([A-Za-z]{3})-(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+([+-])(\d{2})(\d{2})\s*$/;
159
+ function _parseImapDateTime(s) {
160
+ if (typeof s !== "string") return null;
161
+ var m = s.match(IMAP_DT_RE); // allow:regex-no-length-cap — input bounded by IMAP literal cap
162
+ if (!m) return null;
163
+ var day = parseInt(m[1], 10);
164
+ var month = IMAP_MONTHS[m[2].toLowerCase()];
165
+ if (month === undefined) return null;
166
+ var year = parseInt(m[3], 10);
167
+ var hour = parseInt(m[4], 10);
168
+ var min = parseInt(m[5], 10);
169
+ var sec = parseInt(m[6], 10);
170
+ var sign = m[7] === "-" ? -1 : 1;
171
+ var tzH = parseInt(m[8], 10);
172
+ var tzM = parseInt(m[9], 10);
173
+ if (day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59 || tzH > 23 || tzM > 59) return null;
174
+ var utcMs = Date.UTC(year, month, day, hour, min, sec);
175
+ if (!isFinite(utcMs)) return null;
176
+ // RFC 5322 §3.3 — date-time MUST be a real calendar date. `Date.UTC`
177
+ // silently normalises impossible inputs (`Feb 31 2026` → `Mar 3 2026`);
178
+ // round-trip via the calendar fields and refuse any drift so a
179
+ // hostile client can't smuggle a different internalDate than the
180
+ // wire suggests.
181
+ var probe = new Date(utcMs);
182
+ if (probe.getUTCFullYear() !== year ||
183
+ probe.getUTCMonth() !== month ||
184
+ probe.getUTCDate() !== day ||
185
+ probe.getUTCHours() !== hour ||
186
+ probe.getUTCMinutes() !== min ||
187
+ probe.getUTCSeconds() !== sec) {
188
+ return null;
189
+ }
190
+ return utcMs - sign * (tzH * C.TIME.hours(1) + tzM * C.TIME.minutes(1));
191
+ }
192
+
193
+ // Mailbox name validator. RFC 9051 §5.1 — UTF-8 hierarchy. Refuse
194
+ // path-traversal (`..`), NUL, C0 controls, leading/trailing slash,
195
+ // oversize.
196
+ function _validateMailboxName(name, opts) {
197
+ if (typeof name !== "string" || name.length === 0) return false;
198
+ if (name.length > 1024) return false; // allow:raw-byte-literal — mailbox name cap
199
+ for (var i = 0; i < name.length; i += 1) {
200
+ var c = name.charCodeAt(i);
201
+ if (c < 0x20 || c === 0x7F) return false; // allow:raw-byte-literal — control-byte refusal
202
+ }
203
+ if (name.indexOf("..") !== -1) return false;
204
+ if (name === "/" || name[0] === "/" || name[name.length - 1] === "/") return false;
205
+ // Modified-UTF7 detection — RFC 3501 §5.1.3. Sequences are
206
+ // `&...-`. Refuse under strict (RFC 9051 uses raw UTF-8).
207
+ if (opts && opts.allowLegacyMUtf7 !== true) {
208
+ if (/&[A-Za-z0-9+/]*-/.test(name)) return false; // allow:regex-no-length-cap — mailbox name already length-capped above
209
+ }
210
+ return true;
211
+ }
212
+
213
+ /**
214
+ * @primitive b.mail.server.imap.create
215
+ * @signature b.mail.server.imap.create(opts)
216
+ * @since 0.9.49
217
+ * @status stable
218
+ * @related b.mail.server.mx.create, b.mail.server.submission.create, b.mailStore.create
219
+ *
220
+ * Build an IMAP4rev2 listener (RFC 9051). The handle exposes
221
+ * `listen({ port, address })` → ephemeral-bind promise resolving to
222
+ * `{ port, address }`, plus `close()` for graceful shutdown.
223
+ *
224
+ * @opts
225
+ * tlsContext: SecureContext, // required (no plaintext mode)
226
+ * greeting: string, // default "blamejs IMAP4rev2"
227
+ * maxLineBytes: number, // default 8192
228
+ * maxLiteralBytes: number, // default 64 MiB
229
+ * idleTimeoutMs: number, // default 30 min
230
+ * profile: "strict" | "balanced" | "permissive",
231
+ * auth: {
232
+ * mechanisms: ["PLAIN", "LOGIN", "SCRAM-SHA-256", "EXTERNAL", "XOAUTH2"],
233
+ * verify: async function (mechanism, credentials) → { ok, actor },
234
+ * },
235
+ * mailStore: b.mailStore handle, // required
236
+ * rateLimit: b.mail.server.rateLimit handle | opts | false,
237
+ * audit: b.audit // optional
238
+ *
239
+ * @example
240
+ * var imap = b.mail.server.imap.create({
241
+ * tlsContext: b.mail.server.tls.context({ certFile, keyFile }).secureContext,
242
+ * auth: {
243
+ * mechanisms: ["PLAIN", "SCRAM-SHA-256"],
244
+ * verify: async function (mech, creds) {
245
+ * return { ok: true, actor: { tenantId: "t1", username: creds.authzid } };
246
+ * },
247
+ * },
248
+ * mailStore: b.mailStore.create({ backend: b.db.handle() }),
249
+ * });
250
+ * await imap.listen({ port: 143 });
251
+ */
252
+ function create(opts) {
253
+ validateOpts.requireObject(opts, "mail.server.imap.create",
254
+ MailServerImapError, "mail-server-imap/bad-opts");
255
+ if (!opts.tlsContext) {
256
+ throw new MailServerImapError("mail-server-imap/no-tls-context",
257
+ "mail.server.imap.create: tlsContext is required (no implicit plaintext mode). " +
258
+ "Use b.mail.server.tls.context({ certFile, keyFile, watch: true }) to load + " +
259
+ "auto-reload a cert/key pair from disk.");
260
+ }
261
+ if (!opts.mailStore || typeof opts.mailStore.appendMessage !== "function") {
262
+ throw new MailServerImapError("mail-server-imap/no-mail-store",
263
+ "mail.server.imap.create: mailStore is required (compose b.mailStore.create({ backend: ... }))");
264
+ }
265
+ numericBounds.requireAllPositiveFiniteIntIfPresent(opts,
266
+ ["maxLineBytes", "maxLiteralBytes", "idleTimeoutMs"],
267
+ "mail.server.imap.", MailServerImapError, "mail-server-imap/bad-bound");
268
+
269
+ var greeting = opts.greeting || DEFAULT_GREETING_VENDOR;
270
+ var maxLineBytes = opts.maxLineBytes || DEFAULT_MAX_LINE_BYTES;
271
+ var maxLiteralBytes = opts.maxLiteralBytes || DEFAULT_MAX_LITERAL;
272
+ var idleTimeoutMs = opts.idleTimeoutMs || DEFAULT_IDLE_TIMEOUT_MS;
273
+ var profile = opts.profile || "strict";
274
+ var authConfig = opts.auth || null;
275
+ var mailStore = opts.mailStore;
276
+ var allowLegacyMUtf7 = profile === "permissive";
277
+
278
+ var rateLimit;
279
+ if (opts.rateLimit === false) {
280
+ rateLimit = mailServerRateLimit.create({ disabled: true });
281
+ } else if (opts.rateLimit && typeof opts.rateLimit.admitConnection === "function") {
282
+ rateLimit = opts.rateLimit;
283
+ } else {
284
+ rateLimit = mailServerRateLimit.create(opts.rateLimit || {});
285
+ }
286
+
287
+ var tcpServer = null;
288
+ var listening = false;
289
+ var connections = new Set();
290
+
291
+ function _emit(action, metadata, outcome) {
292
+ try {
293
+ audit().safeEmit({
294
+ action: action,
295
+ outcome: outcome || "success",
296
+ metadata: metadata || {},
297
+ });
298
+ } catch (_e) { /* drop-silent — audit best-effort */ }
299
+ }
300
+
301
+ function _handleConnection(rawSocket) {
302
+ var remoteAddress = rawSocket.remoteAddress || "0.0.0.0";
303
+ var admit = rateLimit.admitConnection(remoteAddress);
304
+ if (!admit.ok) {
305
+ _emit("mail.server.imap.rate_limit_refused",
306
+ { remoteAddress: remoteAddress, reason: admit.reason }, "denied");
307
+ try { rawSocket.write("* BAD Too many connections from your IP\r\n"); }
308
+ catch (_e) { /* socket may be down */ }
309
+ try { rawSocket.destroy(); } catch (_e2) { /* idempotent */ }
310
+ return;
311
+ }
312
+ rawSocket.once("close", function () { rateLimit.releaseConnection(remoteAddress); });
313
+
314
+ var connectionId = "imapconn-" + bCrypto.generateToken(8); // allow:raw-byte-literal — connection-id length
315
+ var socket = rawSocket;
316
+ connections.add(socket);
317
+
318
+ var state = {
319
+ id: connectionId,
320
+ remoteAddress: remoteAddress,
321
+ tls: false,
322
+ stage: "not-authenticated",
323
+ actor: null,
324
+ selectedMailbox: null,
325
+ selectedReadOnly: false,
326
+ authPending: null,
327
+ pendingLiteral: null, // { tag, verb, line, size, body }
328
+ idle: null, // { tag, timer }
329
+ // Per-connection receive buffer (must NOT be a closure variable —
330
+ // multiple concurrent connections would clobber each other).
331
+ lineBuffer: Buffer.alloc(0),
332
+ };
333
+
334
+ _emit("mail.server.imap.connect",
335
+ { connectionId: connectionId, remoteAddress: remoteAddress });
336
+
337
+ socket.setTimeout(idleTimeoutMs);
338
+ socket.on("timeout", function () {
339
+ _writeUntagged(socket, "BYE Idle timeout");
340
+ _close(socket, state);
341
+ });
342
+ socket.on("error", function (err) {
343
+ _emit("mail.server.imap.socket_error",
344
+ { connectionId: connectionId, error: (err && err.message) || String(err) }, "failure");
345
+ });
346
+
347
+ // Greeting per RFC 9051 §7.1.5 — `* OK <greeting>`.
348
+ _writeUntagged(socket, "OK [CAPABILITY " + _capabilityLine(state) + "] " + greeting);
349
+
350
+ socket.on("data", function (chunk) {
351
+ // Per-line cap MUST gate the concat — a single large TCP chunk
352
+ // (~64 KiB on most kernels) can push the buffer past the line
353
+ // cap BEFORE the drain loop runs, so the cap-check inside the
354
+ // loop sees a buffer that's already grown past the policy
355
+ // floor. When the chunk would itself overrun the line cap AND
356
+ // no literal is pending (where over-cap bytes are legitimate
357
+ // payload), reject here and tear the connection down.
358
+ var pendingLiteral = state.pendingLiteral;
359
+ var room = pendingLiteral
360
+ ? (pendingLiteral.size - pendingLiteral.body.length) + maxLineBytes
361
+ : (maxLineBytes - state.lineBuffer.length);
362
+ if (chunk.length > room) {
363
+ _writeUntagged(socket, "BAD Line too long (cap " + maxLineBytes + ")");
364
+ _close(socket, state);
365
+ return;
366
+ }
367
+ state.lineBuffer = Buffer.concat([state.lineBuffer, chunk]);
368
+ _drainBuffer(state, socket);
369
+ });
370
+ }
371
+
372
+ // Receive-buffer drain: extract complete lines (CRLF-terminated)
373
+ // and dispatch. When the previous command opened a literal (e.g.
374
+ // APPEND ... {N}), the next N bytes are the literal payload — we
375
+ // accumulate them before resuming line-mode dispatch.
376
+ function _drainBuffer(state, socket) {
377
+ while (true) {
378
+ if (state.pendingLiteral) {
379
+ var need = state.pendingLiteral.size - state.pendingLiteral.body.length;
380
+ if (state.lineBuffer.length < need) {
381
+ state.pendingLiteral.body = Buffer.concat([state.pendingLiteral.body, state.lineBuffer]);
382
+ state.lineBuffer = Buffer.alloc(0);
383
+ return;
384
+ }
385
+ state.pendingLiteral.body = Buffer.concat([state.pendingLiteral.body, state.lineBuffer.subarray(0, need)]);
386
+ state.lineBuffer = state.lineBuffer.subarray(need);
387
+ _completeLiteralCommand(state, socket);
388
+ continue;
389
+ }
390
+ var crlf = state.lineBuffer.indexOf("\r\n");
391
+ if (crlf === -1) {
392
+ if (state.lineBuffer.length > maxLineBytes) {
393
+ _writeUntagged(socket, "BAD Line too long (cap " + maxLineBytes + ")");
394
+ _close(socket, state);
395
+ }
396
+ return;
397
+ }
398
+ var rawLine = state.lineBuffer.subarray(0, crlf).toString("utf8");
399
+ state.lineBuffer = state.lineBuffer.subarray(crlf + 2);
400
+ _handleLine(state, socket, rawLine);
401
+ if (state.stage === "closed") return;
402
+ }
403
+ }
404
+
405
+ function _handleLine(state, socket, line) {
406
+ // Continuation: AUTHENTICATE multi-step expects a client response
407
+ if (state.authPending) {
408
+ _runAuthStep(state, socket, line.trim());
409
+ return;
410
+ }
411
+ // IDLE termination — RFC 2177 §3 expects `DONE` line.
412
+ if (state.idle) {
413
+ if (line.toUpperCase() === "DONE") {
414
+ var idleTag = state.idle.tag;
415
+ if (state.idle.timer) clearTimeout(state.idle.timer);
416
+ state.idle = null;
417
+ _writeTagged(socket, idleTag, "OK IDLE terminated");
418
+ } else {
419
+ _writeUntagged(socket, "BAD Expected DONE during IDLE");
420
+ }
421
+ return;
422
+ }
423
+ var parsed;
424
+ try {
425
+ parsed = guardImapCommand.validate(line, {
426
+ profile: profile,
427
+ authenticated: state.actor !== null,
428
+ });
429
+ } catch (e) {
430
+ if (e && e.code === "guard-imap-command/literal-smuggling") {
431
+ _emit("mail.server.imap.smtp_smuggling_detected",
432
+ { connectionId: state.id, line: line.slice(0, LINE_PREVIEW) }, "denied");
433
+ }
434
+ _writeUntagged(socket, "BAD " + (e && e.message ? e.message.slice(0, ERR_CLAMP) : "syntax"));
435
+ return;
436
+ }
437
+ // Literal-opener: stash + emit continuation. Zero-length literals
438
+ // (`{0}`) are legal per RFC 9051 §6.3.12 (e.g. APPEND of an empty
439
+ // message body — rare but spec-compliant; refusing them would
440
+ // diverge from the wire-protocol).
441
+ if (parsed.literalSize !== null) {
442
+ if (parsed.literalSize > maxLiteralBytes) {
443
+ _emit("mail.server.imap.literal_overflow_refused",
444
+ { connectionId: state.id, attempted: parsed.literalSize, cap: maxLiteralBytes },
445
+ "denied");
446
+ _writeTagged(socket, parsed.tag,
447
+ "NO Literal " + parsed.literalSize + " bytes exceeds cap " + maxLiteralBytes);
448
+ return;
449
+ }
450
+ // Zero-byte literal: no continuation, no read — synthesize the
451
+ // pending-literal with an empty body and complete immediately on
452
+ // the next loop tick.
453
+ if (parsed.literalSize === 0) {
454
+ state.pendingLiteral = {
455
+ tag: parsed.tag,
456
+ verb: parsed.verb,
457
+ line: line,
458
+ size: 0,
459
+ body: Buffer.alloc(0),
460
+ synchronizing: !parsed.literalNonSync,
461
+ };
462
+ _completeLiteralCommand(state, socket);
463
+ return;
464
+ }
465
+ state.pendingLiteral = {
466
+ tag: parsed.tag,
467
+ verb: parsed.verb,
468
+ line: line,
469
+ size: parsed.literalSize,
470
+ body: Buffer.alloc(0),
471
+ synchronizing: !parsed.literalNonSync,
472
+ };
473
+ if (!parsed.literalNonSync) {
474
+ _writeUntagged(socket, "+ Ready for literal data");
475
+ }
476
+ return;
477
+ }
478
+ _dispatch(state, socket, parsed, line);
479
+ }
480
+
481
+ function _completeLiteralCommand(state, socket) {
482
+ var pending = state.pendingLiteral;
483
+ state.pendingLiteral = null;
484
+ // Strip the trailing literal opener `{N}` (or `{N+}`) from the line
485
+ var lineNoLit = pending.line.replace(/\{[0-9]+\+?\}$/, "").trim(); // allow:regex-no-length-cap — line length already capped upstream
486
+ var parsed;
487
+ try { parsed = guardImapCommand.validate(lineNoLit, { profile: profile, authenticated: state.actor !== null }); }
488
+ catch (e) {
489
+ _writeTagged(socket, pending.tag, "BAD " + (e && e.message ? e.message.slice(0, ERR_CLAMP) : "syntax"));
490
+ return;
491
+ }
492
+ _dispatch(state, socket, parsed, lineNoLit, pending.body);
493
+ }
494
+
495
+ // Adapter shim — uniform `(state, socket, parsed, literalBody)`
496
+ // dispatch contract over the per-verb handlers. Builds the registry
497
+ // defaults lazily on first dispatch so the closure-scoped handler
498
+ // references are bound when needed (handlers are hoisted by their
499
+ // function-declarations; the registry init runs at dispatch time).
500
+ var _registry = null;
501
+ function _ensureRegistry() {
502
+ if (_registry !== null) return _registry;
503
+ // Per-handler resource budgets. Sized per the verb's known
504
+ // payload shape (LIST scans the folder tree; FETCH walks N
505
+ // messages; APPEND accepts a literal up to maxLiteralBytes).
506
+ var SHORT_MS = 5 * 1000; // allow:raw-time-literal — 5s short-command budget
507
+ var MEDIUM_MS = 30 * 1000; // allow:raw-time-literal — 30s medium-command budget
508
+ var LONG_MS = 2 * 60 * 1000; // allow:raw-time-literal — 2 min long-command budget (FETCH / APPEND)
509
+ var SHORT_B = 8 * 1024; // allow:raw-byte-literal — 8 KiB short-command response cap
510
+ var MEDIUM_B = 1024 * 1024; // allow:raw-byte-literal — 1 MiB medium-command response cap
511
+ var LONG_B = 64 * 1024 * 1024; // allow:raw-byte-literal — 64 MiB FETCH/APPEND response cap
512
+ var defaults = {
513
+ CAPABILITY: { fn: function (s, so, p) { return _handleCapability(s, so, p.tag); },
514
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
515
+ NOOP: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "OK NOOP completed"); },
516
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
517
+ LOGOUT: { fn: function (s, so, p) { return _handleLogout(s, so, p.tag); },
518
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
519
+ ID: { fn: function (s, so, p) { return _handleId(s, so, p.tag, p.args); },
520
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
521
+ STARTTLS: { fn: function (s, so, p) { return _handleStartTls(s, so, p.tag); },
522
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
523
+ AUTHENTICATE: { fn: function (s, so, p) { return _handleAuthenticate(s, so, p.tag, p.args); },
524
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
525
+ LOGIN: { fn: function (s, so, p) { return _handleLogin(s, so, p.tag, p.args); },
526
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
527
+ ENABLE: { fn: function (s, so, p) { return _handleEnable(s, so, p.tag, p.args); },
528
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
529
+ SELECT: { fn: function (s, so, p) { return _handleSelect(s, so, p.tag, p.args, false); },
530
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
531
+ EXAMINE: { fn: function (s, so, p) { return _handleSelect(s, so, p.tag, p.args, true); },
532
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
533
+ LIST: { fn: function (s, so, p) { return _handleList(s, so, p.tag, p.args); },
534
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
535
+ STATUS: { fn: function (s, so, p) { return _handleStatus(s, so, p.tag, p.args); },
536
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
537
+ NAMESPACE: { fn: function (s, so, p) {
538
+ _writeUntagged(so, "NAMESPACE ((\"\" \"/\")) NIL NIL");
539
+ return _writeTagged(so, p.tag, "OK NAMESPACE completed");
540
+ },
541
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
542
+ APPEND: { fn: function (s, so, p, lit) { return _handleAppend(s, so, p.tag, p.args, lit); },
543
+ maxHandlerBytes: LONG_B, maxHandlerMs: LONG_MS },
544
+ CHECK: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "OK CHECK completed"); },
545
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
546
+ CLOSE: { fn: function (s, so, p) { return _handleClose(s, so, p.tag); },
547
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
548
+ UNSELECT: { fn: function (s, so, p) { return _handleClose(s, so, p.tag); },
549
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
550
+ EXPUNGE: { fn: function (s, so, p) { return _handleExpunge(s, so, p.tag); },
551
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
552
+ FETCH: { fn: function (s, so, p) { return _handleFetch(s, so, p.tag, p.args); },
553
+ maxHandlerBytes: LONG_B, maxHandlerMs: LONG_MS },
554
+ STORE: { fn: function (s, so, p) { return _handleStore(s, so, p.tag, p.args); },
555
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
556
+ UID: { fn: function (s, so, p) { return _handleUid(s, so, p.tag, p.args); },
557
+ maxHandlerBytes: LONG_B, maxHandlerMs: LONG_MS },
558
+ IDLE: { fn: function (s, so, p) { return _handleIdle(s, so, p.tag); },
559
+ maxHandlerBytes: SHORT_B, maxHandlerMs: LONG_MS },
560
+ // v0.11.28 — RFC 5465 NOTIFY / RFC 5464 METADATA / RFC 4469 CATENATE.
561
+ NOTIFY: { fn: function (s, so, p) { return _handleNotify(s, so, p.tag, p.args); },
562
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
563
+ GETMETADATA: { fn: function (s, so, p) { return _handleGetMetadata(s, so, p.tag, p.args); },
564
+ maxHandlerBytes: MEDIUM_B, maxHandlerMs: MEDIUM_MS },
565
+ SETMETADATA: { fn: function (s, so, p, lit) { return _handleSetMetadata(s, so, p.tag, p.args, lit); },
566
+ maxHandlerBytes: LONG_B, maxHandlerMs: MEDIUM_MS },
567
+ DONE: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "BAD DONE outside IDLE"); },
568
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
569
+ // Defaults for the verbs the v0.9.49 listener didn't dispatch —
570
+ // operators wire concrete handlers via opts.overrides.
571
+ SEARCH: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO SEARCH not configured"); },
572
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
573
+ CREATE: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO CREATE not configured"); },
574
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
575
+ DELETE: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO DELETE not configured"); },
576
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
577
+ RENAME: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO RENAME not configured"); },
578
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
579
+ SUBSCRIBE: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO SUBSCRIBE not configured"); },
580
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
581
+ UNSUBSCRIBE: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO UNSUBSCRIBE not configured"); },
582
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
583
+ COPY: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO COPY not configured"); },
584
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
585
+ MOVE: { fn: function (s, so, p) { return _writeTagged(so, p.tag, "NO MOVE not configured"); },
586
+ maxHandlerBytes: SHORT_B, maxHandlerMs: SHORT_MS },
587
+ };
588
+ _registry = mailServerRegistry.create({
589
+ protocol: "imap",
590
+ defaults: defaults,
591
+ overrides: opts.overrides || {},
592
+ // b.agent.tenant adoption (v0.10.12). Operators wiring multi-
593
+ // tenant IMAP deployments pass `tenantScope` from
594
+ // `b.agent.tenant.create({...})` plus the per-listener tenant id.
595
+ // The registry then gates every dispatch on
596
+ // `tenantScope.check(state.actor, agentTenantId)` before guard
597
+ // validation or audit emission.
598
+ tenantScope: opts.tenantScope || null,
599
+ agentTenantId: opts.agentTenantId || null,
600
+ notFoundHandler: function (verb, _state, socket, parsed) {
601
+ return _writeTagged(socket, parsed.tag,
602
+ "BAD Verb '" + verb + "' not implemented in v1");
603
+ },
604
+ });
605
+ return _registry;
606
+ }
607
+
608
+ function _dispatch(state, socket, parsed, _rawLine, literalBody) {
609
+ // Registry dispatch may return a Promise (async override handler,
610
+ // or a safeAsync.withTimeout-wrapped Promise). The caller's
611
+ // try/catch is synchronous, so a Promise rejection would surface
612
+ // as an unhandled rejection AND the client would never receive
613
+ // the tagged error reply. Attach a catch that converts the
614
+ // rejection into a `BAD`/`NO` tagged response + audit emit.
615
+ var result;
616
+ try {
617
+ result = _ensureRegistry().dispatch(parsed.verb, state, socket, parsed, literalBody);
618
+ } catch (err) {
619
+ _writeTagged(socket, parsed.tag,
620
+ "NO " + ((err && err.message) || "handler threw").slice(0, ERR_CLAMP));
621
+ _emit("mail.server.imap.handler_threw",
622
+ { connectionId: state.id, verb: parsed.verb,
623
+ error: (err && err.message) || String(err) }, "failure");
624
+ return;
625
+ }
626
+ if (result && typeof result.then === "function") {
627
+ result.then(
628
+ function () { /* tagged response already written by handler */ },
629
+ function (err) {
630
+ try {
631
+ _writeTagged(socket, parsed.tag,
632
+ "NO " + ((err && err.message) || "handler rejected").slice(0, ERR_CLAMP));
633
+ } catch (_we) { /* socket may already be gone */ }
634
+ try {
635
+ _emit("mail.server.imap.handler_rejected",
636
+ { connectionId: state.id, verb: parsed.verb,
637
+ error: (err && err.message) || String(err) }, "failure");
638
+ } catch (_ae) { /* drop-silent */ }
639
+ }
640
+ );
641
+ }
642
+ return result;
643
+ }
644
+
645
+ function _capabilityLine(state) {
646
+ var caps = ["IMAP4rev2"];
647
+ if (!state.tls) caps.push("STARTTLS");
648
+ // RFC 7162 §3 — CONDSTORE is server-advertised; clients ENABLE
649
+ // before relying on MODSEQ in untagged FETCH responses. QRESYNC
650
+ // (§3.2) adds the VANISHED responses on SELECT + post-EXPUNGE
651
+ // and implicitly engages CONDSTORE per §3.2.5.
652
+ caps.push("CONDSTORE");
653
+ caps.push("QRESYNC");
654
+ // v0.11.28 — opt-in extensions (advertised so capable clients can
655
+ // exercise them; each handler refuses gracefully when the operator
656
+ // backend doesn't supply the corresponding hook).
657
+ caps.push("NOTIFY"); // RFC 5465
658
+ caps.push("METADATA"); // RFC 5464 — per-mailbox annotations // allow:raw-byte-literal — RFC number in comment
659
+ caps.push("METADATA-SERVER"); // RFC 5464 §3.1 — server-wide annotations // allow:raw-byte-literal — RFC number in comment
660
+ caps.push("CATENATE"); // RFC 4469 — APPEND from existing parts
661
+ // NB: COMPRESS=DEFLATE (RFC 4978) intentionally NOT advertised —
662
+ // CRIME-class compression-oracle attack on the encrypted IMAP
663
+ // stream. Operators who explicitly enable it via opts.compress
664
+ // get a documented downgrade; v1 default is off.
665
+ // Advertise AUTH=<mech> ONLY for mechanisms the operator wired
666
+ // in opts.auth.mechanisms. RFC 9051 §7.2 — clients pick from the
667
+ // advertised list; advertising AUTH=PLAIN when authConfig is null
668
+ // or doesn't include PLAIN sets clients up for AUTHENTICATE
669
+ // requests that the listener refuses with "no AUTHENTICATE
670
+ // configured" / "mechanism not advertised".
671
+ if (authConfig && Array.isArray(authConfig.mechanisms)) {
672
+ for (var i = 0; i < authConfig.mechanisms.length; i += 1) {
673
+ var m = String(authConfig.mechanisms[i]).toUpperCase();
674
+ if (caps.indexOf("AUTH=" + m) === -1) caps.push("AUTH=" + m);
675
+ }
676
+ }
677
+ return caps.join(" ");
678
+ }
679
+
680
+ // RFC 7162 §3.1 — ENABLE CONDSTORE flips the per-state flag that
681
+ // makes subsequent untagged FETCH responses include the MODSEQ
682
+ // attribute and lets STORE / FETCH carry CHANGEDSINCE /
683
+ // UNCHANGEDSINCE modifiers. Unknown ENABLE arguments are silently
684
+ // ignored per RFC 5161 §3.1 — the server lists in `ENABLED <name>`
685
+ // only the extensions it actually turned on.
686
+ function _handleEnable(state, socket, tag, args) {
687
+ var requested = (args || "").split(/\s+/).filter(Boolean);
688
+ var enabled = [];
689
+ for (var i = 0; i < requested.length; i += 1) {
690
+ var name = requested[i].toUpperCase();
691
+ if (name === "CONDSTORE") {
692
+ if (!state.enabledCondStore) {
693
+ state.enabledCondStore = true;
694
+ enabled.push("CONDSTORE");
695
+ }
696
+ } else if (name === "QRESYNC") {
697
+ // RFC 7162 §3.2.5 — QRESYNC implicitly engages CONDSTORE.
698
+ // The client signals it can consume `* VANISHED (EARLIER)`
699
+ // responses on SELECT / EXAMINE + post-EXPUNGE; the listener
700
+ // flips both flags and the SELECT handler honours the
701
+ // QRESYNC parameter list when present.
702
+ if (!state.enabledQResync) {
703
+ state.enabledQResync = true;
704
+ state.enabledCondStore = true;
705
+ enabled.push("QRESYNC");
706
+ }
707
+ }
708
+ }
709
+ _writeUntagged(socket, "ENABLED" + (enabled.length ? " " + enabled.join(" ") : ""));
710
+ _writeTagged(socket, tag, "OK ENABLE completed");
711
+ }
712
+
713
+ // RFC 5465 NOTIFY — `NOTIFY SET [STATUS] (<filter-set> (<event>...))*`
714
+ // / `NOTIFY NONE`. Subscribes the connection to mailbox / message
715
+ // events on a filter set. Actual event emission is operator-side
716
+ // (the backend's `subscribeNotify(actor, spec, emitFn)` hook); this
717
+ // handler stores the parsed subscription on `state.notifySpec` so
718
+ // the backend can read it on later mutations. NOTIFY NONE clears.
719
+ function _handleNotify(state, socket, tag, args) {
720
+ if (!_requireAuth(state, socket, tag)) return;
721
+ var raw = (args || "").trim();
722
+ if (/^NONE\b/i.test(raw)) {
723
+ state.notifySpec = null;
724
+ if (typeof mailStore.subscribeNotify === "function") {
725
+ try { mailStore.subscribeNotify(state.actor, null, null); }
726
+ catch (_e) { /* drop-silent — operator hook may refuse mid-life */ }
727
+ }
728
+ _writeTagged(socket, tag, "OK NOTIFY completed");
729
+ return;
730
+ }
731
+ var setMatch = raw.match(/^SET\s+(?:STATUS\s+)?(.+)$/i); // allow:regex-no-length-cap — args length already capped upstream
732
+ if (!setMatch) {
733
+ _writeTagged(socket, tag, "BAD NOTIFY syntax (RFC 5465 §6)");
734
+ return;
735
+ }
736
+ // Store the spec verbatim; the backend parses the filter-set
737
+ // vocabulary (`SELECTED`, `SELECTED-DELAYED`, `INBOXES`,
738
+ // `PERSONAL`, `SUBSCRIBED`, `MAILBOXES <list>`, `SUBTREE <list>`)
739
+ // since the event semantics live there. The listener's job is to
740
+ // hand the wire string to the backend.
741
+ state.notifySpec = setMatch[1];
742
+ if (typeof mailStore.subscribeNotify === "function") {
743
+ Promise.resolve()
744
+ .then(function () {
745
+ return mailStore.subscribeNotify(state.actor, state.notifySpec, function (event) {
746
+ // Backend pushes events as { kind, mailbox, payload }; we
747
+ // emit them as untagged responses on the same connection.
748
+ if (!event || typeof event.kind !== "string") return;
749
+ try {
750
+ if (event.kind === "STATUS") {
751
+ _writeUntagged(socket, "STATUS " + event.payload);
752
+ } else if (event.kind === "LIST") {
753
+ _writeUntagged(socket, "LIST " + event.payload);
754
+ } else if (event.kind === "FETCH") {
755
+ _writeUntagged(socket, (event.seq || "") + " FETCH (" + (event.payload || "") + ")");
756
+ }
757
+ } catch (_e) { /* drop-silent — socket may already be closed */ }
758
+ });
759
+ })
760
+ .then(function () { _writeTagged(socket, tag, "OK NOTIFY completed"); })
761
+ .catch(function (err) {
762
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "NOTIFY refused").slice(0, ERR_CLAMP));
763
+ });
764
+ return;
765
+ }
766
+ // Backend doesn't expose the subscribe hook — accept the wire
767
+ // command but emit no events. RFC 5465 §6 says NO is the right
768
+ // refusal shape when the server cannot fulfil the subscription.
769
+ _writeTagged(socket, tag, "NO NOTIFY backend not configured");
770
+ }
771
+
772
+ // RFC 5464 §4.1 GETMETADATA — `GETMETADATA [opts] mailbox entries`.
773
+ // `mailbox` may be `""` for server-wide annotations (METADATA-SERVER).
774
+ // Entries are slash-prefixed names (`/private/foo` / `/shared/bar`).
775
+ // Backend hook: `mailStore.getMetadata(actor, mailbox, names) →
776
+ // [{ entry, value }]`.
777
+ function _handleGetMetadata(state, socket, tag, args) {
778
+ if (!_requireAuth(state, socket, tag)) return;
779
+ if (typeof mailStore.getMetadata !== "function") {
780
+ _writeTagged(socket, tag, "NO GETMETADATA backend not configured");
781
+ return;
782
+ }
783
+ // Strip optional MAXSIZE / DEPTH opts: GETMETADATA (MAXSIZE 1024) "" ("/foo")
784
+ var rest = (args || "").trim();
785
+ var opts = {};
786
+ var optsMatch = rest.match(/^\(([^)]+)\)\s+(.+)$/); // allow:regex-no-length-cap — args length already capped upstream
787
+ if (optsMatch) {
788
+ var optBody = optsMatch[1];
789
+ var maxMatch = optBody.match(/MAXSIZE\s+(\d+)/i); // allow:regex-no-length-cap — optBody bounded by parens
790
+ if (maxMatch) opts.maxSize = parseInt(maxMatch[1], 10);
791
+ var depthMatch = optBody.match(/DEPTH\s+(\w+)/i); // allow:regex-no-length-cap — optBody bounded
792
+ if (depthMatch) opts.depth = depthMatch[1];
793
+ rest = optsMatch[2];
794
+ }
795
+ var partsMatch = rest.match(/^(\S+|"[^"]*")\s+(\(([^)]+)\)|(\/\S+))$/); // allow:regex-no-length-cap — args length already capped upstream
796
+ if (!partsMatch) {
797
+ _writeTagged(socket, tag, "BAD GETMETADATA syntax (RFC 5464 §4.1)");
798
+ return;
799
+ }
800
+ var mailbox = _unquote(partsMatch[1]);
801
+ var entries = partsMatch[3]
802
+ ? partsMatch[3].split(/\s+/).filter(Boolean)
803
+ : [partsMatch[4]];
804
+ if (mailbox !== "" && !_validateMailboxName(mailbox, { allowLegacyMUtf7: allowLegacyMUtf7 })) {
805
+ _writeTagged(socket, tag, "BAD Mailbox name refused");
806
+ return;
807
+ }
808
+ Promise.resolve()
809
+ .then(function () { return mailStore.getMetadata(state.actor, mailbox, entries, opts); })
810
+ .then(function (rows) {
811
+ if (Array.isArray(rows) && rows.length > 0) {
812
+ var pairs = rows.map(function (r) {
813
+ var v = r.value === null || r.value === undefined ? "NIL" : '"' + String(r.value).replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + '"';
814
+ return r.entry + " " + v;
815
+ }).join(" ");
816
+ _writeUntagged(socket, "METADATA " + (mailbox === "" ? '""' : mailbox) + " (" + pairs + ")");
817
+ }
818
+ _writeTagged(socket, tag, "OK GETMETADATA completed");
819
+ })
820
+ .catch(function (err) {
821
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "GETMETADATA failed").slice(0, ERR_CLAMP));
822
+ });
823
+ }
824
+
825
+ // RFC 5464 §4.3 SETMETADATA — `SETMETADATA mailbox (entry value ...)`.
826
+ // Setting `value = NIL` clears the entry. Backend hook:
827
+ // `mailStore.setMetadata(actor, mailbox, entries)`. The wire format
828
+ // delivers each value as a quoted-string or NIL atom; the parser
829
+ // here handles the simple single-line shape (no literals across
830
+ // SETMETADATA — operators using >1 KiB metadata go through APPEND).
831
+ function _handleSetMetadata(state, socket, tag, args, _literalBody) {
832
+ if (!_requireAuth(state, socket, tag)) return;
833
+ if (typeof mailStore.setMetadata !== "function") {
834
+ _writeTagged(socket, tag, "NO SETMETADATA backend not configured");
835
+ return;
836
+ }
837
+ var match = (args || "").trim().match(/^(\S+|"[^"]*")\s+\((.+)\)$/); // allow:regex-no-length-cap — args length already capped upstream
838
+ if (!match) {
839
+ _writeTagged(socket, tag, "BAD SETMETADATA syntax (RFC 5464 §4.3)");
840
+ return;
841
+ }
842
+ var mailbox = _unquote(match[1]);
843
+ var body = match[2];
844
+ if (mailbox !== "" && !_validateMailboxName(mailbox, { allowLegacyMUtf7: allowLegacyMUtf7 })) {
845
+ _writeTagged(socket, tag, "BAD Mailbox name refused");
846
+ return;
847
+ }
848
+ // Tokenise `<entry> <value> <entry> <value> ...`. Values are
849
+ // `"..."` quoted-string OR `NIL`. Entries are `/private/...` /
850
+ // `/shared/...` slash-prefixed names.
851
+ var entries = [];
852
+ var i = 0;
853
+ while (i < body.length) {
854
+ while (i < body.length && /\s/.test(body[i])) i++;
855
+ if (i >= body.length) break;
856
+ var entryStart = i;
857
+ while (i < body.length && !/\s/.test(body[i])) i++;
858
+ var entryName = body.slice(entryStart, i);
859
+ while (i < body.length && /\s/.test(body[i])) i++;
860
+ if (i >= body.length) {
861
+ _writeTagged(socket, tag, "BAD SETMETADATA entry '" + entryName + "' missing value");
862
+ return;
863
+ }
864
+ var valStart = i;
865
+ var value;
866
+ if (body[i] === '"') {
867
+ i++;
868
+ var v = "";
869
+ while (i < body.length && body[i] !== '"') {
870
+ if (body[i] === "\\" && i + 1 < body.length) { v += body[i + 1]; i += 2; }
871
+ else { v += body[i]; i++; }
872
+ }
873
+ if (body[i] !== '"') {
874
+ _writeTagged(socket, tag, "BAD SETMETADATA unterminated quoted value");
875
+ return;
876
+ }
877
+ i++;
878
+ value = v;
879
+ } else {
880
+ while (i < body.length && !/\s/.test(body[i])) i++;
881
+ var tok = body.slice(valStart, i);
882
+ value = tok.toUpperCase() === "NIL" ? null : tok;
883
+ }
884
+ entries.push({ entry: entryName, value: value });
885
+ }
886
+ if (entries.length === 0) {
887
+ _writeTagged(socket, tag, "BAD SETMETADATA empty entry list");
888
+ return;
889
+ }
890
+ Promise.resolve()
891
+ .then(function () { return mailStore.setMetadata(state.actor, mailbox, entries); })
892
+ .then(function () { _writeTagged(socket, tag, "OK SETMETADATA completed"); })
893
+ .catch(function (err) {
894
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "SETMETADATA failed").slice(0, ERR_CLAMP));
895
+ });
896
+ }
897
+
898
+ function _handleCapability(state, socket, tag) {
899
+ _writeUntagged(socket, "CAPABILITY " + _capabilityLine(state));
900
+ _writeTagged(socket, tag, "OK CAPABILITY completed");
901
+ }
902
+
903
+ function _handleId(state, socket, tag, args) {
904
+ // RFC 2971 — clients send a key/value list, server replies with
905
+ // its own. We accept anything (validator caps line size) and reply
906
+ // with a minimal identifier.
907
+ void args;
908
+ _writeUntagged(socket, "ID (\"name\" \"blamejs\" \"version\" \"" + pkgVersion + "\")");
909
+ _writeTagged(socket, tag, "OK ID completed");
910
+ }
911
+
912
+ function _handleLogout(state, socket, tag) {
913
+ _writeUntagged(socket, "BYE Logging out");
914
+ _writeTagged(socket, tag, "OK LOGOUT completed");
915
+ _close(socket, state);
916
+ }
917
+
918
+ function _handleStartTls(state, socket, tag) {
919
+ if (state.tls) {
920
+ _writeTagged(socket, tag, "BAD TLS already negotiated");
921
+ return;
922
+ }
923
+ _writeTagged(socket, tag, "OK Begin TLS negotiation now");
924
+ // Drain EVERY pre-handshake state field that could carry attacker-
925
+ // controlled bytes past the upgrade boundary (RFC 9051 §11.1 /
926
+ // CVE-2021-33515 class STARTTLS-injection defense):
927
+ // - lineBuffer: unparsed bytes pipelined before the handshake.
928
+ // - pendingLiteral: half-collected APPEND/AUTHENTICATE literal
929
+ // bytes; if not cleared, the literal completes after upgrade
930
+ // using bytes the peer sent in plaintext.
931
+ // - authPending: the AUTHENTICATE step token; a dangling token
932
+ // would let the post-TLS state machine resume an exchange that
933
+ // started in plaintext, conflating cleartext + TLS-protected
934
+ // phases of the same SASL run.
935
+ // Listener-removal + idle-timeout re-arm live in the shared
936
+ // upgradeSocket helper (b.mail.server.tls.upgradeSocket).
937
+ state.lineBuffer = Buffer.alloc(0);
938
+ state.pendingLiteral = null;
939
+ state.authPending = null;
940
+ mailServerTls.upgradeSocket({
941
+ plainSocket: socket,
942
+ secureContext: opts.tlsContext,
943
+ idleTimeoutMs: idleTimeoutMs,
944
+ onSecure: function (_tlsSocket) { state.tls = true; },
945
+ onData: function (tlsSocket, chunk) {
946
+ state.lineBuffer = Buffer.concat([state.lineBuffer, chunk]);
947
+ _drainBuffer(state, tlsSocket);
948
+ },
949
+ onError: function (err) {
950
+ _emit("mail.server.imap.tls_handshake_failed",
951
+ { connectionId: state.id, error: (err && err.message) || String(err) }, "failure");
952
+ _close(socket, state);
953
+ },
954
+ onTimeout: function (tlsSocket) {
955
+ _writeUntagged(tlsSocket, "BYE Idle timeout");
956
+ _close(tlsSocket, state);
957
+ },
958
+ });
959
+ }
960
+
961
+ function _handleAuthenticate(state, socket, tag, args) {
962
+ if (state.actor) {
963
+ _writeTagged(socket, tag, "BAD Already authenticated");
964
+ return;
965
+ }
966
+ if (!state.tls && profile !== "permissive") {
967
+ _writeTagged(socket, tag, "BAD AUTHENTICATE requires TLS (use STARTTLS first)");
968
+ return;
969
+ }
970
+ if (!authConfig || typeof authConfig.verify !== "function") {
971
+ _writeTagged(socket, tag, "NO AUTHENTICATE not configured on this listener");
972
+ return;
973
+ }
974
+ var authAdmit = rateLimit.checkAuthAdmit(state.remoteAddress);
975
+ if (!authAdmit.ok) {
976
+ _emit("mail.server.imap.auth_rate_limit_refused",
977
+ { connectionId: state.id, remoteAddress: state.remoteAddress, reason: authAdmit.reason },
978
+ "denied");
979
+ _writeTagged(socket, tag, "NO [ALERT] Too many AUTH failures from your IP");
980
+ _close(socket, state);
981
+ return;
982
+ }
983
+ var mechName = args.split(" ")[0].toUpperCase();
984
+ var initialResp = args.indexOf(" ") === -1 ? null : args.slice(args.indexOf(" ") + 1).trim();
985
+ var mechanisms = (authConfig.mechanisms || ["PLAIN", "LOGIN"]).map(function (m) {
986
+ return String(m).toUpperCase();
987
+ });
988
+ if (mechanisms.indexOf(mechName) === -1) {
989
+ _writeTagged(socket, tag, "NO Mechanism '" + mechName + "' not advertised");
990
+ return;
991
+ }
992
+ _emit("mail.server.imap.auth_attempt",
993
+ { connectionId: state.id, mechanism: mechName, remoteAddress: state.remoteAddress });
994
+ state.authPending = { mechanism: mechName, tag: tag, step: 0 };
995
+ _runAuthStep(state, socket, initialResp);
996
+ }
997
+
998
+ function _runAuthStep(state, socket, clientResp) {
999
+ var pending = state.authPending;
1000
+ Promise.resolve()
1001
+ .then(function () {
1002
+ return authConfig.verify(pending.mechanism, {
1003
+ step: pending.step,
1004
+ clientResponse: clientResp,
1005
+ tls: state.tls,
1006
+ remoteAddress: state.remoteAddress,
1007
+ });
1008
+ })
1009
+ .then(function (result) {
1010
+ pending.step += 1;
1011
+ if (result && result.pending && typeof result.challenge === "string") {
1012
+ // Server-side challenge — `+ <base64>` per RFC 9051 §6.2.2.
1013
+ _writeContinuation(socket, result.challenge);
1014
+ return;
1015
+ }
1016
+ if (result && result.ok === true && result.actor) {
1017
+ state.actor = result.actor;
1018
+ state.stage = "authenticated";
1019
+ var savedTag = pending.tag;
1020
+ state.authPending = null;
1021
+ _emit("mail.server.imap.auth_success",
1022
+ { connectionId: state.id, mechanism: pending.mechanism,
1023
+ tenantId: result.actor.tenantId || null });
1024
+ _writeTagged(socket, savedTag, "OK [CAPABILITY " + _capabilityLine(state) + "] AUTHENTICATE completed");
1025
+ return;
1026
+ }
1027
+ var failTag = pending.tag;
1028
+ state.authPending = null;
1029
+ rateLimit.noteAuthFailure(state.remoteAddress);
1030
+ _emit("mail.server.imap.auth_failed",
1031
+ { connectionId: state.id, mechanism: pending.mechanism,
1032
+ reason: (result && result.reason) || "verify-returned-fail" }, "denied");
1033
+ _writeTagged(socket, failTag, "NO Authentication credentials invalid");
1034
+ })
1035
+ .catch(function (err) {
1036
+ var failTag = pending.tag;
1037
+ state.authPending = null;
1038
+ rateLimit.noteAuthFailure(state.remoteAddress);
1039
+ _emit("mail.server.imap.auth_failed",
1040
+ { connectionId: state.id, mechanism: pending.mechanism,
1041
+ reason: (err && err.message) || String(err) }, "failure");
1042
+ _writeTagged(socket, failTag, "NO Authentication failed");
1043
+ });
1044
+ }
1045
+
1046
+ function _handleLogin(state, socket, tag, args) {
1047
+ // RFC 9051 §6.3.4 — LOGIN is deprecated; new MUAs use AUTHENTICATE.
1048
+ if (state.actor) {
1049
+ _writeTagged(socket, tag, "BAD Already authenticated");
1050
+ return;
1051
+ }
1052
+ if (profile === "strict") {
1053
+ _writeTagged(socket, tag, "BAD LOGIN deprecated under strict profile; use AUTHENTICATE");
1054
+ return;
1055
+ }
1056
+ if (!state.tls && profile !== "permissive") {
1057
+ _writeTagged(socket, tag, "BAD LOGIN requires TLS (use STARTTLS first)");
1058
+ return;
1059
+ }
1060
+ if (!authConfig || typeof authConfig.verify !== "function") {
1061
+ _writeTagged(socket, tag, "NO AUTH not configured");
1062
+ return;
1063
+ }
1064
+ var authAdmit = rateLimit.checkAuthAdmit(state.remoteAddress);
1065
+ if (!authAdmit.ok) {
1066
+ _writeTagged(socket, tag, "NO [ALERT] Too many AUTH failures from your IP");
1067
+ _close(socket, state);
1068
+ return;
1069
+ }
1070
+ // LOGIN args: `user pass` (quoted or atom).
1071
+ var parts = _parseLoginArgs(args);
1072
+ if (!parts) {
1073
+ _writeTagged(socket, tag, "BAD LOGIN expects user + pass");
1074
+ return;
1075
+ }
1076
+ Promise.resolve()
1077
+ .then(function () {
1078
+ return authConfig.verify("LOGIN", {
1079
+ step: 0,
1080
+ username: parts[0],
1081
+ password: parts[1],
1082
+ tls: state.tls,
1083
+ remoteAddress: state.remoteAddress,
1084
+ });
1085
+ })
1086
+ .then(function (result) {
1087
+ if (result && result.ok && result.actor) {
1088
+ state.actor = result.actor;
1089
+ state.stage = "authenticated";
1090
+ _emit("mail.server.imap.auth_success",
1091
+ { connectionId: state.id, mechanism: "LOGIN", tenantId: result.actor.tenantId || null });
1092
+ _writeTagged(socket, tag, "OK [CAPABILITY " + _capabilityLine(state) + "] LOGIN completed");
1093
+ return;
1094
+ }
1095
+ rateLimit.noteAuthFailure(state.remoteAddress);
1096
+ _emit("mail.server.imap.auth_failed",
1097
+ { connectionId: state.id, mechanism: "LOGIN", reason: "verify-returned-fail" }, "denied");
1098
+ _writeTagged(socket, tag, "NO LOGIN credentials invalid");
1099
+ })
1100
+ .catch(function () {
1101
+ rateLimit.noteAuthFailure(state.remoteAddress);
1102
+ _writeTagged(socket, tag, "NO LOGIN failed");
1103
+ });
1104
+ }
1105
+
1106
+ function _parseLoginArgs(args) {
1107
+ if (typeof args !== "string") return null;
1108
+ // Quoted or atom — RFC 9051 §5.1 quoted ABNF. Inside a quoted
1109
+ // string `\"` and `\\` are escape sequences for `"` and `\`
1110
+ // respectively; any other `\<chr>` is invalid. The earlier shape
1111
+ // terminated the quoted string at the first `"`, so a hostile
1112
+ // client passing `LOGIN "alice\"@example.com" "pw"` would have
1113
+ // its username truncated at `alice` and the rest of the line
1114
+ // reparsed as the password / literal — wrong identity bound to
1115
+ // the AUTH state.
1116
+ var rest = args.trim();
1117
+ function _take() {
1118
+ if (rest[0] === "\"") {
1119
+ // Walk the quoted-string body, accumulating into `out` while
1120
+ // honoring the `\"` / `\\` escape pairs. A bare `\` followed
1121
+ // by any other character is refused (parse fails → null).
1122
+ var out = "";
1123
+ var i = 1;
1124
+ while (i < rest.length) {
1125
+ var ch = rest.charAt(i);
1126
+ if (ch === "\\") {
1127
+ var esc = rest.charAt(i + 1);
1128
+ if (esc !== "\"" && esc !== "\\") return null;
1129
+ out += esc;
1130
+ i += 2;
1131
+ continue;
1132
+ }
1133
+ if (ch === "\"") {
1134
+ rest = rest.slice(i + 1).trim();
1135
+ return out;
1136
+ }
1137
+ out += ch;
1138
+ i += 1;
1139
+ }
1140
+ return null; // unterminated quoted string
1141
+ }
1142
+ var sp = rest.indexOf(" ");
1143
+ var v2 = sp === -1 ? rest : rest.slice(0, sp);
1144
+ rest = sp === -1 ? "" : rest.slice(sp + 1).trim();
1145
+ return v2;
1146
+ }
1147
+ var user = _take(); if (user === null) return null;
1148
+ var pass = _take(); if (pass === null) return null;
1149
+ return [user, pass];
1150
+ }
1151
+
1152
+ function _requireAuth(state, socket, tag) {
1153
+ if (!state.actor) {
1154
+ _writeTagged(socket, tag, "NO Login first");
1155
+ return false;
1156
+ }
1157
+ return true;
1158
+ }
1159
+
1160
+ function _handleSelect(state, socket, tag, args, examine) {
1161
+ if (!_requireAuth(state, socket, tag)) return;
1162
+ var trimmed = (args || "").trim();
1163
+ // RFC 7162 §3.2.4 — `SELECT mailbox (QRESYNC (<uidvalidity>
1164
+ // <modseq> [<knownUids>] [<knownSequenceMatchData>]))`. The
1165
+ // QRESYNC parameter is wrapped in an outer parenthesis pair after
1166
+ // the mailbox name. Extract it before parsing the mailbox so the
1167
+ // mailbox-name validator sees just the name.
1168
+ var qresyncParam = null;
1169
+ var qresyncMatch = trimmed.match(/^(\S+|"[^"]+")\s+\(\s*QRESYNC\s*\(\s*([^)]+)\)\s*(?:\(\s*([^)]+)\)\s*)?\)\s*$/i); // allow:regex-no-length-cap — args length already capped upstream
1170
+ if (qresyncMatch) {
1171
+ var inner = qresyncMatch[2].trim().split(/\s+/);
1172
+ qresyncParam = {
1173
+ uidvalidity: parseInt(inner[0], 10),
1174
+ modseq: parseInt(inner[1], 10),
1175
+ knownUids: inner[2] || null,
1176
+ knownSeq: qresyncMatch[3] || null,
1177
+ };
1178
+ if (!isFinite(qresyncParam.uidvalidity) || !isFinite(qresyncParam.modseq)) {
1179
+ _writeTagged(socket, tag, "BAD SELECT QRESYNC params must be (<uidvalidity> <modseq> ...) numerics");
1180
+ return;
1181
+ }
1182
+ trimmed = qresyncMatch[1];
1183
+ }
1184
+ var name = _unquote(trimmed);
1185
+ if (!_validateMailboxName(name, { allowLegacyMUtf7: allowLegacyMUtf7 })) {
1186
+ _writeTagged(socket, tag, "BAD Mailbox name refused");
1187
+ return;
1188
+ }
1189
+ // QRESYNC requires CONDSTORE to be engaged; if the client sent
1190
+ // the parameter without having issued ENABLE first, RFC 7162
1191
+ // §3.2.4 lets the server flip the flags implicitly.
1192
+ if (qresyncParam && !state.enabledQResync) {
1193
+ state.enabledQResync = true;
1194
+ state.enabledCondStore = true;
1195
+ }
1196
+ Promise.resolve()
1197
+ .then(function () {
1198
+ if (typeof mailStore.selectFolder === "function") {
1199
+ return mailStore.selectFolder(state.actor, name, {
1200
+ readOnly: examine,
1201
+ qresync: qresyncParam,
1202
+ });
1203
+ }
1204
+ // RFC 9051 §2.3.1.1 — UIDVALIDITY MUST be strictly increasing
1205
+ // and 32-bit unique across the mailbox lifetime. The earlier
1206
+ // fallback returned a sentinel `uidvalidity: 1` to keep tests
1207
+ // green when the operator hadn't wired `selectFolder`, but the
1208
+ // sentinel value collides with any real UIDVALIDITY=1 from a
1209
+ // legitimate backend and tricks clients into believing they
1210
+ // have a valid synced state. Refuse SELECT instead — operators
1211
+ // MUST wire `mailStore.selectFolder` to expose mailboxes.
1212
+ var err = new Error("mailStore.selectFolder is not configured (RFC 9051 §2.3.1.1 requires a unique strictly-increasing UIDVALIDITY)");
1213
+ err.code = "mail-server-imap/no-select-backend";
1214
+ throw err;
1215
+ })
1216
+ .then(function (info) {
1217
+ state.selectedMailbox = name;
1218
+ state.selectedReadOnly = !!examine;
1219
+ state.stage = "selected";
1220
+ var flagsStr = (info.flags && info.flags.length) ? info.flags.join(" ") : "\\Seen \\Answered \\Flagged \\Deleted \\Draft";
1221
+ _writeUntagged(socket, info.exists + " EXISTS");
1222
+ _writeUntagged(socket, info.recent + " RECENT");
1223
+ _writeUntagged(socket, "FLAGS (" + flagsStr + ")");
1224
+ _writeUntagged(socket, "OK [UIDVALIDITY " + info.uidvalidity + "] UIDs valid");
1225
+ _writeUntagged(socket, "OK [UIDNEXT " + info.uidnext + "] Predicted next UID");
1226
+ if (info.modseq !== undefined) {
1227
+ _writeUntagged(socket, "OK [HIGHESTMODSEQ " + info.modseq + "]");
1228
+ }
1229
+ // RFC 7162 §3.2.5 — when SELECT carried a QRESYNC parameter
1230
+ // AND the client's UIDVALIDITY matches, emit a single
1231
+ // `* VANISHED (EARLIER) <uid-set>` listing UIDs the server
1232
+ // expunged since the client's snapshot. The backend supplies
1233
+ // this via `info.vanishedEarlier` (sequence-set string) — the
1234
+ // listener does the wire emission. Mismatched UIDVALIDITY
1235
+ // means the client's cache is stale and MUST re-SELECT; we
1236
+ // skip the VANISHED line in that case so the client falls
1237
+ // through to a full re-sync. RFC 7162 §3.2.5.2 says the
1238
+ // server MAY also include changed-since-modseq FETCH lines
1239
+ // — those flow through the normal FETCH path with
1240
+ // CHANGEDSINCE so we leave them to the operator.
1241
+ if (qresyncParam && info.vanishedEarlier &&
1242
+ info.uidvalidity === qresyncParam.uidvalidity) {
1243
+ _writeUntagged(socket, "VANISHED (EARLIER) " + info.vanishedEarlier);
1244
+ }
1245
+ _emit("mail.server.imap.select", {
1246
+ connectionId: state.id, mailbox: name,
1247
+ modseq: info.modseq || 0, exists: info.exists,
1248
+ qresync: qresyncParam !== null,
1249
+ });
1250
+ _writeTagged(socket, tag, "OK [" + (examine ? "READ-ONLY" : "READ-WRITE") + "] " +
1251
+ (examine ? "EXAMINE" : "SELECT") + " completed");
1252
+ })
1253
+ .catch(function (err) {
1254
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "Select failed").slice(0, ERR_CLAMP));
1255
+ });
1256
+ }
1257
+
1258
+ function _handleList(state, socket, tag, args) {
1259
+ if (!_requireAuth(state, socket, tag)) return;
1260
+ // RFC 9051 §6.3.9 — LIST reference mailbox-pattern. Minimal
1261
+ // implementation delegates to mailStore.listFolders if present.
1262
+ void args;
1263
+ Promise.resolve()
1264
+ .then(function () {
1265
+ if (typeof mailStore.listFolders === "function") {
1266
+ return mailStore.listFolders(state.actor);
1267
+ }
1268
+ return [{ name: "INBOX", attributes: [] }];
1269
+ })
1270
+ .then(function (folders) {
1271
+ for (var i = 0; i < folders.length; i += 1) {
1272
+ var f = folders[i];
1273
+ var attrs = (f.attributes || []).map(function (a) { return "\\" + a; }).join(" ");
1274
+ _writeUntagged(socket, "LIST (" + attrs + ") \"/\" " + _quote(f.name));
1275
+ }
1276
+ _writeTagged(socket, tag, "OK LIST completed");
1277
+ })
1278
+ .catch(function (err) {
1279
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "List failed").slice(0, ERR_CLAMP));
1280
+ });
1281
+ }
1282
+
1283
+ function _handleStatus(state, socket, tag, args) {
1284
+ if (!_requireAuth(state, socket, tag)) return;
1285
+ var match = args.match(/^(\S+|"[^"]+")\s+\(([^)]+)\)$/); // allow:regex-no-length-cap — args length already capped upstream
1286
+ if (!match) {
1287
+ _writeTagged(socket, tag, "BAD STATUS expects mailbox + paren-list of items");
1288
+ return;
1289
+ }
1290
+ var name = _unquote(match[1]);
1291
+ var items = match[2].split(/\s+/);
1292
+ if (!_validateMailboxName(name, { allowLegacyMUtf7: allowLegacyMUtf7 })) {
1293
+ _writeTagged(socket, tag, "BAD Mailbox name refused");
1294
+ return;
1295
+ }
1296
+ Promise.resolve()
1297
+ .then(function () {
1298
+ if (typeof mailStore.statusFolder === "function") {
1299
+ return mailStore.statusFolder(state.actor, name, items);
1300
+ }
1301
+ return { MESSAGES: 0, UIDNEXT: 1, UIDVALIDITY: 1, UNSEEN: 0 };
1302
+ })
1303
+ .then(function (info) {
1304
+ var parts = [];
1305
+ for (var k = 0; k < items.length; k += 1) {
1306
+ var key = items[k].toUpperCase();
1307
+ if (info[key] !== undefined) parts.push(key + " " + info[key]);
1308
+ }
1309
+ _writeUntagged(socket, "STATUS " + _quote(name) + " (" + parts.join(" ") + ")");
1310
+ _writeTagged(socket, tag, "OK STATUS completed");
1311
+ })
1312
+ .catch(function (err) {
1313
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "Status failed").slice(0, ERR_CLAMP));
1314
+ });
1315
+ }
1316
+
1317
+ function _handleAppend(state, socket, tag, args, literalBody) {
1318
+ if (!_requireAuth(state, socket, tag)) return;
1319
+ // RFC 4469 CATENATE — `APPEND mailbox [(flags)] [date-time] CATENATE
1320
+ // (TEXT {literal} URL "imap://...")`. The CATENATE keyword turns the
1321
+ // command body into a list of parts the server stitches into a
1322
+ // single message; backends supply the `appendCatenate(actor,
1323
+ // mailbox, parts, opts) → meta` hook. Without CATENATE, fall
1324
+ // through to the bare APPEND path that already exists.
1325
+ var catenateMatch = args.match(/^(\S+|"[^"]+")(?:\s+\(([^)]*)\))?(?:\s+("[^"]+"))?\s+CATENATE\s+(.+)$/i); // allow:regex-no-length-cap — args length already capped upstream
1326
+ if (catenateMatch) {
1327
+ if (typeof mailStore.appendCatenate !== "function") {
1328
+ _writeTagged(socket, tag, "NO CATENATE backend not configured");
1329
+ return;
1330
+ }
1331
+ var catMailbox = _unquote(catenateMatch[1]);
1332
+ var catFlags = catenateMatch[2] ? catenateMatch[2].split(/\s+/).filter(Boolean) : [];
1333
+ var catDateArg = catenateMatch[3] ? _unquote(catenateMatch[3]) : null;
1334
+ var catInternalDate = null;
1335
+ if (catDateArg) {
1336
+ catInternalDate = _parseImapDateTime(catDateArg);
1337
+ if (catInternalDate === null) {
1338
+ _writeTagged(socket, tag, "BAD APPEND CATENATE date-time invalid");
1339
+ return;
1340
+ }
1341
+ }
1342
+ if (!_validateMailboxName(catMailbox, { allowLegacyMUtf7: allowLegacyMUtf7 })) {
1343
+ _writeTagged(socket, tag, "BAD Mailbox name refused");
1344
+ return;
1345
+ }
1346
+ // Validate the parens are well-formed BEFORE we touch the
1347
+ // backend. The wire-format parts list MUST start with `(` and
1348
+ // end with `)`; a truncated list (e.g. `(TEXT {3}` arriving as
1349
+ // a single literal-completion before the rest of the parts
1350
+ // streams in) is refused. Order-preserving left-to-right token
1351
+ // walk replaces the prior URL-then-TEXT split — CATENATE
1352
+ // semantics depend on the SEQUENCE of parts.
1353
+ var partsBodyRaw = catenateMatch[4];
1354
+ if (partsBodyRaw[0] !== "(" || partsBodyRaw[partsBodyRaw.length - 1] !== ")") {
1355
+ _writeTagged(socket, tag, "BAD APPEND CATENATE parts list missing parens (RFC 4469 §3)");
1356
+ return;
1357
+ }
1358
+ var partsBody = partsBodyRaw.slice(1, -1);
1359
+ var parts = [];
1360
+ var hadTextPart = false;
1361
+ // Tokenise sequentially. Each part is one of:
1362
+ // URL "imap://..."
1363
+ // TEXT {<n>} (literal — multi-literal CATENATE deferred to a
1364
+ // later slice; defer-with-condition: refused
1365
+ // with NO until the multi-literal protocol path
1366
+ // lands).
1367
+ var pi = 0;
1368
+ while (pi < partsBody.length) {
1369
+ while (pi < partsBody.length && /\s/.test(partsBody[pi])) pi += 1;
1370
+ if (pi >= partsBody.length) break;
1371
+ if (/^URL\b/i.test(partsBody.slice(pi))) {
1372
+ pi += 3; // allow:raw-byte-literal — length of literal "URL" keyword
1373
+ while (pi < partsBody.length && /\s/.test(partsBody[pi])) pi += 1;
1374
+ if (partsBody[pi] !== "\"") {
1375
+ _writeTagged(socket, tag, "BAD APPEND CATENATE URL value must be quoted-string");
1376
+ return;
1377
+ }
1378
+ pi += 1;
1379
+ var urlStart = pi;
1380
+ while (pi < partsBody.length && partsBody[pi] !== "\"") pi += 1;
1381
+ if (partsBody[pi] !== "\"") {
1382
+ _writeTagged(socket, tag, "BAD APPEND CATENATE URL value unterminated quoted-string");
1383
+ return;
1384
+ }
1385
+ parts.push({ kind: "URL", url: partsBody.slice(urlStart, pi) });
1386
+ pi += 1;
1387
+ } else if (/^TEXT\b/i.test(partsBody.slice(pi))) {
1388
+ hadTextPart = true;
1389
+ break;
1390
+ } else {
1391
+ _writeTagged(socket, tag, "BAD APPEND CATENATE unknown part (RFC 4469 §3 only URL/TEXT)");
1392
+ return;
1393
+ }
1394
+ }
1395
+ if (hadTextPart) {
1396
+ // Multi-literal CATENATE TEXT parts need a streaming-literal
1397
+ // protocol path the listener doesn't currently expose. RFC
1398
+ // 4469 §3 explicitly permits servers to refuse parts they
1399
+ // can't honour; refusing is correct (better than reordering
1400
+ // and corrupting the message body the client requested).
1401
+ _writeTagged(socket, tag, "NO CATENATE TEXT-literal parts not yet implemented; use APPEND with a single literal");
1402
+ return;
1403
+ }
1404
+ if (parts.length === 0) {
1405
+ _writeTagged(socket, tag, "BAD APPEND CATENATE empty parts list");
1406
+ return;
1407
+ }
1408
+ Promise.resolve()
1409
+ .then(function () {
1410
+ return mailStore.appendCatenate(catMailbox, parts, {
1411
+ actor: state.actor, flags: catFlags, internalDate: catInternalDate });
1412
+ })
1413
+ .then(function (meta) {
1414
+ var ok = "OK APPEND completed";
1415
+ if (meta && meta.uid && meta.uidValidity) {
1416
+ ok = "OK [APPENDUID " + meta.uidValidity + " " + meta.uid + "] APPEND completed";
1417
+ }
1418
+ _writeTagged(socket, tag, ok);
1419
+ })
1420
+ .catch(function (err) {
1421
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "CATENATE failed").slice(0, ERR_CLAMP));
1422
+ });
1423
+ return;
1424
+ }
1425
+ if (!literalBody) {
1426
+ _writeTagged(socket, tag, "BAD APPEND requires a literal {N} message");
1427
+ return;
1428
+ }
1429
+ // RFC 9051 §6.3.12 — APPEND mailbox [(flags)] [date-time] literal
1430
+ var match = args.match(/^(\S+|"[^"]+")(?:\s+\(([^)]*)\))?(?:\s+("[^"]+"))?$/); // allow:regex-no-length-cap — args length already capped upstream
1431
+ if (!match) {
1432
+ _writeTagged(socket, tag, "BAD APPEND syntax");
1433
+ return;
1434
+ }
1435
+ var name = _unquote(match[1]);
1436
+ var flags = match[2] ? match[2].split(/\s+/).filter(Boolean) : [];
1437
+ // RFC 9051 §6.3.12 — optional date-time argument sets INTERNALDATE
1438
+ // on the appended message. Earlier shape captured the token but
1439
+ // never threaded it; backends now receive it as `internalDate`
1440
+ // (ms-since-epoch) and the mail-store applies it instead of the
1441
+ // append-time clock. Refused as syntax error when the date-time
1442
+ // can't be parsed (rather than silently using the clock).
1443
+ var dateTimeArg = match[3] ? _unquote(match[3]) : null;
1444
+ var internalDate = null;
1445
+ if (dateTimeArg) {
1446
+ internalDate = _parseImapDateTime(dateTimeArg);
1447
+ if (internalDate === null) {
1448
+ _writeTagged(socket, tag, "BAD APPEND date-time '" + dateTimeArg +
1449
+ "' not in RFC 9051 §6.3.12 / RFC 5322 §3.3 date-time grammar");
1450
+ return;
1451
+ }
1452
+ }
1453
+ if (!_validateMailboxName(name, { allowLegacyMUtf7: allowLegacyMUtf7 })) {
1454
+ _writeTagged(socket, tag, "BAD Mailbox name refused");
1455
+ return;
1456
+ }
1457
+ Promise.resolve()
1458
+ .then(function () {
1459
+ // RFC 9208 — when the backend exposes a per-mailbox / per-user
1460
+ // quota, APPEND MUST check against it BEFORE writing the
1461
+ // message. The earlier shape called `appendMessage` directly,
1462
+ // leaving quota enforcement entirely up to the backend; an
1463
+ // operator wiring a bare `appendMessage` without quota plumbing
1464
+ // could be DoS'd via unbounded APPENDs filling the mailbox
1465
+ // beyond the advertised QUOTA limit. Honor `mailStore.quota`
1466
+ // (RFC 9208 GETQUOTA / IMAP-QUOTA returns the same shape) and
1467
+ // surface 5.7.4 OVERQUOTA per §5.
1468
+ if (typeof mailStore.quota === "function") {
1469
+ // mailStore.quota(folderName) returns
1470
+ // { usedBytes, usedCount, capBytes, capCount } per the
1471
+ // lib/mail-store.js contract. capBytes is null when no
1472
+ // quota is configured for the folder; honor it only when
1473
+ // it's a positive number.
1474
+ return Promise.resolve(mailStore.quota(name))
1475
+ .then(function (q) {
1476
+ if (q && typeof q.usedBytes === "number" &&
1477
+ typeof q.capBytes === "number" &&
1478
+ q.capBytes > 0 &&
1479
+ q.usedBytes + literalBody.length > q.capBytes) {
1480
+ var err = new Error("APPEND would exceed quota (used " + q.usedBytes +
1481
+ " + " + literalBody.length + " > cap " + q.capBytes + ")");
1482
+ err.code = "mail-server-imap/overquota";
1483
+ err.overquota = true;
1484
+ err.limit = q.capBytes;
1485
+ throw err;
1486
+ }
1487
+ return mailStore.appendMessage(name, literalBody, {
1488
+ actor: state.actor, flags: flags, internalDate: internalDate });
1489
+ });
1490
+ }
1491
+ return mailStore.appendMessage(name, literalBody, {
1492
+ actor: state.actor, flags: flags, internalDate: internalDate });
1493
+ })
1494
+ .then(function (info) {
1495
+ _emit("mail.server.imap.append",
1496
+ { connectionId: state.id, mailbox: name, size: literalBody.length, flags: flags });
1497
+ var token = info && info.uid ? "[APPENDUID " + (info.uidvalidity || 0) + " " + info.uid + "] " : "";
1498
+ _writeTagged(socket, tag, "OK " + token + "APPEND completed");
1499
+ })
1500
+ .catch(function (err) {
1501
+ if (err && err.overquota) {
1502
+ _writeTagged(socket, tag, "NO [OVERQUOTA] Quota exceeded (RFC 9208 §5)");
1503
+ return;
1504
+ }
1505
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "Append failed").slice(0, ERR_CLAMP));
1506
+ });
1507
+ }
1508
+
1509
+ function _handleClose(state, socket, tag) {
1510
+ state.selectedMailbox = null;
1511
+ state.selectedReadOnly = false;
1512
+ state.stage = "authenticated";
1513
+ _writeTagged(socket, tag, "OK CLOSE completed");
1514
+ }
1515
+
1516
+ function _handleExpunge(state, socket, tag) {
1517
+ if (!state.selectedMailbox) {
1518
+ _writeTagged(socket, tag, "NO No mailbox selected");
1519
+ return;
1520
+ }
1521
+ Promise.resolve()
1522
+ .then(function () {
1523
+ if (typeof mailStore.expungeFolder === "function") {
1524
+ return mailStore.expungeFolder(state.actor, state.selectedMailbox);
1525
+ }
1526
+ return { expunged: [], modseq: 0 };
1527
+ })
1528
+ .then(function (info) {
1529
+ var ex = info.expunged || [];
1530
+ for (var i = 0; i < ex.length; i += 1) {
1531
+ _writeUntagged(socket, ex[i] + " EXPUNGE");
1532
+ }
1533
+ _emit("mail.server.imap.expunge",
1534
+ { connectionId: state.id, mailbox: state.selectedMailbox,
1535
+ count: ex.length, modseq: info.modseq || 0 });
1536
+ _writeTagged(socket, tag, "OK EXPUNGE completed");
1537
+ })
1538
+ .catch(function (err) {
1539
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "Expunge failed").slice(0, ERR_CLAMP));
1540
+ });
1541
+ }
1542
+
1543
+ function _handleFetch(state, socket, tag, args, useUid) {
1544
+ if (!state.selectedMailbox) {
1545
+ // RFC 9051 §6.4.5 — FETCH outside of Selected state is a
1546
+ // protocol-context violation, not a server-policy refusal.
1547
+ // BAD signals the client to fix its dialog rather than retry.
1548
+ _writeTagged(socket, tag, "BAD FETCH only valid in Selected state (RFC 9051 §6.4.5)");
1549
+ return;
1550
+ }
1551
+ if (typeof mailStore.fetchRange !== "function") {
1552
+ _writeTagged(socket, tag, "BAD FETCH backend not configured");
1553
+ return;
1554
+ }
1555
+ var match = args.match(/^(\S+)\s+(.+)$/); // allow:regex-no-length-cap — args length already capped upstream
1556
+ if (!match) {
1557
+ _writeTagged(socket, tag, "BAD FETCH expects sequence-set + parts");
1558
+ return;
1559
+ }
1560
+ var seqSet = match[1];
1561
+ var partsSpec = match[2];
1562
+ // RFC 7162 §3.1.4 — FETCH may carry a CHANGEDSINCE modifier in a
1563
+ // trailing parenthesised list:
1564
+ // FETCH 1:* (FLAGS) (CHANGEDSINCE 12345)
1565
+ // and/or VANISHED (QRESYNC) which is deferred to a later slice.
1566
+ // The modifier list is parsed off the END of partsSpec; what
1567
+ // remains is handed to the backend as the fetch-att spec.
1568
+ var changedSince = null;
1569
+ var includeVanished = false;
1570
+ var modMatch = partsSpec.match(/\s*\(([^)]*)\)\s*$/); // allow:regex-no-length-cap — partsSpec already bounded upstream
1571
+ if (modMatch && /\b(CHANGEDSINCE|VANISHED)\b/i.test(modMatch[1])) {
1572
+ var modBody = modMatch[1];
1573
+ var changedMatch = modBody.match(/CHANGEDSINCE\s+(\d+)/i); // allow:regex-no-length-cap — modBody already bounded
1574
+ if (changedMatch) {
1575
+ var csN = parseInt(changedMatch[1], 10);
1576
+ if (isFinite(csN) && csN >= 0) changedSince = csN;
1577
+ }
1578
+ includeVanished = /\bVANISHED\b/i.test(modBody);
1579
+ partsSpec = partsSpec.slice(0, partsSpec.length - modMatch[0].length).trim();
1580
+ }
1581
+ // RFC 7162 §3.1.2 — any FETCH that uses CHANGEDSINCE implicitly
1582
+ // engages CONDSTORE for the session; the client expects MODSEQ
1583
+ // in responses even without a prior `ENABLE CONDSTORE`. RFC 7162
1584
+ // §3.1.4.1 — when CONDSTORE is engaged (explicit ENABLE OR
1585
+ // implicit via CHANGEDSINCE) OR the client requested MODSEQ as a
1586
+ // fetch-att, every untagged FETCH response includes the MODSEQ
1587
+ // attribute. Engaging CONDSTORE via CHANGEDSINCE also sticks for
1588
+ // the rest of the session.
1589
+ if (changedSince !== null && !state.enabledCondStore) {
1590
+ state.enabledCondStore = true;
1591
+ }
1592
+ var includeModseq = state.enabledCondStore === true ||
1593
+ changedSince !== null ||
1594
+ /\bMODSEQ\b/i.test(partsSpec);
1595
+ Promise.resolve()
1596
+ .then(function () {
1597
+ return mailStore.fetchRange(state.actor, state.selectedMailbox, seqSet, partsSpec,
1598
+ { useUid: useUid === true, changedSince: changedSince, includeVanished: includeVanished,
1599
+ includeModseq: includeModseq });
1600
+ })
1601
+ .then(function (rows) {
1602
+ var rs = rows || [];
1603
+ _emit("mail.server.imap.fetch_bulk",
1604
+ { connectionId: state.id, mailbox: state.selectedMailbox, count: rs.length,
1605
+ changedSince: changedSince, condStore: state.enabledCondStore === true });
1606
+ for (var i = 0; i < rs.length; i += 1) {
1607
+ var r = rs[i];
1608
+ var payload = r.payload || "";
1609
+ if (includeModseq && r.modseq !== undefined && !/MODSEQ\s*\(/.test(payload)) {
1610
+ payload = (payload ? payload + " " : "") + "MODSEQ (" + r.modseq + ")";
1611
+ }
1612
+ _writeUntagged(socket, r.seq + " FETCH (" + payload + ")");
1613
+ }
1614
+ _writeTagged(socket, tag, "OK FETCH completed");
1615
+ })
1616
+ .catch(function (err) {
1617
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "Fetch failed").slice(0, ERR_CLAMP));
1618
+ });
1619
+ }
1620
+
1621
+ function _handleStore(state, socket, tag, args, useUid) {
1622
+ if (!state.selectedMailbox) {
1623
+ // RFC 9051 §6.4.6 — STORE outside of Selected state is a
1624
+ // protocol-context violation. BAD (not NO) is the correct
1625
+ // response per the IMAP grammar; UID STORE has the same rule
1626
+ // since the verb is just a `UID` prefix on STORE.
1627
+ _writeTagged(socket, tag, "BAD STORE only valid in Selected state (RFC 9051 §6.4.6)");
1628
+ return;
1629
+ }
1630
+ if (state.selectedReadOnly) {
1631
+ _writeTagged(socket, tag, "NO Mailbox is read-only");
1632
+ return;
1633
+ }
1634
+ if (typeof mailStore.storeFlags !== "function") {
1635
+ _writeTagged(socket, tag, "BAD STORE backend not configured");
1636
+ return;
1637
+ }
1638
+ // RFC 7162 §3.1.3 — STORE may carry a parenthesised UNCHANGEDSINCE
1639
+ // modifier between the sequence-set and the FLAGS op:
1640
+ // STORE 1:* (UNCHANGEDSINCE 12345) +FLAGS (\Deleted)
1641
+ // The backend's response shape is { rows, modified } — `modified`
1642
+ // is the seq-set string of message ids whose modseq advanced past
1643
+ // unchangedSince before this STORE ran. We surface those via
1644
+ // [MODIFIED <set>] OK response (RFC 7162 §3.1.3).
1645
+ var unchangedSince = null;
1646
+ var unchangedMatch = args.match(/^(\S+)\s+\(UNCHANGEDSINCE\s+(\d+)\)\s+(.+)$/i); // allow:regex-no-length-cap — args length already capped upstream
1647
+ if (unchangedMatch) {
1648
+ var usN = parseInt(unchangedMatch[2], 10);
1649
+ if (isFinite(usN) && usN >= 0) unchangedSince = usN;
1650
+ args = unchangedMatch[1] + " " + unchangedMatch[3];
1651
+ }
1652
+ var match = args.match(/^(\S+)\s+([+-]?FLAGS(?:\.SILENT)?)\s+\(([^)]*)\)$/i); // allow:regex-no-length-cap — args length already capped upstream
1653
+ if (!match) {
1654
+ _writeTagged(socket, tag, "BAD STORE expects seq-set FLAGS (...)");
1655
+ return;
1656
+ }
1657
+ var seqSet = match[1];
1658
+ var op = match[2].toUpperCase();
1659
+ var flagsArr = match[3].split(/\s+/).filter(Boolean);
1660
+ var silent = /\.SILENT$/i.test(op);
1661
+ var mode = op[0] === "+" ? "add" : op[0] === "-" ? "remove" : "replace";
1662
+ // RFC 7162 §3.1.2 — UNCHANGEDSINCE in STORE engages CONDSTORE for
1663
+ // the session (same implicit-enable rule as FETCH CHANGEDSINCE).
1664
+ if (unchangedSince !== null && !state.enabledCondStore) {
1665
+ state.enabledCondStore = true;
1666
+ }
1667
+ var includeModseqStore = state.enabledCondStore === true || unchangedSince !== null;
1668
+ Promise.resolve()
1669
+ .then(function () {
1670
+ return mailStore.storeFlags(state.actor, state.selectedMailbox, seqSet, mode, flagsArr,
1671
+ { useUid: useUid === true, unchangedSince: unchangedSince, includeModseq: includeModseqStore });
1672
+ })
1673
+ .then(function (result) {
1674
+ // Backend may return either an array of rows (legacy shape)
1675
+ // OR an object `{ rows, modified }`. Normalise.
1676
+ var rs, modifiedSet;
1677
+ if (Array.isArray(result)) { rs = result; modifiedSet = null; }
1678
+ else if (result && typeof result === "object") {
1679
+ rs = result.rows || [];
1680
+ modifiedSet = result.modified || null;
1681
+ } else { rs = []; modifiedSet = null; }
1682
+ // RFC 7162 §3.1.3 — under CONDSTORE / UNCHANGEDSINCE, the
1683
+ // server MUST emit a FETCH response carrying the new MODSEQ
1684
+ // for every successfully-updated message EVEN UNDER .SILENT.
1685
+ // Without it, CONDSTORE clients cannot refresh their local
1686
+ // modseq state and drift out of sync. Under non-CONDSTORE
1687
+ // .SILENT, the legacy behaviour stays (no untagged FETCH).
1688
+ var emitFlags = !silent;
1689
+ var emitModseqOnly = silent && includeModseqStore;
1690
+ if (emitFlags || emitModseqOnly) {
1691
+ for (var i = 0; i < rs.length; i += 1) {
1692
+ var r = rs[i];
1693
+ var payload;
1694
+ if (emitFlags) {
1695
+ payload = "FLAGS (" + (r.flags || []).join(" ") + ")";
1696
+ if (includeModseqStore && r.modseq !== undefined) {
1697
+ payload = payload + " MODSEQ (" + r.modseq + ")";
1698
+ }
1699
+ } else if (r.modseq !== undefined) {
1700
+ // SILENT + CONDSTORE — emit MODSEQ alone (no FLAGS).
1701
+ payload = "MODSEQ (" + r.modseq + ")";
1702
+ } else {
1703
+ continue;
1704
+ }
1705
+ _writeUntagged(socket, r.seq + " FETCH (" + payload + ")");
1706
+ }
1707
+ }
1708
+ var okTag = "OK STORE completed";
1709
+ // RFC 7162 §3.1.3 — MODIFIED carries the set of ids the
1710
+ // conditional STORE refused to update because their modseq
1711
+ // advanced past unchangedSince. Clients re-issue FETCH against
1712
+ // the set to refresh state before retry.
1713
+ if (modifiedSet && String(modifiedSet).length > 0) {
1714
+ okTag = "OK [MODIFIED " + modifiedSet + "] STORE completed";
1715
+ }
1716
+ _writeTagged(socket, tag, okTag);
1717
+ })
1718
+ .catch(function (err) {
1719
+ _writeTagged(socket, tag, "NO " + ((err && err.message) || "Store failed").slice(0, ERR_CLAMP));
1720
+ });
1721
+ }
1722
+
1723
+ function _handleUid(state, socket, tag, args) {
1724
+ // UID FETCH / UID STORE / UID SEARCH / UID COPY / UID MOVE per
1725
+ // RFC 9051 §6.4.9. The sub-command's sequence-set is interpreted
1726
+ // as UIDs (not message-sequence-numbers); we pass `useUid: true`
1727
+ // to the sub-handler which threads it through to the backend's
1728
+ // mailStore.fetchRange / storeFlags via opts. Without this, the
1729
+ // backend treats the seq-set as msg-numbers and a client's
1730
+ // `UID FETCH 12345 (BODY[])` returns the WRONG message.
1731
+ var sub = args.match(/^(\S+)\s+(.+)$/); // allow:regex-no-length-cap — args length already capped upstream
1732
+ if (!sub) {
1733
+ _writeTagged(socket, tag, "BAD UID expects a sub-command");
1734
+ return;
1735
+ }
1736
+ var subVerb = sub[1].toUpperCase();
1737
+ var subArgs = sub[2];
1738
+ if (subVerb === "FETCH") return _handleFetch(state, socket, tag, subArgs, true);
1739
+ if (subVerb === "STORE") return _handleStore(state, socket, tag, subArgs, true);
1740
+ // RFC 9051 §6.4.9 also defines UID SEARCH / UID COPY / UID MOVE /
1741
+ // UID EXPUNGE; deferred from the initial listener slice.
1742
+ //
1743
+ // SEARCH: composes with the existing _handleSearch path; needs
1744
+ // the searchRange path threaded through `useUid: true`.
1745
+ // COPY: composes with the existing _handleCopy path; needs
1746
+ // the mailStore.copyRange opt accepted.
1747
+ // MOVE: RFC 6851; same shape as COPY plus an atomic-delete
1748
+ // step on the source mailbox.
1749
+ // EXPUNGE: RFC 4315 UIDPLUS; expunges by uid-set instead of by
1750
+ // \Deleted-flag scan.
1751
+ //
1752
+ // Re-open condition: operator surfaces a real IMAP client that
1753
+ // refuses to fall back to seq-number variants (most modern
1754
+ // clients — mutt / Thunderbird / Apple Mail / Outlook — already
1755
+ // use the seq-number forms when UID variants are unavailable).
1756
+ //
1757
+ // Operator escape hatch today: clients that issue these UID
1758
+ // sub-commands receive `BAD` and retry against the seq-number
1759
+ // variant (SEARCH / COPY / MOVE / EXPUNGE) which the listener
1760
+ // does serve.
1761
+ _writeTagged(socket, tag, "BAD UID " + subVerb +
1762
+ " is not yet implemented; client may retry with the seq-number form");
1763
+ }
1764
+
1765
+ function _handleIdle(state, socket, tag) {
1766
+ if (!_requireAuth(state, socket, tag)) return;
1767
+ _writeContinuation(socket, "idling");
1768
+ // RFC 2177 §3 — IDLE must be terminated with DONE before
1769
+ // bandwidth-timeout. We schedule a soft cutoff 1 min before the
1770
+ // hard 30-min cutoff to force client re-issue.
1771
+ var timer = setTimeout(function () {
1772
+ if (state.idle) {
1773
+ _writeUntagged(socket, "BYE IDLE timed out — re-issue");
1774
+ state.idle = null;
1775
+ _close(socket, state);
1776
+ }
1777
+ }, IDLE_BANDWIDTH_TIMEOUT_MS);
1778
+ state.idle = { tag: tag, timer: timer };
1779
+ }
1780
+
1781
+ function _writeTagged(socket, tag, msg) {
1782
+ try { socket.write(tag + " " + msg + "\r\n"); }
1783
+ catch (_e) { /* socket may be down */ }
1784
+ }
1785
+ function _writeUntagged(socket, msg) {
1786
+ try { socket.write("* " + msg + "\r\n"); }
1787
+ catch (_e) { /* socket may be down */ }
1788
+ }
1789
+ function _writeContinuation(socket, msg) {
1790
+ try { socket.write("+ " + msg + "\r\n"); }
1791
+ catch (_e) { /* socket may be down */ }
1792
+ }
1793
+ function _close(socket, state) {
1794
+ // The drain loop's `if (state.stage === "closed") return;` guard
1795
+ // (around the bottom of _drainBuffer) was dead before this —
1796
+ // _close never wrote the sentinel, so the drain loop kept
1797
+ // processing buffered bytes after the socket was destroyed.
1798
+ // Setting stage="closed" here makes the guard reachable so a
1799
+ // close mid-loop short-circuits the next command dispatch
1800
+ // (defense-in-depth against an exception thrown by a handler
1801
+ // that doesn't tear down the loop).
1802
+ if (state && typeof state === "object") state.stage = "closed";
1803
+ try { socket.end(); } catch (_e) { /* idempotent */ }
1804
+ try { socket.destroy(); } catch (_e2) { /* idempotent */ }
1805
+ connections.delete(socket);
1806
+ }
1807
+ function _quote(s) { return '"' + String(s).replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + '"'; }
1808
+ function _unquote(s) {
1809
+ if (typeof s !== "string") return "";
1810
+ if (s[0] === "\"" && s[s.length - 1] === "\"") return s.slice(1, -1);
1811
+ return s;
1812
+ }
1813
+
1814
+ // ---- Lifecycle ----------------------------------------------------------
1815
+ async function listen(listenOpts) {
1816
+ listenOpts = listenOpts || {};
1817
+ if (listening) {
1818
+ throw new MailServerImapError("mail-server-imap/already-listening",
1819
+ "listen: already listening");
1820
+ }
1821
+ var port = listenOpts.port === undefined ? 143 : listenOpts.port; // allow:raw-byte-literal — RFC 9051 IMAP port (IANA)
1822
+ var address = listenOpts.address || "0.0.0.0";
1823
+ tcpServer = net.createServer(function (socket) { _handleConnection(socket); });
1824
+ return new Promise(function (resolve, reject) {
1825
+ tcpServer.once("error", reject);
1826
+ tcpServer.listen(port, address, function () {
1827
+ listening = true;
1828
+ tcpServer.removeListener("error", reject);
1829
+ _emit("mail.server.imap.listening",
1830
+ { port: port, address: address });
1831
+ resolve({ port: tcpServer.address().port, address: address });
1832
+ });
1833
+ });
1834
+ }
1835
+
1836
+ async function close() {
1837
+ if (!listening) return;
1838
+ listening = false;
1839
+ for (var s of connections) { try { s.destroy(); } catch (_e) { /* idempotent */ } }
1840
+ connections.clear();
1841
+ return new Promise(function (resolve) {
1842
+ tcpServer.close(function () {
1843
+ _emit("mail.server.imap.closed", {});
1844
+ resolve();
1845
+ });
1846
+ });
1847
+ }
1848
+
1849
+ return {
1850
+ listen: listen,
1851
+ close: close,
1852
+ };
1853
+ }
1854
+
1855
+ module.exports = {
1856
+ create: create,
1857
+ MailServerImapError: MailServerImapError,
1858
+ };