@blamejs/blamejs-shop 0.4.56 → 0.4.58

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 (402) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/affiliates.js +35 -4
  3. package/lib/api-keys.js +17 -2
  4. package/lib/asset-manifest.json +1 -1
  5. package/lib/backorder.js +21 -4
  6. package/lib/click-and-collect.js +11 -2
  7. package/lib/credit-limits.js +132 -84
  8. package/lib/vendor/MANIFEST.json +426 -366
  9. package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
  10. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  11. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
  12. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
  13. package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
  14. package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
  15. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
  16. package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
  17. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
  18. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  19. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  20. package/lib/vendor/blamejs/api-snapshot.json +1381 -4
  21. package/lib/vendor/blamejs/eslint.config.mjs +1 -0
  22. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
  23. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
  24. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
  25. package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
  26. package/lib/vendor/blamejs/index.js +2 -0
  27. package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
  28. package/lib/vendor/blamejs/lib/acme.js +6 -5
  29. package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
  30. package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
  31. package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
  32. package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
  33. package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
  34. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
  35. package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
  36. package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
  37. package/lib/vendor/blamejs/lib/ai-input.js +2 -2
  38. package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
  39. package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
  40. package/lib/vendor/blamejs/lib/api-key.js +37 -28
  41. package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
  42. package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
  43. package/lib/vendor/blamejs/lib/archive-read.js +5 -17
  44. package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
  45. package/lib/vendor/blamejs/lib/archive.js +2 -10
  46. package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
  47. package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
  48. package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
  49. package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
  50. package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
  51. package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
  52. package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
  53. package/lib/vendor/blamejs/lib/audit.js +84 -0
  54. package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
  55. package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
  56. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
  57. package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
  58. package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
  59. package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
  60. package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
  61. package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
  62. package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
  63. package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
  64. package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
  65. package/lib/vendor/blamejs/lib/auth/password.js +7 -1
  66. package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
  67. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
  68. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
  69. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
  70. package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
  71. package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
  72. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
  73. package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
  74. package/lib/vendor/blamejs/lib/backup/index.js +14 -47
  75. package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
  76. package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
  77. package/lib/vendor/blamejs/lib/cache.js +7 -18
  78. package/lib/vendor/blamejs/lib/cbor.js +2 -1
  79. package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
  80. package/lib/vendor/blamejs/lib/cert.js +3 -10
  81. package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
  82. package/lib/vendor/blamejs/lib/cli.js +5 -1
  83. package/lib/vendor/blamejs/lib/client-hints.js +7 -9
  84. package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
  85. package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
  86. package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
  87. package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
  88. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
  89. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
  90. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
  91. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
  92. package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
  93. package/lib/vendor/blamejs/lib/compliance.js +2 -9
  94. package/lib/vendor/blamejs/lib/config-drift.js +2 -12
  95. package/lib/vendor/blamejs/lib/content-digest.js +10 -8
  96. package/lib/vendor/blamejs/lib/cookies.js +5 -11
  97. package/lib/vendor/blamejs/lib/cose.js +19 -11
  98. package/lib/vendor/blamejs/lib/cra-report.js +1 -11
  99. package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
  100. package/lib/vendor/blamejs/lib/crypto.js +120 -3
  101. package/lib/vendor/blamejs/lib/csp.js +235 -3
  102. package/lib/vendor/blamejs/lib/daemon.js +42 -41
  103. package/lib/vendor/blamejs/lib/data-act.js +19 -9
  104. package/lib/vendor/blamejs/lib/db-query.js +6 -40
  105. package/lib/vendor/blamejs/lib/db.js +34 -12
  106. package/lib/vendor/blamejs/lib/dbsc.js +5 -6
  107. package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
  108. package/lib/vendor/blamejs/lib/deprecate.js +4 -5
  109. package/lib/vendor/blamejs/lib/did.js +6 -2
  110. package/lib/vendor/blamejs/lib/dsr.js +8 -12
  111. package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
  112. package/lib/vendor/blamejs/lib/external-db.js +14 -26
  113. package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
  114. package/lib/vendor/blamejs/lib/fdx.js +22 -18
  115. package/lib/vendor/blamejs/lib/file-upload.js +80 -66
  116. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
  117. package/lib/vendor/blamejs/lib/framework-error.js +12 -0
  118. package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
  119. package/lib/vendor/blamejs/lib/fsm.js +7 -12
  120. package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
  121. package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
  122. package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
  123. package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
  124. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  125. package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
  126. package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
  127. package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
  128. package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
  129. package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
  130. package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
  131. package/lib/vendor/blamejs/lib/guard-email.js +46 -53
  132. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  133. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
  134. package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
  135. package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
  136. package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
  137. package/lib/vendor/blamejs/lib/guard-html.js +65 -117
  138. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
  139. package/lib/vendor/blamejs/lib/guard-image.js +280 -77
  140. package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
  141. package/lib/vendor/blamejs/lib/guard-json.js +87 -103
  142. package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
  143. package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
  144. package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
  145. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
  146. package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
  147. package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
  148. package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
  149. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
  150. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
  151. package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
  152. package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
  153. package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
  154. package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
  155. package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
  156. package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
  157. package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
  158. package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
  159. package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
  160. package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
  161. package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
  162. package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
  163. package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
  164. package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
  165. package/lib/vendor/blamejs/lib/guard-template.js +23 -80
  166. package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
  167. package/lib/vendor/blamejs/lib/guard-text.js +592 -0
  168. package/lib/vendor/blamejs/lib/guard-time.js +27 -95
  169. package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
  170. package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
  171. package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
  172. package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
  173. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
  174. package/lib/vendor/blamejs/lib/http-client.js +8 -21
  175. package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
  176. package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
  177. package/lib/vendor/blamejs/lib/i18n.js +83 -26
  178. package/lib/vendor/blamejs/lib/inbox.js +8 -8
  179. package/lib/vendor/blamejs/lib/incident-report.js +3 -21
  180. package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
  181. package/lib/vendor/blamejs/lib/jobs.js +3 -2
  182. package/lib/vendor/blamejs/lib/keychain.js +6 -18
  183. package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
  184. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
  185. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
  186. package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
  187. package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
  188. package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
  189. package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
  190. package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
  191. package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
  192. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  193. package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
  194. package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
  195. package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
  196. package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
  197. package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
  198. package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
  199. package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
  200. package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
  201. package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
  202. package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
  203. package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
  204. package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
  205. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
  206. package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
  207. package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
  208. package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
  209. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
  210. package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
  211. package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
  212. package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
  213. package/lib/vendor/blamejs/lib/mail-store.js +3 -2
  214. package/lib/vendor/blamejs/lib/mail.js +6 -11
  215. package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
  216. package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
  217. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
  218. package/lib/vendor/blamejs/lib/mcp.js +1 -1
  219. package/lib/vendor/blamejs/lib/mdoc.js +11 -12
  220. package/lib/vendor/blamejs/lib/metrics.js +32 -30
  221. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
  222. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
  223. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
  224. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  225. package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
  226. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
  227. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
  228. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
  229. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
  230. package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
  231. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
  232. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
  233. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
  234. package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
  235. package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
  236. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
  237. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
  238. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
  239. package/lib/vendor/blamejs/lib/migrations.js +4 -13
  240. package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
  241. package/lib/vendor/blamejs/lib/module-loader.js +44 -0
  242. package/lib/vendor/blamejs/lib/money.js +105 -0
  243. package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
  244. package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
  245. package/lib/vendor/blamejs/lib/network-dane.js +8 -6
  246. package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
  247. package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
  248. package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
  249. package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
  250. package/lib/vendor/blamejs/lib/network-tls.js +40 -42
  251. package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
  252. package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
  253. package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
  254. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
  255. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
  256. package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
  257. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
  258. package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
  259. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
  260. package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
  261. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
  262. package/lib/vendor/blamejs/lib/observability.js +95 -0
  263. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
  264. package/lib/vendor/blamejs/lib/otel-export.js +7 -10
  265. package/lib/vendor/blamejs/lib/outbox.js +43 -37
  266. package/lib/vendor/blamejs/lib/pagination.js +11 -15
  267. package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
  268. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
  269. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
  270. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
  271. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
  272. package/lib/vendor/blamejs/lib/pick.js +63 -5
  273. package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
  274. package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
  275. package/lib/vendor/blamejs/lib/problem-details.js +2 -5
  276. package/lib/vendor/blamejs/lib/pubsub.js +4 -8
  277. package/lib/vendor/blamejs/lib/redact.js +2 -1
  278. package/lib/vendor/blamejs/lib/render.js +4 -2
  279. package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
  280. package/lib/vendor/blamejs/lib/restore.js +5 -22
  281. package/lib/vendor/blamejs/lib/retention.js +3 -5
  282. package/lib/vendor/blamejs/lib/safe-async.js +457 -0
  283. package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
  284. package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
  285. package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
  286. package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
  287. package/lib/vendor/blamejs/lib/safe-json.js +7 -8
  288. package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
  289. package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
  290. package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
  291. package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
  292. package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
  293. package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
  294. package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
  295. package/lib/vendor/blamejs/lib/sandbox.js +3 -2
  296. package/lib/vendor/blamejs/lib/scheduler.js +5 -12
  297. package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
  298. package/lib/vendor/blamejs/lib/seeders.js +4 -11
  299. package/lib/vendor/blamejs/lib/self-update.js +92 -69
  300. package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
  301. package/lib/vendor/blamejs/lib/session.js +194 -6
  302. package/lib/vendor/blamejs/lib/sql.js +225 -78
  303. package/lib/vendor/blamejs/lib/sse.js +6 -10
  304. package/lib/vendor/blamejs/lib/static.js +136 -98
  305. package/lib/vendor/blamejs/lib/storage.js +4 -2
  306. package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
  307. package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
  308. package/lib/vendor/blamejs/lib/tsa.js +11 -15
  309. package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
  310. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
  311. package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
  312. package/lib/vendor/blamejs/lib/vc.js +2 -7
  313. package/lib/vendor/blamejs/lib/vex.js +35 -13
  314. package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
  315. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
  316. package/lib/vendor/blamejs/lib/webhook.js +43 -18
  317. package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
  318. package/lib/vendor/blamejs/lib/websocket.js +7 -3
  319. package/lib/vendor/blamejs/lib/worm.js +2 -3
  320. package/lib/vendor/blamejs/lib/ws-client.js +8 -10
  321. package/lib/vendor/blamejs/package.json +1 -1
  322. package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
  323. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
  324. package/lib/vendor/blamejs/test/00-primitives.js +136 -7
  325. package/lib/vendor/blamejs/test/10-state.js +9 -3
  326. package/lib/vendor/blamejs/test/30-chain.js +40 -0
  327. package/lib/vendor/blamejs/test/helpers/check.js +18 -0
  328. package/lib/vendor/blamejs/test/helpers/db.js +4 -0
  329. package/lib/vendor/blamejs/test/helpers/index.js +1 -0
  330. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
  331. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
  332. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
  333. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
  334. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
  335. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
  336. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
  337. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
  340. package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
  341. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
  342. package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
  344. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
  346. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
  347. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
  348. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
  349. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
  351. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
  352. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
  387. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
  388. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
  389. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
  390. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
  391. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
  392. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
  393. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
  395. package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
  396. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
  397. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
  398. package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
  399. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
  400. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
  401. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
  402. package/package.json +1 -1
