@blamejs/blamejs-shop 0.4.69 → 0.4.71

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 (299) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/admin.js +8 -6
  3. package/lib/asset-manifest.json +1 -1
  4. package/lib/security-middleware.js +65 -23
  5. package/lib/shipping-insurance.js +29 -4
  6. package/lib/sms-dispatcher.js +17 -4
  7. package/lib/storefront.js +10 -7
  8. package/lib/vendor/MANIFEST.json +319 -267
  9. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  10. package/lib/vendor/blamejs/api-snapshot.json +58 -5
  11. package/lib/vendor/blamejs/examples/wiki/README.md +1 -1
  12. package/lib/vendor/blamejs/examples/wiki/docker-compose.prod.yml +9 -8
  13. package/lib/vendor/blamejs/examples/wiki/docker-compose.yml +10 -9
  14. package/lib/vendor/blamejs/examples/wiki/env-snapshot.json +4 -3
  15. package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +33 -17
  16. package/lib/vendor/blamejs/examples/wiki/routes/admin.js +7 -10
  17. package/lib/vendor/blamejs/examples/wiki/server.js +5 -4
  18. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +5 -0
  19. package/lib/vendor/blamejs/lib/a2a-tasks.js +38 -6
  20. package/lib/vendor/blamejs/lib/agent-event-bus.js +13 -0
  21. package/lib/vendor/blamejs/lib/agent-idempotency.js +5 -1
  22. package/lib/vendor/blamejs/lib/agent-snapshot.js +32 -2
  23. package/lib/vendor/blamejs/lib/ai-aedt-bias-audit.js +2 -1
  24. package/lib/vendor/blamejs/lib/ai-content-detect.js +1 -3
  25. package/lib/vendor/blamejs/lib/ai-frontier-protocol.js +1 -1
  26. package/lib/vendor/blamejs/lib/ai-model-manifest.js +1 -1
  27. package/lib/vendor/blamejs/lib/ai-output.js +16 -7
  28. package/lib/vendor/blamejs/lib/api-snapshot.js +4 -1
  29. package/lib/vendor/blamejs/lib/app-shutdown.js +7 -1
  30. package/lib/vendor/blamejs/lib/archive-gz.js +9 -0
  31. package/lib/vendor/blamejs/lib/archive-read.js +9 -7
  32. package/lib/vendor/blamejs/lib/archive-tar-read.js +51 -8
  33. package/lib/vendor/blamejs/lib/archive.js +4 -2
  34. package/lib/vendor/blamejs/lib/asn1-der.js +70 -22
  35. package/lib/vendor/blamejs/lib/atomic-file.js +204 -2
  36. package/lib/vendor/blamejs/lib/audit-chain.js +54 -5
  37. package/lib/vendor/blamejs/lib/audit-daily-review.js +12 -2
  38. package/lib/vendor/blamejs/lib/audit-sign.js +2 -1
  39. package/lib/vendor/blamejs/lib/audit-tools.js +108 -23
  40. package/lib/vendor/blamejs/lib/audit.js +7 -2
  41. package/lib/vendor/blamejs/lib/auth/access-lock.js +2 -2
  42. package/lib/vendor/blamejs/lib/auth/bot-challenge.js +1 -1
  43. package/lib/vendor/blamejs/lib/auth/ciba.js +43 -4
  44. package/lib/vendor/blamejs/lib/auth/dpop.js +6 -1
  45. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +5 -1
  46. package/lib/vendor/blamejs/lib/auth/jwt.js +2 -2
  47. package/lib/vendor/blamejs/lib/auth/lockout.js +18 -2
  48. package/lib/vendor/blamejs/lib/auth/passkey.js +1 -1
  49. package/lib/vendor/blamejs/lib/auth/password.js +1 -1
  50. package/lib/vendor/blamejs/lib/auth/saml.js +33 -13
  51. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +24 -4
  52. package/lib/vendor/blamejs/lib/auth/status-list.js +14 -2
  53. package/lib/vendor/blamejs/lib/auth/step-up.js +9 -1
  54. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +21 -2
  55. package/lib/vendor/blamejs/lib/backup/bundle.js +7 -2
  56. package/lib/vendor/blamejs/lib/backup/crypto.js +23 -8
  57. package/lib/vendor/blamejs/lib/backup/index.js +41 -20
  58. package/lib/vendor/blamejs/lib/backup/manifest.js +7 -1
  59. package/lib/vendor/blamejs/lib/break-glass.js +41 -22
  60. package/lib/vendor/blamejs/lib/cbor.js +34 -11
  61. package/lib/vendor/blamejs/lib/cdn-cache-control.js +7 -3
  62. package/lib/vendor/blamejs/lib/cert.js +5 -3
  63. package/lib/vendor/blamejs/lib/cli.js +5 -1
  64. package/lib/vendor/blamejs/lib/cloud-events.js +3 -2
  65. package/lib/vendor/blamejs/lib/cluster-storage.js +7 -3
  66. package/lib/vendor/blamejs/lib/codepoint-class.js +17 -0
  67. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -1
  68. package/lib/vendor/blamejs/lib/compliance-sanctions.js +9 -7
  69. package/lib/vendor/blamejs/lib/compliance.js +1 -1
  70. package/lib/vendor/blamejs/lib/config-drift.js +22 -8
  71. package/lib/vendor/blamejs/lib/content-credentials.js +11 -8
  72. package/lib/vendor/blamejs/lib/content-digest.js +11 -4
  73. package/lib/vendor/blamejs/lib/cookies.js +10 -2
  74. package/lib/vendor/blamejs/lib/cose.js +20 -0
  75. package/lib/vendor/blamejs/lib/crdt.js +2 -1
  76. package/lib/vendor/blamejs/lib/crypto-field.js +29 -23
  77. package/lib/vendor/blamejs/lib/crypto.js +18 -4
  78. package/lib/vendor/blamejs/lib/csp.js +4 -0
  79. package/lib/vendor/blamejs/lib/daemon.js +4 -1
  80. package/lib/vendor/blamejs/lib/data-act.js +27 -4
  81. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +14 -6
  82. package/lib/vendor/blamejs/lib/db-query.js +69 -9
  83. package/lib/vendor/blamejs/lib/db.js +32 -15
  84. package/lib/vendor/blamejs/lib/dora.js +43 -13
  85. package/lib/vendor/blamejs/lib/dr-runbook.js +1 -1
  86. package/lib/vendor/blamejs/lib/dsa.js +2 -1
  87. package/lib/vendor/blamejs/lib/dsr.js +22 -8
  88. package/lib/vendor/blamejs/lib/early-hints.js +19 -0
  89. package/lib/vendor/blamejs/lib/eat.js +5 -1
  90. package/lib/vendor/blamejs/lib/external-db.js +60 -4
  91. package/lib/vendor/blamejs/lib/fda-21cfr11.js +30 -5
  92. package/lib/vendor/blamejs/lib/flag-providers.js +6 -2
  93. package/lib/vendor/blamejs/lib/forms.js +1 -1
  94. package/lib/vendor/blamejs/lib/gate-contract.js +46 -5
  95. package/lib/vendor/blamejs/lib/gdpr-ropa.js +18 -9
  96. package/lib/vendor/blamejs/lib/graphql-federation.js +17 -4
  97. package/lib/vendor/blamejs/lib/guard-all.js +2 -2
  98. package/lib/vendor/blamejs/lib/guard-dsn.js +1 -1
  99. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  100. package/lib/vendor/blamejs/lib/guard-html.js +9 -11
  101. package/lib/vendor/blamejs/lib/guard-imap-command.js +1 -1
  102. package/lib/vendor/blamejs/lib/guard-jmap.js +1 -1
  103. package/lib/vendor/blamejs/lib/guard-json.js +14 -6
  104. package/lib/vendor/blamejs/lib/guard-mail-move.js +1 -1
  105. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +1 -1
  106. package/lib/vendor/blamejs/lib/guard-pop3-command.js +1 -1
  107. package/lib/vendor/blamejs/lib/guard-smtp-command.js +1 -1
  108. package/lib/vendor/blamejs/lib/guard-svg.js +8 -9
  109. package/lib/vendor/blamejs/lib/html-balance.js +7 -3
  110. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +33 -12
  111. package/lib/vendor/blamejs/lib/http-client.js +225 -53
  112. package/lib/vendor/blamejs/lib/iab-tcf.js +3 -2
  113. package/lib/vendor/blamejs/lib/importmap-integrity.js +41 -1
  114. package/lib/vendor/blamejs/lib/incident-report.js +9 -6
  115. package/lib/vendor/blamejs/lib/json-patch.js +1 -1
  116. package/lib/vendor/blamejs/lib/json-path.js +24 -3
  117. package/lib/vendor/blamejs/lib/jtd.js +2 -2
  118. package/lib/vendor/blamejs/lib/legal-hold.js +24 -8
  119. package/lib/vendor/blamejs/lib/log.js +2 -2
  120. package/lib/vendor/blamejs/lib/mail-agent.js +2 -2
  121. package/lib/vendor/blamejs/lib/mail-arf.js +1 -1
  122. package/lib/vendor/blamejs/lib/mail-auth.js +3 -3
  123. package/lib/vendor/blamejs/lib/mail-bimi.js +16 -16
  124. package/lib/vendor/blamejs/lib/mail-bounce.js +3 -3
  125. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +71 -6
  126. package/lib/vendor/blamejs/lib/mail-deploy.js +9 -5
  127. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -4
  128. package/lib/vendor/blamejs/lib/mail-helo.js +2 -4
  129. package/lib/vendor/blamejs/lib/mail-journal.js +11 -8
  130. package/lib/vendor/blamejs/lib/mail-mdn.js +8 -4
  131. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -4
  132. package/lib/vendor/blamejs/lib/mail-scan.js +3 -5
  133. package/lib/vendor/blamejs/lib/mail-server-jmap.js +4 -1
  134. package/lib/vendor/blamejs/lib/mail-server-registry.js +1 -1
  135. package/lib/vendor/blamejs/lib/mail-server-tls.js +9 -2
  136. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -4
  137. package/lib/vendor/blamejs/lib/mail-store-fts.js +1 -1
  138. package/lib/vendor/blamejs/lib/mail.js +22 -2
  139. package/lib/vendor/blamejs/lib/markup-tokenizer.js +24 -0
  140. package/lib/vendor/blamejs/lib/mcp.js +6 -4
  141. package/lib/vendor/blamejs/lib/mdoc.js +26 -3
  142. package/lib/vendor/blamejs/lib/metrics.js +14 -3
  143. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +2 -2
  144. package/lib/vendor/blamejs/lib/middleware/body-parser.js +10 -4
  145. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +26 -18
  146. package/lib/vendor/blamejs/lib/middleware/clear-site-data.js +5 -1
  147. package/lib/vendor/blamejs/lib/middleware/compression.js +9 -0
  148. package/lib/vendor/blamejs/lib/middleware/cors.js +32 -23
  149. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +60 -21
  150. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -4
  151. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +28 -4
  152. package/lib/vendor/blamejs/lib/middleware/network-allowlist.js +61 -30
  153. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +25 -16
  154. package/lib/vendor/blamejs/lib/middleware/scim-server.js +2 -1
  155. package/lib/vendor/blamejs/lib/middleware/security-headers.js +24 -6
  156. package/lib/vendor/blamejs/lib/middleware/speculation-rules.js +6 -3
  157. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +2 -2
  158. package/lib/vendor/blamejs/lib/money.js +1 -1
  159. package/lib/vendor/blamejs/lib/mtls-ca.js +10 -6
  160. package/lib/vendor/blamejs/lib/network-dns-resolver.js +1 -1
  161. package/lib/vendor/blamejs/lib/network-dns.js +9 -2
  162. package/lib/vendor/blamejs/lib/network-dnssec.js +2 -1
  163. package/lib/vendor/blamejs/lib/network-smtp-policy.js +23 -5
  164. package/lib/vendor/blamejs/lib/network-tls.js +27 -5
  165. package/lib/vendor/blamejs/lib/network-tsig.js +2 -2
  166. package/lib/vendor/blamejs/lib/nis2-report.js +1 -1
  167. package/lib/vendor/blamejs/lib/nist-crosswalk.js +1 -1
  168. package/lib/vendor/blamejs/lib/ntp-check.js +28 -0
  169. package/lib/vendor/blamejs/lib/numeric-bounds.js +9 -0
  170. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +1 -2
  171. package/lib/vendor/blamejs/lib/object-store/gcs-bucket-ops.js +4 -2
  172. package/lib/vendor/blamejs/lib/object-store/gcs.js +6 -4
  173. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -2
  174. package/lib/vendor/blamejs/lib/object-store/http-request.js +30 -1
  175. package/lib/vendor/blamejs/lib/object-store/local.js +37 -17
  176. package/lib/vendor/blamejs/lib/object-store/sigv4.js +1 -2
  177. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +20 -4
  178. package/lib/vendor/blamejs/lib/outbox.js +11 -4
  179. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +1 -1
  180. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +21 -3
  181. package/lib/vendor/blamejs/lib/queue-local.js +10 -3
  182. package/lib/vendor/blamejs/lib/redact.js +7 -3
  183. package/lib/vendor/blamejs/lib/request-helpers.js +201 -23
  184. package/lib/vendor/blamejs/lib/resource-access-lock.js +3 -3
  185. package/lib/vendor/blamejs/lib/restore-bundle.js +46 -18
  186. package/lib/vendor/blamejs/lib/restore-rollback.js +10 -4
  187. package/lib/vendor/blamejs/lib/restore.js +19 -0
  188. package/lib/vendor/blamejs/lib/retention.js +20 -4
  189. package/lib/vendor/blamejs/lib/router.js +17 -4
  190. package/lib/vendor/blamejs/lib/safe-ical.js +2 -2
  191. package/lib/vendor/blamejs/lib/safe-icap.js +1 -1
  192. package/lib/vendor/blamejs/lib/safe-json.js +44 -0
  193. package/lib/vendor/blamejs/lib/safe-sieve.js +1 -1
  194. package/lib/vendor/blamejs/lib/safe-vcard.js +1 -1
  195. package/lib/vendor/blamejs/lib/sandbox-worker.js +6 -0
  196. package/lib/vendor/blamejs/lib/sandbox.js +1 -1
  197. package/lib/vendor/blamejs/lib/scheduler.js +17 -1
  198. package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +16 -0
  199. package/lib/vendor/blamejs/lib/session.js +27 -3
  200. package/lib/vendor/blamejs/lib/sql.js +3 -3
  201. package/lib/vendor/blamejs/lib/static.js +65 -13
  202. package/lib/vendor/blamejs/lib/template.js +7 -5
  203. package/lib/vendor/blamejs/lib/tenant-quota.js +52 -19
  204. package/lib/vendor/blamejs/lib/tsa.js +5 -2
  205. package/lib/vendor/blamejs/lib/vault/index.js +5 -0
  206. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +22 -26
  207. package/lib/vendor/blamejs/lib/vault/passphrase-source.js +8 -3
  208. package/lib/vendor/blamejs/lib/vault/rotate.js +13 -18
  209. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +4 -1
  210. package/lib/vendor/blamejs/lib/vc.js +1 -1
  211. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +10 -10
  212. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +23 -10
  213. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5498 -5494
  214. package/lib/vendor/blamejs/lib/webhook.js +16 -1
  215. package/lib/vendor/blamejs/lib/websocket.js +1 -1
  216. package/lib/vendor/blamejs/lib/worm.js +1 -1
  217. package/lib/vendor/blamejs/lib/ws-client.js +57 -46
  218. package/lib/vendor/blamejs/lib/x509-chain.js +44 -0
  219. package/lib/vendor/blamejs/package.json +1 -1
  220. package/lib/vendor/blamejs/release-notes/v0.15.14.json +122 -0
  221. package/lib/vendor/blamejs/scripts/check-vendor-currency.js +119 -4
  222. package/lib/vendor/blamejs/test/00-primitives.js +5 -1
  223. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +18 -4
  224. package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +42 -0
  225. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +36 -0
  226. package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
  227. package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +47 -0
  228. package/lib/vendor/blamejs/test/layer-0-primitives/archive-gz.test.js +24 -0
  229. package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-hardening.test.js +160 -0
  230. package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +45 -0
  231. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +30 -0
  232. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-open-nofollow.test.js +79 -0
  233. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-write-excl.test.js +132 -0
  234. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-write-stream.test.js +181 -0
  235. package/lib/vendor/blamejs/test/layer-0-primitives/audit-chain-corrupted-anchor.test.js +65 -0
  236. package/lib/vendor/blamejs/test/layer-0-primitives/audit-chain-incremental-verify.test.js +83 -0
  237. package/lib/vendor/blamejs/test/layer-0-primitives/audit-daily-review.test.js +48 -1
  238. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +13 -3
  239. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +122 -0
  240. package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge.test.js +37 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +5 -3
  242. package/lib/vendor/blamejs/test/layer-0-primitives/auth-lockout.test.js +21 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +73 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +17 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +62 -3
  246. package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +12 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/cluster-storage.test.js +40 -0
  248. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +146 -5
  249. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +14 -0
  250. package/lib/vendor/blamejs/test/layer-0-primitives/compression-range.test.js +115 -0
  251. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +17 -5
  252. package/lib/vendor/blamejs/test/layer-0-primitives/cors.test.js +27 -5
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +83 -0
  254. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +58 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/data-act.test.js +30 -0
  256. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +74 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/dora.test.js +20 -6
  258. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-alg-kty.test.js +64 -0
  259. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +32 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/fda-21cfr11.test.js +43 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +30 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/graphql-federation.test.js +33 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +34 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +12 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +72 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-throttle-transform.test.js +88 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/importmap-integrity.test.js +25 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +28 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +20 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/mail-header-injection.test.js +58 -0
  271. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +63 -9
  272. package/lib/vendor/blamejs/test/layer-0-primitives/mdoc.test.js +41 -14
  273. package/lib/vendor/blamejs/test/layer-0-primitives/network-allowlist.test.js +61 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/object-store-range-header.test.js +51 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +35 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/output-header-hardening.test.js +102 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/parser-verify-hardening.test.js +191 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/proto-shadow-allowlist.test.js +120 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +75 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +128 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/restore-blob-remap.test.js +128 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/retention-sweep-termination.test.js +104 -0
  283. package/lib/vendor/blamejs/test/layer-0-primitives/router-body-validation.test.js +98 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/safe-json-stringify-for-script.test.js +43 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +48 -5
  286. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +23 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +54 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +24 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +42 -1
  290. package/lib/vendor/blamejs/test/layer-0-primitives/step-up.test.js +7 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/template-escape-html.test.js +43 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +15 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/vault-default-store.test.js +48 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/vendor-currency-classify.test.js +77 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +50 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +22 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/x509-chain-ca-enforcement.test.js +149 -0
  298. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +34 -0
  299. package/package.json +1 -1