@@ -11,6 +11,7 @@
11
11
  var helpers = require("../helpers");
12
12
  var b = helpers.b;
13
13
  var check = helpers.check;
14
+ var arcSign = require("../../lib/mail-arc-sign");
14
15
 
15
16
  function testSurface() {
16
17
  check("mail.spf.verify is a function", typeof b.mail.spf.verify === "function");
@@ -1376,8 +1377,46 @@ async function testSpfMechanismPtrRemainsDeferred() {
1376
1377
  rv.result === "permerror" && /5\.5/.test(rv.explanation || ""));
1377
1378
  }
1378
1379
 
1380
+ // ARC canon-source header parser — byte-exact golden lock. The AMS/AS
1381
+ // signatures are computed over the bytes this parser extracts; a sign->verify
1382
+ // round-trip shares the parser and so cannot catch a byte-error (it would only
1383
+ // surface as a rejection at a real ARC verifier). ARC's relaxed-canon parser
1384
+ // STRIPS leading WSP from the value (vs DKIM's simple-canon parser, which
1385
+ // preserves it) and PRESERVES the raw CRLF of a folded continuation.
1386
+ function testArcHeaderParserGolden() {
1387
+ var ph = arcSign._parseHeaderBlockForTest;
1388
+ function eq(label, raw, expected) {
1389
+ check("arc parser: " + label, JSON.stringify(ph(raw)) === JSON.stringify(expected));
1390
+ }
1391
+ eq("relaxed parser STRIPS leading WSP from value",
1392
+ "From: a@b.com",
1393
+ [{ name: "From", value: "a@b.com" }]);
1394
+ eq("leading SP + TAB stripped",
1395
+ "X: \tvalue",
1396
+ [{ name: "X", value: "value" }]);
1397
+ eq("folded continuation keeps raw CRLF + line",
1398
+ "From: a@b.com\r\nSubject: hello\r\n world",
1399
+ [{ name: "From", value: "a@b.com" },
1400
+ { name: "Subject", value: "hello\r\n world" }]);
1401
+ eq("exact name, order preserved across a colon-less line",
1402
+ "From: a@b.com\r\ngarbage\r\nTo: c@d.com",
1403
+ [{ name: "From", value: "a@b.com" },
1404
+ { name: "To", value: "c@d.com" }]);
1405
+ }
1406
+
1407
+ function testByteCapMultibyte() {
1408
+ // dmarc.parseForensicReport maxBytes is a BYTE cap; it returns an error
1409
+ // object (does not throw) on refusal.
1410
+ var report = String.fromCharCode(0x4e2d).repeat(20); // 60 UTF-8 bytes; cap 30
1411
+ var r = b.mail.dmarc.parseForensicReport(report, { maxBytes: 30 });
1412
+ check("dmarc-ruf byte-cap: multibyte report over byte cap rejected",
1413
+ r && r.ok === false && r.error && r.error.code === "mail-auth/dmarc-ruf-too-large");
1414
+ }
1415
+
1379
1416
  async function run() {
1417
+ testByteCapMultibyte();
1380
1418
  testSurface();
1419
+ testArcHeaderParserGolden();
1381
1420
  testSpfParse();
1382
1421
  testSpfBadRecord();
1383
1422
  await testSpfVerifyMockedDns();
@@ -90,6 +90,41 @@ function testDkimCanonicalization() {
90
90
  check("simple body: keeps interior WSP", sb("hello world\r\n") === "hello world\r\n");
91
91
  }
92
92
 
93
+ // ---- Header-block parser (the bytes the canonicalizers consume) ----
94
+ //
95
+ // The sign->verify round-trip CANNOT catch a parser byte-error: both sides run
96
+ // this same parser, so a wrong { name, value } extraction is self-consistent
97
+ // and the round-trip still passes — it would only surface as a signature
98
+ // rejection at a real external verifier (Gmail / opendkim) computing from the
99
+ // raw message. So pin the parser's byte-exact output directly. The two
100
+ // signature-critical invariants: the value PRESERVES its leading SP/WSP (simple
101
+ // canon signs those bytes verbatim), and a folded continuation PRESERVES the
102
+ // raw CRLF + continuation line (relaxed canon unfolds it itself; collapsing it
103
+ // in the parser would change the signed bytes).
104
+ function testDkimHeaderParserGolden() {
105
+ var ph = b.mail.dkim._parseHeadersForTest;
106
+ function eq(label, raw, expected) {
107
+ check("parser: " + label, JSON.stringify(ph(raw)) === JSON.stringify(expected));
108
+ }
109
+ eq("simple field preserves leading SP in value",
110
+ "From: a@b.com",
111
+ [{ name: "From", value: " a@b.com" }]);
112
+ eq("value preserves leading SP + TAB verbatim",
113
+ "X: \tvalue",
114
+ [{ name: "X", value: " \tvalue" }]);
115
+ eq("SP-folded continuation keeps raw CRLF + line",
116
+ "From: a@b.com\r\nSubject: hello\r\n world",
117
+ [{ name: "From", value: " a@b.com" },
118
+ { name: "Subject", value: " hello\r\n world" }]);
119
+ eq("TAB-folded continuation keeps raw CRLF + TAB line",
120
+ "Subject: a\r\n\tb",
121
+ [{ name: "Subject", value: " a\r\n\tb" }]);
122
+ eq("exact field name (no trim), order preserved across a colon-less line",
123
+ "From: a@b.com\r\ngarbage-no-colon\r\nTo: c@d.com",
124
+ [{ name: "From", value: " a@b.com" },
125
+ { name: "To", value: " c@d.com" }]);
126
+ }
127
+
93
128
  // ---- RSA-SHA256 sign + verify round-trip ----
94
129
 
95
130
  function _splitSignedRfc822(signed) {
@@ -594,6 +629,7 @@ function testDkimStripBTagValueAnchored() {
594
629
  async function run() {
595
630
  testDkimSurfaceAndValidation();
596
631
  testDkimCanonicalization();
632
+ testDkimHeaderParserGolden();
597
633
  testDkimRsaSignProducesHeader();
598
634
  testDkimEd25519Sign();
599
635
  testDkimSignerRejectsBadInput();
@@ -180,6 +180,22 @@ async function testGc() {
180
180
  check("gc removed at least 1", r.removed >= 1);
181
181
  }
182
182
 
183
+ async function testMaxEntriesEvictsOldest() {
184
+ // The in-memory backend caps entry count via boundedMap (evict-oldest). At
185
+ // maxEntries=2, recording a 3rd distinct triplet evicts the 1st — so the 1st
186
+ // is first-seen again on re-check rather than retry-too-soon. Distinct /24
187
+ // subnets so the triplets don't CIDR-aggregate into one fingerprint.
188
+ var gl = b.mail.greylist.create({ maxEntries: 2 });
189
+ await gl.check(_ctx({ ip: "198.51.100.1" })); // entry 1
190
+ await gl.check(_ctx({ ip: "203.0.113.1" })); // entry 2 — at cap
191
+ await gl.check(_ctx({ ip: "192.0.2.1" })); // entry 3 — evicts entry 1
192
+ var v = await gl.check(_ctx({ ip: "198.51.100.1" }));
193
+ check("maxEntries: oldest triplet evicted → first-seen again", v.reason === "first-seen");
194
+ // Entry 3 (most recent) is still present → retry-too-soon, not evicted.
195
+ var v3 = await gl.check(_ctx({ ip: "192.0.2.1" }));
196
+ check("maxEntries: newest triplet retained", v3.reason === "retry-too-soon");
197
+ }
198
+
183
199
  async function testFingerprintHashStable() {
184
200
  var fp1 = b.mail.greylist._hashFingerprint("203.0.113.0/24", "a@b.com", "c@d.com");
185
201
  var fp2 = b.mail.greylist._hashFingerprint("203.0.113.0/24", "a@b.com", "c@d.com");
@@ -206,6 +222,7 @@ async function run() {
206
222
  await testCompliancePosture();
207
223
  await testProfileResolution();
208
224
  await testGc();
225
+ await testMaxEntriesEvictsOldest();
209
226
  await testFingerprintHashStable();
210
227
  }
211
228
 
@@ -28,6 +28,45 @@ async function run() {
28
28
  var modSurface = b.mail.server.tls;
29
29
  check("surface: context is fn", typeof modSurface.context === "function");
30
30
  check("surface: MailServerTlsError class", typeof modSurface.MailServerTlsError === "function");
31
+ check("surface: upgradeSocket is fn", typeof modSurface.upgradeSocket === "function");
32
+ check("surface: upgradeLineProtocol is fn", typeof modSurface.upgradeLineProtocol === "function");
33
+
34
+ // ---- upgradeLineProtocol: config-time validation (§8 entry-point) ----
35
+ var ulpBad = [];
36
+ try { modSurface.upgradeLineProtocol(); } catch (e) { ulpBad.push(e); }
37
+ try { modSurface.upgradeLineProtocol({}); } catch (e) { ulpBad.push(e); }
38
+ try { modSurface.upgradeLineProtocol({ state: {} }); } catch (e) { ulpBad.push(e); }
39
+ check("upgradeLineProtocol throws on missing opts", ulpBad[0] && /opts required/.test(ulpBad[0].message));
40
+ check("upgradeLineProtocol throws on missing state", ulpBad[1] && /state/.test(ulpBad[1].message));
41
+ check("upgradeLineProtocol throws on missing drain", ulpBad[2] && /drain/.test(ulpBad[2].message));
42
+
43
+ // ---- upgradeLineProtocol: the STARTTLS-injection drain runs BEFORE the
44
+ // upgrade (CVE-2021-33515 / CVE-2021-38371). With a non-socket the inner
45
+ // upgradeSocket throws, but the pre-handshake state MUST already be wiped.
46
+ var injState = {
47
+ lineBuffer: Buffer.from("A001 LOGIN pipelined-pre-handshake\r\n"),
48
+ pendingLiteral: { bytes: 42 },
49
+ authPending: "half-sasl-token",
50
+ tls: false,
51
+ };
52
+ var injThrew = null;
53
+ try {
54
+ modSurface.upgradeLineProtocol({
55
+ state: injState,
56
+ socket: {}, // not a net.Socket → inner upgradeSocket throws
57
+ secureContext: {},
58
+ idleTimeoutMs: 1000,
59
+ clearFields: ["pendingLiteral", "authPending"],
60
+ drain: function () {},
61
+ onError: function () {},
62
+ });
63
+ } catch (e) { injThrew = e; }
64
+ check("upgradeLineProtocol rejects a non-socket (via upgradeSocket)",
65
+ injThrew && /plainSocket/.test(injThrew.message));
66
+ check("injection drain: lineBuffer emptied even when the upgrade fails",
67
+ injState.lineBuffer.length === 0);
68
+ check("injection drain: clearFields[0] (pendingLiteral) nulled", injState.pendingLiteral === null);
69
+ check("injection drain: clearFields[1] (authPending) nulled", injState.authPending === null);
31
70
 
32
71
  // ---- happy path: plain PEM files load + return a SecureContext ----
33
72
  var tmp1 = _mkTmpDir("happy");
@@ -371,7 +371,24 @@ async function testRefusesBadBackend() {
371
371
  threw && (threw.code || "").indexOf("mail-store/bad-backend") !== -1);
372
372
  }
373
373
 
374
+ async function testByteCapMultibyte() {
375
+ // maxBodyBytes is a BYTE cap on the decoded body text. A multibyte body
376
+ // under the char count but over the byte cap must be refused.
377
+ var fx = await _setupStore("bytecap");
378
+ try {
379
+ var store = b.mailStore.create({ backend: fx.db, maxBodyBytes: 30 });
380
+ var mb = String.fromCharCode(0x4e2d).repeat(15); // 15 chars / 45 UTF-8 bytes; cap 30
381
+ var msg = _msg(["From: a@example.com", "To: b@example.com", "Subject: x",
382
+ "Date: Wed, 14 May 2026 12:00:00 +0000", "Content-Type: text/plain; charset=utf-8"], mb);
383
+ var threw = null;
384
+ try { store.appendMessage("INBOX", msg); } catch (e) { threw = e; }
385
+ check("mailStore byte-cap: multibyte body over byte cap refused",
386
+ threw && threw.code === "mail-store/oversize-body");
387
+ } finally { _teardown(fx); }
388
+ }
389
+
374
390
  async function run() {
391
+ await testByteCapMultibyte();
375
392
  testSurface();
376
393
  await testBootstrap();
377
394
  await testAppendFetchRoundtrip();
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ /**
3
+ * mime-parse — RFC 5322 / 2045 header-block + MIME structure parsing shared by
4
+ * the mail stack (email, dsn, arf, auth, bounce). Covers the header-block
5
+ * classifier (fields / malformed / folding / header-body boundary), the
6
+ * parseHeaderBlock fields view, header/body bisection, Content-Type parsing,
7
+ * case-insensitive header lookup, and multipart partitioning.
8
+ *
9
+ * classifyHeaderBlock.malformed is the header-injection signal (a header-section
10
+ * line that is neither a `name: value` field nor a folding continuation) that
11
+ * the silent-skip parsers used to drop; guard-email consumes it.
12
+ */
13
+
14
+ var helpers = require("../helpers");
15
+ var check = helpers.check;
16
+ var mp = require("../../lib/mime-parse");
17
+
18
+ function _eq(label, actual, expected) {
19
+ check(label, JSON.stringify(actual) === JSON.stringify(expected));
20
+ }
21
+
22
+ function testClassifyHeaderBlockFields() {
23
+ var r = mp.classifyHeaderBlock("A: 1\r\nB: 2\r\n boldfold\r\n\r\nbody");
24
+ _eq("classify: fields parsed, folding collapsed to single SP",
25
+ r.fields, [{ name: "A", value: "1" }, { name: "B", value: "2 boldfold" }]);
26
+ check("classify: clean block has no malformed lines", r.malformed.length === 0);
27
+ }
28
+
29
+ function testClassifyHeaderBlockMalformed() {
30
+ var r = mp.classifyHeaderBlock("garbage\r\nTo: x@y.com");
31
+ _eq("classify: a colon-less header-section line is malformed (injection signal)",
32
+ r.malformed, [{ lineIndex: 0, line: "garbage", reason: "no-colon" }]);
33
+ _eq("classify: the valid field after it still parses",
34
+ r.fields, [{ name: "To", value: "x@y.com" }]);
35
+ }
36
+
37
+ function testClassifyHeaderBlockBoundary() {
38
+ // A non-field line AFTER the blank header/body boundary is BODY — not flagged.
39
+ var r = mp.classifyHeaderBlock("A: 1\r\n\r\nnot-a-header-line");
40
+ check("classify: boundary-aware — body lines are not malformed", r.malformed.length === 0);
41
+ _eq("classify: only the header section is parsed into fields",
42
+ r.fields, [{ name: "A", value: "1" }]);
43
+ }
44
+
45
+ function testClassifyHeaderBlockBadInput() {
46
+ check("classify: null → empty structure", mp.classifyHeaderBlock(null).fields.length === 0);
47
+ check("classify: undefined → empty structure", mp.classifyHeaderBlock(undefined).malformed.length === 0);
48
+ }
49
+
50
+ function testParseHeaderBlockIsFieldsView() {
51
+ _eq("parseHeaderBlock returns the classifier's fields",
52
+ mp.parseHeaderBlock("From: a\r\nTo: b"),
53
+ [{ name: "From", value: "a" }, { name: "To", value: "b" }]);
54
+ // Equivalence with classifyHeaderBlock.fields on the same input.
55
+ var raw = "Subject: hi\r\n there\r\nFrom: a@b.com";
56
+ _eq("parseHeaderBlock === classifyHeaderBlock(x).fields",
57
+ mp.parseHeaderBlock(raw), mp.classifyHeaderBlock(raw).fields);
58
+ }
59
+
60
+ function testSplitHeadersAndBody() {
61
+ var s = mp.splitHeadersAndBody("H: v\r\n\r\nthe body\r\nline2");
62
+ _eq("split: header section parsed", s.headers, [{ name: "H", value: "v" }]);
63
+ check("split: body preserved verbatim after the blank line", s.body === "the body\r\nline2");
64
+ var none = mp.splitHeadersAndBody("H: v\r\nI: w");
65
+ check("split: no blank line → empty body", none.body === "");
66
+ }
67
+
68
+ function testParseContentType() {
69
+ var ct = mp.parseContentType("text/html; charset=utf-8; boundary=xyz");
70
+ check("parseContentType: type lowercased", ct.type === "text/html");
71
+ check("parseContentType: charset param", ct.params.charset === "utf-8");
72
+ check("parseContentType: boundary param", ct.params.boundary === "xyz");
73
+ }
74
+
75
+ function testFindHeader() {
76
+ var hs = [{ name: "From", value: "a" }, { name: "to", value: "b" }];
77
+ check("findHeader: case-insensitive match", mp.findHeader(hs, "TO") === "b");
78
+ check("findHeader: missing → null/undefined", !mp.findHeader(hs, "Subject"));
79
+ }
80
+
81
+ function testSplitMimeParts() {
82
+ _eq("splitMimeParts: partitions on --boundary, drops preamble + close",
83
+ mp.splitMimeParts("preamble\r\n--bnd\r\npart1\r\n--bnd\r\npart2\r\n--bnd--\r\n", "bnd"),
84
+ ["part1", "part2"]);
85
+ _eq("splitMimeParts: empty boundary → no parts",
86
+ mp.splitMimeParts("anything", ""), []);
87
+ }
88
+
89
+ function run() {
90
+ testClassifyHeaderBlockFields();
91
+ testClassifyHeaderBlockMalformed();
92
+ testClassifyHeaderBlockBoundary();
93
+ testClassifyHeaderBlockBadInput();
94
+ testParseHeaderBlockIsFieldsView();
95
+ testSplitHeadersAndBody();
96
+ testParseContentType();
97
+ testFindHeader();
98
+ testSplitMimeParts();
99
+ }
100
+
101
+ module.exports = { run: run };
102
+
103
+ if (require.main === module) {
104
+ try { run(); console.log("[mime-parse] OK — " + helpers.getChecks() + " checks passed"); }
105
+ catch (e) { console.error("FAIL:", e.stack || e); process.exit(1); }
106
+ }
@@ -20,7 +20,24 @@ function run() {
20
20
  check("b.money.convert function", typeof b.money.convert === "function");
21
21
  check("b.money.CURRENCIES exposed", typeof b.money.CURRENCIES === "object");
22
22
  check("b.money.MoneyError exposed", typeof b.money.MoneyError === "function");
23
+ check("b.money.roundMinor function", typeof b.money.roundMinor === "function");
23
24
  check("b.money.Money class exposed", typeof b.money.Money === "function");
25
+
26
+ // ---- roundMinor: cash-rounding to an increment (BigInt minor units) ----
27
+ check("roundMinor: CHF 12.32 → nearest 0.05 (half-even)", b.money.roundMinor(1232n, 5n) === 1230n);
28
+ check("roundMinor: tie → half-even picks even multiple", b.money.roundMinor(25n, 10n, "half-even") === 20n);
29
+ check("roundMinor: tie → half-up away from zero", b.money.roundMinor(25n, 10n, "half-up") === 30n);
30
+ check("roundMinor: negative tie → half-up away from zero", b.money.roundMinor(-25n, 10n, "half-up") === -30n);
31
+ check("roundMinor: floor toward -inf", b.money.roundMinor(27n, 10n, "floor") === 20n);
32
+ check("roundMinor: ceiling toward +inf", b.money.roundMinor(21n, 10n, "ceiling") === 30n);
33
+ check("roundMinor: exact multiple returns unchanged", b.money.roundMinor(30n, 10n) === 30n);
34
+ check("roundMinor: safe-integer Number coerced to BigInt", b.money.roundMinor(25, 10n, "half-up") === 30n);
35
+ check("roundMinor: bad mode throws money/bad-rounding-mode",
36
+ (function () { try { b.money.roundMinor(10n, 5n, "nope"); return null; } catch (e) { return e.code; } })()
37
+ === "money/bad-rounding-mode");
38
+ check("roundMinor: non-integer minor throws money/bad-minor-units",
39
+ (function () { try { b.money.roundMinor(1.5, 5n); return null; } catch (e) { return e.code; } })()
40
+ === "money/bad-minor-units");
24
41
  check("b.money.Money is the prototype", b.money.of("1.00", "USD") instanceof b.money.Money);
25
42
  check("CURRENCIES is frozen", Object.isFrozen(b.money.CURRENCIES));
26
43
  check("CURRENCIES.USD exponent", b.money.CURRENCIES.USD === 2);
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ /**
3
+ * b.mtlsCa revocation + issuance identity (#322).
4
+ *
5
+ * The require-mtls gate denies by SHA3-512 fingerprint, but revocation used to
6
+ * be keyed only by serial, the registry could only be a plaintext file, and
7
+ * issuance discarded the serial + fingerprint. This proves the three additive
8
+ * fixes: fingerprint-addressable revoke()/isRevoked(), a bring-your-own
9
+ * revocation store, and serial+fingerprint surfaced from issuance.
10
+ */
11
+
12
+ var helpers = require("../helpers");
13
+ var b = helpers.b;
14
+ var check = helpers.check;
15
+ var fs = require("fs");
16
+ var os = require("os");
17
+ var path = require("path");
18
+
19
+ async function run() {
20
+ var dir = fs.mkdtempSync(path.join(os.tmpdir(), "blamejs-mtls-revoke-"));
21
+ var ca = b.mtlsCa.create({ dataDir: dir, caKeySealedMode: "disabled", generation: 1 });
22
+
23
+ // ---- #322 part 3: issuance surfaces serial + fingerprint ----
24
+ var issued = await ca.generateClientCert({ cn: "client-1" });
25
+ check("issuance surfaces a hex serialNumber",
26
+ typeof issued.serialNumber === "string" && /^[0-9a-f]+$/.test(issued.serialNumber));
27
+ check("issuance surfaces a 128-hex SHA3-512 fingerprint",
28
+ typeof issued.fingerprint === "string" && issued.fingerprint.length === 128);
29
+ check("the surfaced fingerprint equals the gate's b.crypto.sha3Hash(cert)",
30
+ issued.fingerprint === b.crypto.sha3Hash(issued.cert));
31
+
32
+ // ---- #322 part 1: revoke + isRevoked by serial (backward-compat) ----
33
+ ca.revoke(issued.serialNumber, { reason: "superseded" });
34
+ check("revoke(serial) then isRevoked(serial) is true", ca.isRevoked(issued.serialNumber) === true);
35
+ check("a serial that was never revoked reads false", ca.isRevoked("00ff") === false);
36
+ var first = ca.revoke(issued.serialNumber);
37
+ var again = ca.revoke(issued.serialNumber);
38
+ check("revoke is idempotent (revokedAt unchanged)", first.revokedAt === again.revokedAt);
39
+
40
+ // ---- #322 part 1: revoke + isRevoked by fingerprint (the gate's key) ----
41
+ var issued2 = await ca.generateClientCert({ cn: "client-2" });
42
+ ca.revoke({ fingerprint: issued2.fingerprint, reason: "keyCompromise" });
43
+ check("revoke({fingerprint}) then isRevoked(fingerprint) is true",
44
+ ca.isRevoked(issued2.fingerprint) === true);
45
+ check("isRevoked tolerates separator/case formatting",
46
+ ca.isRevoked(issued2.fingerprint.toUpperCase()) === true);
47
+
48
+ var threwNoKey = false;
49
+ try { ca.revoke({ reason: "x" }); } catch (e) { threwNoKey = /no-revocation-key/.test(e.code || ""); }
50
+ check("revoke with neither serial nor fingerprint throws", threwNoKey);
51
+
52
+ // ---- #322 part 2: bring-your-own revocation store ----
53
+ var rows = [];
54
+ var store = { list: function () { return rows.slice(); }, add: function (e) { rows.push(e); } };
55
+ var dir2 = fs.mkdtempSync(path.join(os.tmpdir(), "blamejs-mtls-byostore-"));
56
+ var ca2 = b.mtlsCa.create({ dataDir: dir2, caKeySealedMode: "disabled", revocationStore: store });
57
+ ca2.revoke("AB:CD:EF", { reason: "cessationOfOperation" });
58
+ check("BYO store: revoke writes through the operator store (normalized serial)",
59
+ rows.length === 1 && rows[0].serialNumber === "abcdef");
60
+ check("BYO store: isRevoked reads through the operator store", ca2.isRevoked("abcdef") === true);
61
+ check("BYO store: the default revocations.json was not written",
62
+ !fs.existsSync(path.join(dir2, "revocations.json")));
63
+
64
+ var threwBadStore = false;
65
+ try {
66
+ b.mtlsCa.create({ dataDir: dir2, caKeySealedMode: "disabled", revocationStore: { list: 1 } });
67
+ } catch (e) { threwBadStore = /bad-revocation-store/.test(e.code || ""); }
68
+ check("a revocationStore missing list()/add() is refused at create()", threwBadStore);
69
+
70
+ // ---- #322 part 3: a custom engine may return a non-X.509 cert shape ----
71
+ // The serial comes from an X.509 parse (best-effort); the fingerprint is a
72
+ // hash of the returned bytes (always available). Optional identity
73
+ // enrichment must never crash issuance.
74
+ var dir3 = fs.mkdtempSync(path.join(os.tmpdir(), "blamejs-mtls-stub-"));
75
+ var stubEngine = {
76
+ generateCa: async function () {
77
+ return { caCertPem: "ENGINE-CA", caKeyPem: "ENGINE-KEY", generation: 1 };
78
+ },
79
+ signClientCert: async function (a) {
80
+ return { cert: "-----BEGIN CERTIFICATE-----\nNOT-X509-" + a.cn + "\n-----END CERTIFICATE-----\n", key: "k" };
81
+ },
82
+ };
83
+ var ca3 = b.mtlsCa.create({ dataDir: dir3, engine: stubEngine, caKeySealedMode: "disabled" });
84
+ var stub = await ca3.generateClientCert({ cn: "stub-client" });
85
+ check("non-X.509 engine cert does not crash issuance", typeof stub.cert === "string");
86
+ check("unparseable cert yields serialNumber null (best-effort)", stub.serialNumber === null);
87
+ check("fingerprint is still surfaced for a non-X.509 cert", stub.fingerprint === b.crypto.sha3Hash(stub.cert));
88
+ ca3.revoke({ fingerprint: stub.fingerprint });
89
+ check("a non-X.509 cert is still revocable by fingerprint", ca3.isRevoked(stub.fingerprint) === true);
90
+
91
+ try {
92
+ fs.rmSync(dir, { recursive: true, force: true });
93
+ fs.rmSync(dir2, { recursive: true, force: true });
94
+ fs.rmSync(dir3, { recursive: true, force: true });
95
+ } catch (_e) { /* best-effort */ }
96
+ }
97
+
98
+ module.exports = { run: run };
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * b.nonceStore.release(nonce) — the rollback half of reserve -> commit ->
4
+ * rollback (#325).
5
+ *
6
+ * An eager checkAndInsert claim with no un-claim inverts the at-least-once
7
+ * contract: when downstream processing fails and the provider redelivers, the
8
+ * already-claimed id reads as a replay and the event is dropped. release()
9
+ * un-claims so the redelivery is reprocessed. The cluster backend's release
10
+ * (DELETE by nonce hash) is exercised in the live-integration suite; here we
11
+ * cover the memory + custom backends.
12
+ */
13
+
14
+ var helpers = require("../helpers");
15
+ var b = helpers.b;
16
+ var check = helpers.check;
17
+
18
+ async function run() {
19
+ var exp = Date.now() + 60000;
20
+
21
+ // ---- memory backend: reserve -> replay -> release -> re-reserve ----
22
+ var s = b.nonceStore.create({ backend: "memory" });
23
+ check("#325 first claim wins (reserve)", (await s.checkAndInsert("evt-1", exp)) === true);
24
+ check("#325 a concurrent duplicate reads as replay", (await s.checkAndInsert("evt-1", exp)) === false);
25
+ check("#325 release un-claims a live nonce (returns true)", (await s.release("evt-1")) === true);
26
+ check("#325 a redelivery after release is reprocessed (re-claim wins)",
27
+ (await s.checkAndInsert("evt-1", exp)) === true);
28
+ check("#325 commit path: WITHOUT release the duplicate stays suppressed",
29
+ (await s.checkAndInsert("evt-1", exp)) === false);
30
+ check("#325 release of a never-claimed nonce returns false", (await s.release("never-seen")) === false);
31
+
32
+ var threwBad = false;
33
+ try { await s.release(""); } catch (e) { threwBad = /INVALID_NONCE/.test(e.code || ""); }
34
+ check("#325 release rejects an empty nonce", threwBad);
35
+ s.close();
36
+
37
+ // ---- custom backend: release forwarded when present, loud when absent ----
38
+ var forwarded = null;
39
+ var withRelease = b.nonceStore.create({ backend: {
40
+ checkAndInsert: function () { return Promise.resolve(true); },
41
+ release: function (n) { forwarded = n; return Promise.resolve(true); },
42
+ } });
43
+ await withRelease.release("evt-Z");
44
+ check("#325 a custom backend's release() is forwarded", forwarded === "evt-Z");
45
+
46
+ var withoutRelease = b.nonceStore.create({ backend: {
47
+ checkAndInsert: function () { return Promise.resolve(true); },
48
+ } });
49
+ var threwNoRel = false;
50
+ try { await withoutRelease.release("x"); } catch (e) { threwNoRel = /BACKEND_NO_RELEASE/.test(e.code || ""); }
51
+ check("#325 a custom backend without release() fails loudly (no silent dropped rollback)", threwNoRel);
52
+
53
+ // ---- enforceReplay: first use passes; replay refused; store-throw fails closed ----
54
+ function RErr(code, message) { this.code = code; this.message = message; }
55
+ var ropts = { errorClass: RErr, storeFailedCode: "x/store-failed", replayCode: "x/replay", tokenLabel: "token" };
56
+ var rs = b.nonceStore.create({ backend: "memory" });
57
+ await b.nonceStore.enforceReplay(rs, "jti-A", exp, ropts);
58
+ check("enforceReplay: first use of a jti passes (no throw)", true);
59
+ var replayErr = null;
60
+ try { await b.nonceStore.enforceReplay(rs, "jti-A", exp, ropts); } catch (e) { replayErr = e; }
61
+ check("enforceReplay: a re-used jti is refused with the replay code + message",
62
+ replayErr instanceof RErr && replayErr.code === "x/replay" &&
63
+ replayErr.message === "token jti='jti-A' has been seen before — replay refused");
64
+ rs.close();
65
+
66
+ // A store failure must fail CLOSED (store-failed error), never silently pass.
67
+ var failStore = b.nonceStore.create({ backend: {
68
+ checkAndInsert: function () { return Promise.reject(new Error("db down")); },
69
+ } });
70
+ var storeErr = null;
71
+ try { await b.nonceStore.enforceReplay(failStore, "jti-B", exp, ropts); } catch (e) { storeErr = e; }
72
+ check("enforceReplay: a store failure fails closed (store-failed code, not a pass)",
73
+ storeErr instanceof RErr && storeErr.code === "x/store-failed" &&
74
+ storeErr.message.indexOf("replayStore.checkAndInsert threw: db down") === 0);
75
+ }
76
+
77
+ module.exports = { run: run };
@@ -201,6 +201,52 @@ function testObservabilitySemconvK8sAttributes() {
201
201
  check("SEMCONV.K8S_REPLICASET_NAME", S.K8S_REPLICASET_NAME === "k8s.replicaset.name");
202
202
  }
203
203
 
204
+ // b.observability.namespaced — the drop-silent prefixed metric emitter every
205
+ // primitive used to hand-roll as a private _emitMetric closure.
206
+ function testObservabilityNamespaced() {
207
+ check("b.observability.namespaced is a function",
208
+ typeof b.observability.namespaced === "function");
209
+ var seen = [];
210
+ var orig = b.observability.safeEvent; // late-bound — the stub is observed
211
+ b.observability.safeEvent = function (name, n, labels) {
212
+ seen.push({ name: name, n: n, labels: labels });
213
+ };
214
+ try {
215
+ var emit = b.observability.namespaced("network.byte_quota");
216
+ emit("exceeded", 5, { key: "k" });
217
+ emit("reset"); // value → 1, labels → {}
218
+ var gated = b.observability.namespaced("middleware.tusUpload", false);
219
+ gated("create.ok"); // gateFlag false → no-op
220
+ } finally {
221
+ b.observability.safeEvent = orig;
222
+ }
223
+ check("namespaced prefixes the name + passes value/labels through",
224
+ seen[0].name === "network.byte_quota.exceeded" && seen[0].n === 5 && seen[0].labels.key === "k");
225
+ check("namespaced defaults value to 1 and labels to {}",
226
+ seen[1].name === "network.byte_quota.reset" && seen[1].n === 1 &&
227
+ JSON.stringify(seen[1].labels) === "{}");
228
+ check("namespaced(prefix, false) is a no-op",
229
+ !seen.some(function (e) { return e.name === "middleware.tusUpload.create.ok"; }));
230
+ }
231
+
232
+ // b.observability.makeCounterEmitter — the per-instance counter sibling of
233
+ // namespaced, every primitive used to hand-roll as a private _emitObs closure.
234
+ function testObservabilityMakeCounterEmitter() {
235
+ check("b.observability.makeCounterEmitter is a function",
236
+ typeof b.observability.makeCounterEmitter === "function");
237
+ var sinkSeen = [];
238
+ var sink = { event: function (name, value, labels) { sinkSeen.push({ name: name, value: value, labels: labels }); } };
239
+ var emit = b.observability.makeCounterEmitter(sink);
240
+ emit("auth.lockout.tripped", { actor: "alice" });
241
+ check("makeCounterEmitter emits value 1 + name + labels to the sink",
242
+ sinkSeen.length === 1 && sinkSeen[0].name === "auth.lockout.tripped" &&
243
+ sinkSeen[0].value === 1 && sinkSeen[0].labels.actor === "alice");
244
+ var threw = false;
245
+ try { b.observability.makeCounterEmitter({ event: function () { throw new Error("sink down"); } })("x"); }
246
+ catch (_e) { threw = true; }
247
+ check("makeCounterEmitter is drop-silent on a sink throw", threw === false);
248
+ }
249
+
204
250
  async function run() {
205
251
  testObservabilitySurface();
206
252
  testObservabilityTapRunsFnWithoutRegistries();
@@ -217,6 +263,8 @@ async function run() {
217
263
  testObservabilityEventDropsBadName();
218
264
  testObservabilitySemconvResourceAttributes();
219
265
  testObservabilitySemconvK8sAttributes();
266
+ testObservabilityNamespaced();
267
+ testObservabilityMakeCounterEmitter();
220
268
  }
221
269
 
222
270
  module.exports = { run: run };