@@ -1093,6 +1093,15 @@ function _verifyOcspSignature(parsed, issuerPem) {
1093
1093
  // `ocsp.requireStapled` or any other source) plus the issuer cert PEM
1094
1094
  // and returns a structured outcome:
1095
1095
  // { ok, status, certStatus, thisUpdate, nextUpdate, signatureValid, errors }
1096
+ // Normalize a certificate serial for comparison: lowercase, drop separators
1097
+ // (X509Certificate.serialNumber is uppercase, no colons here but defensive) and
1098
+ // the optional DER leading sign-zero, so a serial from node:crypto and one
1099
+ // parsed from the OCSP certID DER compare equal. Both sides go through this.
1100
+ function _normOcspSerial(s) {
1101
+ var h = String(s || "").toLowerCase().replace(/[^0-9a-f]/g, "");
1102
+ return h.replace(/^0+/, "") || "0";
1103
+ }
1104
+
1096
1105
  function evaluateOcspResponse(ocspDer, opts) {
1097
1106
  opts = opts || {};
1098
1107
  var issuerPem = opts.issuerPem;
@@ -1120,12 +1129,21 @@ function evaluateOcspResponse(ocspDer, opts) {
1120
1129
  return { ok: false, status: parsed.status, signatureValid: false,
1121
1130
  errors: ["OCSP signature did not verify against the issuer key"] };
1122
1131
  }
1123
- // Look up the requested cert serial in the responses; "good" wins.
1124
- var serial = opts.serialHex || (parsed.basic.responses[0] && parsed.basic.responses[0].certIdSerialHex);
1132
+ // Bind the response to the serial of the certificate UNDER VALIDATION. The
1133
+ // old code defaulted an absent serialHex to responses[0]'s own serial and
1134
+ // then matched it — so a CA-signed "good" response covering a DIFFERENT cert
1135
+ // of the same issuer (replayed/mis-routed batch reply) was accepted. Require
1136
+ // a bound serial and fail closed without one; compare normalized (lowercase,
1137
+ // strip separators + DER leading sign-zero on both sides).
1138
+ if (!opts.serialHex) {
1139
+ return { ok: false, status: parsed.status, signatureValid: true,
1140
+ errors: ["OCSP evaluation requires opts.serialHex (the serial of the certificate being validated) to bind the response"] };
1141
+ }
1142
+ var wantSerial = _normOcspSerial(opts.serialHex);
1125
1143
  var match = null;
1126
1144
  for (var i = 0; i < parsed.basic.responses.length; i += 1) {
1127
1145
  var r = parsed.basic.responses[i];
1128
- if (!serial || r.certIdSerialHex === serial) { match = r; break; }
1146
+ if (_normOcspSerial(r.certIdSerialHex) === wantSerial) { match = r; break; }
1129
1147
  }
1130
1148
  if (!match) {
1131
1149
  return { ok: false, status: parsed.status, signatureValid: true,
@@ -1418,7 +1436,9 @@ async function fetchOcspResponse(opts) {
1418
1436
  }
1419
1437
  var evald = evaluateOcspResponse(res.body, {
1420
1438
  issuerPem: opts.issuerPem,
1421
- serialHex: opts.serialHex || null,
1439
+ // Bind to the leaf being checked (its serial), not whatever the response
1440
+ // happens to carry — defaults to leafX.serialNumber when not overridden.
1441
+ serialHex: opts.serialHex || leafX.serialNumber,
1422
1442
  expectedNonce: opts.nonce === false ? null : built.nonce,
1423
1443
  });
1424
1444
  if (!evald.ok) {
@@ -1458,7 +1478,9 @@ var ocsp = Object.freeze({
1458
1478
  }
1459
1479
  var evald = evaluateOcspResponse(rv.ocspBytes, {
1460
1480
  issuerPem: opts.issuerPem,
1461
- serialHex: opts.serialHex || null,
1481
+ // Bind to the connected peer's certificate serial (not the response's own
1482
+ // entry) — without it evaluateOcspResponse fails closed.
1483
+ serialHex: opts.serialHex || (rv.peerCert && rv.peerCert.serialNumber) || null,
1462
1484
  });
1463
1485
  if (!evald.ok) {
1464
1486
  throw new TlsTrustError("tls/ocsp-not-good",
@@ -61,8 +61,8 @@ var ERROR = { NOERROR: 0, BADSIG: 16, BADKEY: 17, BADTIME: 18, BADTRUNC: 22 };
61
61
 
62
62
  function _normAlg(name, allowLegacy) {
63
63
  var key = String(name || "hmac-sha256").toLowerCase().replace(/\.$/, "");
64
- if (ALGORITHMS[key]) return { name: key, hash: ALGORITHMS[key] };
65
- if (LEGACY_ALGORITHMS[key]) {
64
+ if (Object.prototype.hasOwnProperty.call(ALGORITHMS, key)) return { name: key, hash: ALGORITHMS[key] };
65
+ if (Object.prototype.hasOwnProperty.call(LEGACY_ALGORITHMS, key)) {
66
66
  if (!allowLegacy) throw new TsigError("tsig/legacy-algorithm", "tsig: algorithm '" + key + "' is broken; pass allowLegacy:true to permit it for legacy interop");
67
67
  return { name: key, hash: LEGACY_ALGORITHMS[key] };
68
68
  }
@@ -54,7 +54,7 @@ function create(opts) {
54
54
  validateOpts.requireNonEmptyString(opts.entityId,
55
55
  "nis2.report.create: opts.entityId is required (NIS2 registration ID)",
56
56
  Nis2ReportError, "nis2-report/bad-entity-id");
57
- if (!VALID_ENTITY_TYPES[opts.entityType]) {
57
+ if (!Object.prototype.hasOwnProperty.call(VALID_ENTITY_TYPES, opts.entityType)) {
58
58
  throw new Nis2ReportError("nis2-report/bad-entity-type",
59
59
  "nis2.report.create: opts.entityType must be 'essential' or 'important' (NIS2 Article 3 classification)");
60
60
  }
@@ -199,7 +199,7 @@ var CATALOGS = {
199
199
  * // → ["b.permissions", "b.middleware.requireAuth", ...]
200
200
  */
201
201
  function controls(catalog) {
202
- if (typeof catalog !== "string" || !CATALOGS[catalog]) {
202
+ if (typeof catalog !== "string" || !Object.prototype.hasOwnProperty.call(CATALOGS, catalog)) {
203
203
  throw new NistCrosswalkError("nist-crosswalk/unknown-catalog",
204
204
  "controls: unknown catalog '" + catalog + "'. Known: " +
205
205
  Object.keys(CATALOGS).join(", "));
@@ -45,6 +45,8 @@
45
45
  * Boot-time clock-drift verification against an external NTP / NTS-KE reference.
46
46
  */
47
47
  var dgram = require("node:dgram");
48
+ var nodeCrypto = require("node:crypto");
49
+ var bCrypto = require("./crypto");
48
50
  var C = require("./constants");
49
51
  var lazyRequire = require("./lazy-require");
50
52
  var safeAsync = require("./safe-async");
@@ -200,6 +202,14 @@ function querySingle(server, opts) {
200
202
  // LI=0 (no warning), VN=4, Mode=3 (client). Other bytes zero.
201
203
  var req = Buffer.alloc(NTP_PACKET_BYTES);
202
204
  req[0] = 0x23;
205
+ // RFC 5905 §8 client-cookie: put a random 64-bit nonce in the request's
206
+ // Transmit Timestamp (bytes 40-47). A conformant server copies it verbatim
207
+ // into the reply's Originate Timestamp (bytes 24-31). Verifying that echo
208
+ // rejects an off-path spoofed reply — without it ANY 48-byte UDP datagram
209
+ // reaching our ephemeral port becomes the authoritative time, letting a
210
+ // spoofer force a fatal-drift refuse-to-boot under BLAMEJS_NTP_STRICT.
211
+ var originCookie = nodeCrypto.randomBytes(8);
212
+ originCookie.copy(req, 40);
203
213
  var sendTimeMs = Date.now();
204
214
 
205
215
  socket.on("error", function (e) {
@@ -213,6 +223,24 @@ function querySingle(server, opts) {
213
223
  if (!Buffer.isBuffer(msg) || msg.length < NTP_PACKET_BYTES) {
214
224
  return done({ code: "ntp/bad-reply", message: "reply too short (" + (msg && msg.length) + " bytes)" });
215
225
  }
226
+ // Origin-cookie echo (RFC 5905 §8): the reply's Originate Timestamp
227
+ // (bytes 24-31) MUST equal the nonce we sent. An off-path spoofer can't
228
+ // know it, so this is the primary reply-authenticity check.
229
+ if (!bCrypto.timingSafeEqual(msg.subarray(24, 32), originCookie)) {
230
+ return done({ code: "ntp/origin-mismatch",
231
+ message: server + ": reply Originate Timestamp does not echo the request nonce (spoofed/stale reply)" });
232
+ }
233
+ // Reject a non-server mode, an unsynchronized/kiss-o'-death stratum
234
+ // (0 or >= 16), or LI=3 (alarm — clock not synchronized): such a peer
235
+ // cannot supply a trustworthy time and must not drive drift.
236
+ var mode = msg[0] & 0x07;
237
+ var li = (msg[0] >> 6) & 0x03;
238
+ var stratum = msg[1];
239
+ if (mode !== 4 || li === 3 || stratum === 0 || stratum >= 16) {
240
+ return done({ code: "ntp/unsynchronized",
241
+ message: server + ": reply mode=" + mode + " stratum=" + stratum + " LI=" + li +
242
+ " is not a synchronized server response" });
243
+ }
216
244
  // Bytes 40-47 = Transmit Timestamp (NTP epoch seconds.fraction)
217
245
  var ntpSeconds = msg.readUInt32BE(40); // NTP packet offset
218
246
  var ntpFraction = msg.readUInt32BE(44); // NTP packet offset
@@ -66,6 +66,14 @@ function isNonNegativeFiniteInt(value) {
66
66
  Number.isInteger(value) && value >= 0;
67
67
  }
68
68
 
69
+ // Any-sign finite integer (no sign bound) — for callers that only require
70
+ // integrality (e.g. a CloudEvents 32-bit signed-integer extension, a DNS
71
+ // algorithm/digest-type code) and reject only non-numbers / floats / Infinity /
72
+ // NaN. Distinct from isNonNegativeFiniteInt (which also forbids negatives).
73
+ function isFiniteInt(value) {
74
+ return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value);
75
+ }
76
+
69
77
  // requirePositiveFiniteIntIfPresent / requireNonNegativeFiniteIntIfPresent —
70
78
  // optional-shape gates that throw via the caller's framework-error class
71
79
  // when the value is present but invalid. Replaces the per-file
@@ -150,6 +158,7 @@ module.exports = {
150
158
  shape: shape,
151
159
  isPositiveFiniteInt: isPositiveFiniteInt,
152
160
  isNonNegativeFiniteInt: isNonNegativeFiniteInt,
161
+ isFiniteInt: isFiniteInt,
153
162
  requirePositiveFiniteInt: requirePositiveFiniteInt,
154
163
  requirePositiveFiniteIntIfPresent: requirePositiveFiniteIntIfPresent,
155
164
  requireNonNegativeFiniteIntIfPresent: requireNonNegativeFiniteIntIfPresent,
@@ -37,7 +37,6 @@
37
37
  */
38
38
  var nodeCrypto = require("node:crypto");
39
39
  var { URL } = require("node:url");
40
- var { Readable } = require("node:stream");
41
40
  var safeXml = require("../parsers/safe-xml");
42
41
  var sharedRequest = require("./http-request");
43
42
  var sigv4 = require("./sigv4");
@@ -299,7 +298,7 @@ function create(config) {
299
298
  return getResponse(key, opts).then(function (r) { return r.body; });
300
299
  }
301
300
 
302
- function getStream(key, opts) { return Readable.from(get(key, opts)); }
301
+ function getStream(key, opts) { return sharedRequest.promiseToStream(get(key, opts)); }
303
302
 
304
303
  function getResponse(key, opts) {
305
304
  opts = opts || {};
@@ -23,13 +23,13 @@
23
23
  * Auth: same service-account JSON / RSA-SHA256-signed JWT exchanged
24
24
  * for an OAuth2 access token as `lib/object-store/gcs.js`.
25
25
  */
26
- var nodeFs = require("node:fs");
27
26
  var gcs = require("./gcs");
28
27
  var authHeader = require("../auth-header");
29
28
  var httpClient = require("../http-client");
30
29
  var safeJson = require("../safe-json");
31
30
  var safeUrl = require("../safe-url");
32
31
  var C = require("../constants");
32
+ var atomicFile = require("../atomic-file");
33
33
  var requestHelpers = require("../request-helpers");
34
34
  var { ObjectStoreError } = require("../framework-error");
35
35
 
@@ -139,7 +139,9 @@ function create(config) {
139
139
  var serviceAccount = config.serviceAccount;
140
140
  if (!serviceAccount && config.serviceAccountFile) {
141
141
  try {
142
- serviceAccount = safeJson.parse(nodeFs.readFileSync(config.serviceAccountFile));
142
+ // Cap + fd-bound read of the GCS service-account JSON (private_key). NO
143
+ // refuseSymlink: commonly a k8s projected-secret mount (symlink).
144
+ serviceAccount = safeJson.parse(atomicFile.fdSafeReadSync(config.serviceAccountFile, { maxBytes: C.BYTES.kib(64), encoding: "utf8" }));
143
145
  } catch (e) {
144
146
  throw _err("BAD_OPT", "gcs bucketOps: failed to read serviceAccountFile '" +
145
147
  config.serviceAccountFile + "': " + ((e && e.message) || String(e)), true);
@@ -22,12 +22,11 @@
22
22
  * https://cloud.google.com/storage/docs/json_api/v1
23
23
  * https://developers.google.com/identity/protocols/oauth2/service-account
24
24
  */
25
- var nodeFs = require("node:fs");
26
25
  var nodeCrypto = require("node:crypto");
27
- var { Readable } = require("node:stream");
28
26
  var bCrypto = require("../crypto");
29
27
  var safeJson = require("../safe-json");
30
28
  var C = require("../constants");
29
+ var atomicFile = require("../atomic-file");
31
30
  var requestHelpers = require("../request-helpers");
32
31
  var { ObjectStoreError } = require("../framework-error");
33
32
  var safeUrl = require("../safe-url");
@@ -115,7 +114,10 @@ function create(config) {
115
114
  var serviceAccount = config.serviceAccount;
116
115
  if (!serviceAccount && config.serviceAccountFile) {
117
116
  try {
118
- serviceAccount = safeJson.parse(nodeFs.readFileSync(config.serviceAccountFile), { schema: SERVICE_ACCOUNT_SCHEMA });
117
+ // Cap + fd-bound read of the GCS service-account JSON (contains the
118
+ // private_key). NO refuseSymlink: the SA file is commonly a k8s
119
+ // projected-secret mount (symlink). 64 KiB bounds the uncapped read.
120
+ serviceAccount = safeJson.parse(atomicFile.fdSafeReadSync(config.serviceAccountFile, { maxBytes: C.BYTES.kib(64), encoding: "utf8" }), { schema: SERVICE_ACCOUNT_SCHEMA });
119
121
  } catch (e) {
120
122
  throw new Error("gcs: failed to read serviceAccountFile '" + config.serviceAccountFile + "': " + e.message);
121
123
  }
@@ -224,7 +226,7 @@ function create(config) {
224
226
  }
225
227
 
226
228
  function getStream(key, opts) {
227
- return Readable.from(get(key, opts));
229
+ return sharedRequest.promiseToStream(get(key, opts));
228
230
  }
229
231
 
230
232
  async function getResponse(key, opts) {
@@ -16,7 +16,6 @@
16
16
  * Errors are surfaced as object-store errors with statusCode set so the
17
17
  * retry layer can classify retryable vs permanent.
18
18
  */
19
- var { Readable } = require("node:stream");
20
19
  var { ObjectStoreError } = require("../framework-error");
21
20
  var safeUrl = require("../safe-url");
22
21
  var sharedRequest = require("./http-request");
@@ -96,7 +95,7 @@ function create(config) {
96
95
  // https that doesn't buffer; return a Readable wrapping the buffered
97
96
  // body. Backends that support chunked transfer (e.g. SigV4) implement
98
97
  // a real streaming getStream in their own adapter.
99
- return Readable.from(get(key));
98
+ return sharedRequest.promiseToStream(get(key));
100
99
  }
101
100
 
102
101
  function head(key) {
@@ -16,6 +16,7 @@
16
16
  * different class pass `errorClass: SomeError` in opts.
17
17
  */
18
18
 
19
+ var { Readable } = require("node:stream");
19
20
  var httpClient = require("../http-client");
20
21
  var C = require("../constants");
21
22
  var numericBounds = require("../numeric-bounds");
@@ -109,7 +110,22 @@ function resolvePresignUploadMinBytes(opts) {
109
110
  // parameter; the rest is identical.
110
111
  function applyConditionalGetHeaders(target, opts, rangeHeaderName) {
111
112
  if (opts.range) {
112
- target[rangeHeaderName] = "bytes=" + opts.range.start + "-" + opts.range.end;
113
+ // The documented + shipped contract is an array [start, end] (see
114
+ // b.archive.adapters.objectStore and b.backup). Reading .start/.end off an
115
+ // array yields undefined → "bytes=undefined-undefined", which every store
116
+ // IGNORES — silently returning the FULL object instead of the byte range
117
+ // (over-fetch + wrong data for a partial read). Accept the array form (and
118
+ // {start,end} for compatibility) and validate, so a malformed range fails
119
+ // loudly rather than emitting a garbage header.
120
+ var r = opts.range;
121
+ var start = Array.isArray(r) ? r[0] : r.start;
122
+ var end = Array.isArray(r) ? r[1] : r.end;
123
+ if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) {
124
+ throw _err("INVALID_RANGE",
125
+ "range must be [start, end] (or { start, end }) with 0 <= start <= end, got " +
126
+ JSON.stringify(r), true);
127
+ }
128
+ target[rangeHeaderName] = "bytes=" + start + "-" + end;
113
129
  }
114
130
  if (opts.ifNoneMatch) target["If-None-Match"] = opts.ifNoneMatch;
115
131
  if (opts.ifMatch) target["If-Match"] = opts.ifMatch;
@@ -153,8 +169,21 @@ function notModifiedGetResult() {
153
169
  };
154
170
  }
155
171
 
172
+ // Wrap a Promise<Buffer|string> as a Readable WITHOUT awaiting it first, so a
173
+ // backend's getStream() stays synchronous (the dispatcher hands the returned
174
+ // Readable straight to the consumer). A bare `Readable.from(promise)` throws
175
+ // ERR_INVALID_ARG_TYPE — Readable.from needs an (async-)iterable, not a Promise
176
+ // — which broke getStream on every remote backend. The async generator defers
177
+ // the await to the first read; a rejection surfaces as the stream's 'error'
178
+ // event, matching the dispatcher's "the Readable surfaces its own errors"
179
+ // contract.
180
+ function promiseToStream(promise) {
181
+ return Readable.from((async function* () { yield await promise; })());
182
+ }
183
+
156
184
  module.exports = request;
157
185
  module.exports.applyConditionalGetHeaders = applyConditionalGetHeaders;
186
+ module.exports.promiseToStream = promiseToStream;
158
187
  module.exports.mapGetResponse = mapGetResponse;
159
188
  module.exports.mapHeadResponse = mapHeadResponse;
160
189
  module.exports.notModifiedGetResult = notModifiedGetResult;
@@ -14,6 +14,7 @@
14
14
  var nodeFs = require("node:fs");
15
15
  var nodePath = require("node:path");
16
16
  var atomicFile = require("../atomic-file");
17
+ var C = require("../constants");
17
18
  var cluster = require("../cluster");
18
19
  var { ObjectStoreError } = require("../framework-error");
19
20
 
@@ -54,16 +55,14 @@ function create(config) {
54
55
  return Promise.resolve({ size: body.length });
55
56
  }
56
57
  if (body && typeof body.pipe === "function") {
57
- // Streaming put — pipe directly to disk
58
- return new Promise(function (resolve, reject) {
59
- var ws = nodeFs.createWriteStream(full);
60
- var bytes = 0;
61
- body.on("data", function (chunk) { bytes += chunk.length; });
62
- body.pipe(ws);
63
- ws.on("finish", function () { resolve({ size: bytes }); });
64
- ws.on("error", reject);
65
- body.on("error", reject);
66
- });
58
+ // Streaming put — stage into a no-follow exclusive temp + atomic rename
59
+ // (a bare createWriteStream(full) follows a symlink planted at `full` and
60
+ // leaves a half-written object there if the source aborts). maxBytes is
61
+ // raised to the object-store ceiling; default 64 MiB is too small here.
62
+ return atomicFile.writeStream(full, body, {
63
+ fileMode: 0o600,
64
+ maxBytes: C.BYTES.gib(64),
65
+ }).then(function (r) { return { size: r.bytesWritten }; });
67
66
  }
68
67
  if (typeof body === "string") {
69
68
  var buf = Buffer.from(body, "utf8");
@@ -75,18 +74,39 @@ function create(config) {
75
74
 
76
75
  function get(key) {
77
76
  var full = _resolveSafe(rootDir, key);
78
- if (!nodeFs.existsSync(full)) {
79
- return Promise.reject(_err("NOT_FOUND", "key not found: " + key, true));
80
- }
81
- return Promise.resolve(nodeFs.readFileSync(full));
77
+ // One capped fd-bound read (no existsSync check-then-read TOCTOU): get()
78
+ // buffers the whole object, so an uncapped read of a multi-GiB object is an
79
+ // OOM lever — cap it (large reads should use getStream). refuseSymlink stays
80
+ // OFF: operators may legitimately symlink into the store, and _resolveSafe
81
+ // already confines the key to rootDir.
82
+ try {
83
+ return Promise.resolve(atomicFile.fdSafeReadSync(full, {
84
+ maxBytes: C.BYTES.mib(64),
85
+ errorFor: function (kind, detail) {
86
+ if (kind === "enoent") return _err("NOT_FOUND", "key not found: " + key, true);
87
+ if (kind === "too-large") {
88
+ return _err("OBJECT_TOO_LARGE", "object " + key + " exceeds the buffered-get read cap (" +
89
+ detail.size + " > " + detail.max + " bytes) — use getStream()", true);
90
+ }
91
+ return _err("READ_FAILED", "failed to read " + key, true);
92
+ },
93
+ }));
94
+ } catch (e) { return Promise.reject(e); }
82
95
  }
83
96
 
84
97
  function getStream(key) {
85
98
  var full = _resolveSafe(rootDir, key);
86
- if (!nodeFs.existsSync(full)) {
87
- throw _err("NOT_FOUND", "key not found: " + key, true);
99
+ // Open once and stream from that fd, mapping ENOENT to NOT_FOUND, so the
100
+ // existsSync→createReadStream check-then-read window is collapsed. Plain
101
+ // O_RDONLY (follows symlinks): operators may symlink into the store, and the
102
+ // key is already confined by _resolveSafe.
103
+ var fd;
104
+ try { fd = nodeFs.openSync(full, "r"); }
105
+ catch (e) {
106
+ if (e && e.code === "ENOENT") throw _err("NOT_FOUND", "key not found: " + key, true);
107
+ throw e;
88
108
  }
89
- return nodeFs.createReadStream(full);
109
+ return nodeFs.createReadStream(full, { fd: fd });
90
110
  }
91
111
 
92
112
  function head(key) {
@@ -25,7 +25,6 @@
25
25
  */
26
26
  var nodeCrypto = require("node:crypto");
27
27
  var { URL } = require("node:url");
28
- var { Readable } = require("node:stream");
29
28
  var safeXml = require("../parsers/safe-xml");
30
29
  var sharedRequest = require("./http-request");
31
30
  var C = require("../constants");
@@ -633,7 +632,7 @@ function create(config) {
633
632
  }
634
633
 
635
634
  function getStream(key, opts) {
636
- return Readable.from(get(key, opts));
635
+ return sharedRequest.promiseToStream(get(key, opts));
637
636
  }
638
637
 
639
638
  // getResponse(key, opts?) — full-fidelity GET. Returns
@@ -133,12 +133,27 @@ function _valueToOtlp(v) {
133
133
  return { stringValue: String(v) };
134
134
  }
135
135
 
136
+ // Run a single wire STRING (span name / status message) through the telemetry
137
+ // redactor. These reach the collector exactly like attribute values, so a
138
+ // connection string / token / PII in an error message (the tracer's canonical
139
+ // `setStatus("error", e.message)`) must be scrubbed too (CWE-532). Routes
140
+ // through redactAttrs (the same chokepoint attributes use); fails toward an
141
+ // empty string on a redactor throw, matching redactAttrs' drop-on-error.
142
+ function _redactWireString(key, value) {
143
+ if (typeof value !== "string" || value.length === 0) return value || "";
144
+ try {
145
+ var holder = {};
146
+ holder[key] = value;
147
+ return observability().redactAttrs(holder)[key];
148
+ } catch (_e) { return ""; }
149
+ }
150
+
136
151
  function _spanToOtlp(span) {
137
152
  return {
138
153
  traceId: span.traceId,
139
154
  spanId: span.spanId,
140
155
  parentSpanId: span.parentSpanId || "",
141
- name: span.name,
156
+ name: _redactWireString("otel.span.name", span.name),
142
157
  kind: KIND_TO_OTLP[span.kind] || KIND_TO_OTLP.internal,
143
158
  startTimeUnixNano: span.startTimeUnixNano,
144
159
  endTimeUnixNano: span.endTimeUnixNano || span.startTimeUnixNano,
@@ -155,7 +170,7 @@ function _spanToOtlp(span) {
155
170
  droppedEventsCount: span.droppedEventsCount || 0,
156
171
  status: {
157
172
  code: STATUS_CODE_TO_OTLP[span.status && span.status.code] || 0,
158
- message: (span.status && span.status.message) || "",
173
+ message: _redactWireString("exception.message", (span.status && span.status.message) || ""),
159
174
  },
160
175
  };
161
176
  }
@@ -336,7 +351,7 @@ function _attrsToProto(attrs) {
336
351
  function _spanToProto(span) {
337
352
  // Status code: 0=Unset, 1=Ok, 2=Error. Status field 1 is reserved.
338
353
  var statusBody = Buffer.concat([
339
- pb.string(2, (span.status && span.status.message) || ""),
354
+ pb.string(2, _redactWireString("exception.message", (span.status && span.status.message) || "")),
340
355
  pb.uint32(3, STATUS_CODE_TO_OTLP[span.status && span.status.code] || 0),
341
356
  ]);
342
357
  var eventsRepeated = pb.repeatedMessage(11, span.events || [], function (e) {
@@ -352,7 +367,7 @@ function _spanToProto(span) {
352
367
  pb.bytes(2, _hexToBytes(span.spanId)),
353
368
  pb.string(3, ""), // trace_state (not yet propagated by the framework)
354
369
  pb.bytes(4, _hexToBytes(span.parentSpanId || "")),
355
- pb.string(5, span.name || ""),
370
+ pb.string(5, _redactWireString("otel.span.name", span.name || "")),
356
371
  pb.uint32(6, KIND_TEXT_TO_ENUM[span.kind] != null ? KIND_TEXT_TO_ENUM[span.kind] : KIND_TEXT_TO_ENUM.internal),
357
372
  pb.fixed64(7, span.startTimeUnixNano || 0),
358
373
  pb.fixed64(8, span.endTimeUnixNano || span.startTimeUnixNano || 0), // proto field number 8, not bytes
@@ -648,6 +663,7 @@ module.exports = {
648
663
  OtlpExporterError: OtlpExporterError,
649
664
  // Exported for tests
650
665
  _spanToOtlp: _spanToOtlp,
666
+ _spanToProto: _spanToProto,
651
667
  _bundleSpans: _bundleSpans,
652
668
  _attrToOtlp: _attrToOtlp,
653
669
  _BASE64URL_RE_REF: safeBuffer.BASE64URL_RE, // not used; reserved for OTLP/protobuf shape upgrade
@@ -375,11 +375,18 @@ function create(opts) {
375
375
  { name: "last_error", type: "TEXT" },
376
376
  { name: "status", type: "VARCHAR(16)", notNull: true, default: "pending" },
377
377
  ], { dialect: dialect }), dialect);
378
- // Partial index on the pending pool (the publisher's claim path scans
379
- // status='pending' ORDER BY next_attempt_at). The 'pending' literal is
380
- // a builder-emitted static predicate, opted in via allowLiterals.
378
+ // Index for the publisher's claim path (scans status='pending' ORDER BY
379
+ // next_attempt_at). sqlite/postgres support a partial index (WHERE on
380
+ // CREATE INDEX) on next_attempt_at; MySQL does NOT — a WHERE there is a
381
+ // syntax error that made declareSchema() throw on MySQL — so fall back to a
382
+ // composite (status, next_attempt_at) index, which serves the same
383
+ // equality+range scan. The 'pending' literal is a builder-emitted static
384
+ // predicate, opted in via allowLiterals.
385
+ var idxCols = dialect === "mysql" ? ["status", "next_attempt_at"] : ["next_attempt_at"];
386
+ var idxOpts = { dialect: dialect };
387
+ if (dialect !== "mysql") idxOpts.where = "status = 'pending'";
381
388
  var idx = sql.toExternalSql(sql.createIndex(opts.table + "_pending_idx", opts.table,
382
- ["next_attempt_at"], { dialect: dialect, where: "status = 'pending'" }), dialect);
389
+ idxCols, idxOpts), dialect);
383
390
  await target.query(ddl.sql, ddl.params);
384
391
  await target.query(idx.sql, idx.params);
385
392
  // Back-compat: an outbox table created before the claimed_at column
@@ -174,7 +174,7 @@ function parse(input, opts) {
174
174
  }
175
175
  out += String.fromCodePoint(code);
176
176
  i = end + 1;
177
- } else if (BUILT_IN_ENTITIES[name] !== undefined) {
177
+ } else if (Object.prototype.hasOwnProperty.call(BUILT_IN_ENTITIES, name)) {
178
178
  out += BUILT_IN_ENTITIES[name];
179
179
  i = end + 1;
180
180
  } else {
@@ -771,9 +771,27 @@ function parse(input, opts) {
771
771
  }
772
772
 
773
773
  function _stripEolComment(text) {
774
- // Strip ` #...` comments (must be preceded by whitespace) at end of line.
775
- var match = text.match(/^(.*?)(\s+#.*)?$/);
776
- return safeBuffer.stripTrailingHspace(match && match[1] != null ? match[1] : text);
774
+ // Strip ` #...` comments (a YAML end-of-line comment must be preceded by
775
+ // whitespace) via a single linear scan. The previous /^(.*?)(\s+#.*)?$/
776
+ // backtracks polynomially on a long inline-whitespace run with no '#'
777
+ // (each position re-tries `\s+#`) — a ReDoS lever on attacker-supplied
778
+ // YAML. This finds the first whitespace-preceded '#' and cuts the
779
+ // preceding whitespace run, identical output without the catastrophic
780
+ // backtracking.
781
+ for (var i = 1; i < text.length; i++) {
782
+ if (text.charCodeAt(i) !== 0x23 /* # */) continue;
783
+ var prev = text.charCodeAt(i - 1);
784
+ // inline whitespace: space / tab / vtab / formfeed / CR
785
+ if (prev !== 0x20 && prev !== 0x09 && prev !== 0x0b && prev !== 0x0c && prev !== 0x0d) continue;
786
+ var end = i;
787
+ while (end > 0) {
788
+ var c = text.charCodeAt(end - 1);
789
+ if (c === 0x20 || c === 0x09 || c === 0x0b || c === 0x0c || c === 0x0d) end--;
790
+ else break;
791
+ }
792
+ return safeBuffer.stripTrailingHspace(text.slice(0, end));
793
+ }
794
+ return safeBuffer.stripTrailingHspace(text);
777
795
  }
778
796
 
779
797
  // ---- Block scalars (| literal, > folded) ----
@@ -406,7 +406,13 @@ function create(config) {
406
406
  .where("_id", jobId)
407
407
  .where("status", "inflight")
408
408
  .toSql();
409
- await store.execute(doneBuilt.sql, doneBuilt.params);
409
+ var doneRes = await store.execute(doneBuilt.sql, doneBuilt.params);
410
+ // Only run the post-completion side effects if THIS call actually flipped
411
+ // the row inflight→done. If the status guard matched 0 rows the job was
412
+ // already completed or re-leased to another worker (its lease expired and
413
+ // sweepExpired re-queued it) — a stale completer must NOT re-enqueue the
414
+ // cron repeat (duplicate firing) or release flow children twice.
415
+ if ((doneRes.rowCount || 0) === 0) return false;
410
416
 
411
417
  // Repeat-in-queue: cron-recurring job re-enqueues itself for the
412
418
  // next firing time. Failures (which take the fail() path) don't
@@ -513,9 +519,10 @@ function create(config) {
513
519
  [nowMs + retryDelayMs])
514
520
  .setRaw("finishedAt", "CASE WHEN " + attemptsLt + " THEN NULL ELSE ? END", [nowMs])
515
521
  .where("_id", jobId)
522
+ .where("status", "inflight") // lease-ownership guard — a stale fail() must not clobber a job re-leased to another worker after this one's lease expired (mirrors complete()/extendLease)
516
523
  .toSql();
517
- await store.execute(failBuilt.sql, failBuilt.params);
518
- return true;
524
+ var failRes = await store.execute(failBuilt.sql, failBuilt.params);
525
+ return (failRes.rowCount || 0) > 0;
519
526
  }
520
527
 
521
528
  async function sweepExpired() {
@@ -278,12 +278,16 @@ function redact(value, opts) {
278
278
  function _redact(value, depth, maxDepth, marker, parentKey) {
279
279
  if (depth > maxDepth) return marker;
280
280
  if (value === null || value === undefined) return value;
281
+ // A sensitive parent key collapses the ENTIRE value — scalar OR composite —
282
+ // to the marker. Checking before the type branches is what stops a secret
283
+ // under e.g. `authorization: ["Bearer …"]` / `password: {…}` from slipping
284
+ // through the array/object branches (which recurse with parentKey=null), the
285
+ // way a scalar already does (CWE-532 telemetry egress).
286
+ if (parentKey && _isSensitiveFieldName(parentKey)) return marker;
281
287
  if (typeof value === "string") {
282
- if (parentKey && _isSensitiveFieldName(parentKey)) return marker;
283
288
  return _redactValue(value);
284
289
  }
285
290
  if (typeof value === "number" || typeof value === "boolean") {
286
- if (parentKey && _isSensitiveFieldName(parentKey)) return marker;
287
291
  return value;
288
292
  }
289
293
  if (Buffer.isBuffer(value) || value instanceof Uint8Array) {
@@ -513,7 +517,7 @@ function classifyDefaults(opts) {
513
517
  "redact.classifyDefaults: patterns[" + p + "] must be a string, got " +
514
518
  typeof patterns[p]);
515
519
  }
516
- if (!CLASSIFIER_PATTERNS[patterns[p]] &&
520
+ if (!Object.prototype.hasOwnProperty.call(CLASSIFIER_PATTERNS, patterns[p]) &&
517
521
  !(opts.extra && opts.extra[patterns[p]])) {
518
522
  throw new DlpError("redact-dlp/unknown-pattern",
519
523
  "redact.classifyDefaults: unknown pattern '" + patterns[p] +