@blamejs/blamejs-shop 0.4.31 → 0.4.32

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 (336) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +392 -278
  4. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  5. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  6. package/lib/vendor/blamejs/.gitignore +6 -0
  7. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  8. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  9. package/lib/vendor/blamejs/README.md +8 -6
  10. package/lib/vendor/blamejs/SECURITY.md +19 -3
  11. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  12. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  13. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  14. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  15. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  16. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  17. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  18. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  19. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  20. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  21. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  22. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  23. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  24. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  25. package/lib/vendor/blamejs/index.js +4 -0
  26. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  27. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  28. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  29. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  30. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  31. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  32. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  33. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  34. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  35. package/lib/vendor/blamejs/lib/audit.js +259 -123
  36. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
  37. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  38. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  39. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
  40. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  41. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  42. package/lib/vendor/blamejs/lib/cache.js +174 -105
  43. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  44. package/lib/vendor/blamejs/lib/cli.js +19 -14
  45. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  46. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  47. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  48. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  49. package/lib/vendor/blamejs/lib/compliance.js +206 -4
  50. package/lib/vendor/blamejs/lib/consent.js +82 -29
  51. package/lib/vendor/blamejs/lib/constants.js +27 -11
  52. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  53. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  54. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  55. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  56. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  57. package/lib/vendor/blamejs/lib/db.js +249 -99
  58. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  59. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  60. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  61. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  62. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  63. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  64. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  65. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  66. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  67. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  68. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  69. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  70. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  71. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  72. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  73. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  74. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  75. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  76. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  77. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  78. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  79. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  80. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  81. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  82. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  83. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  84. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  85. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  86. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  87. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  88. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  89. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  90. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  91. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  92. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  93. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  94. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  95. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  96. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  97. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  98. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  99. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  100. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  101. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  102. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  103. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  104. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  106. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  107. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  108. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  109. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  110. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  111. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  112. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  113. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  114. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  115. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  116. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  117. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  118. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  119. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  120. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  121. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  122. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  123. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  124. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  125. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  126. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  128. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  129. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  131. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  132. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  133. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  134. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  135. package/lib/vendor/blamejs/lib/mail.js +8 -4
  136. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  137. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  138. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  139. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  140. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  141. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  142. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  143. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  144. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  145. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  146. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  147. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  148. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  149. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  150. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  151. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  152. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  153. package/lib/vendor/blamejs/lib/observability.js +124 -0
  154. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  155. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  156. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  157. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  158. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  159. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  160. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  161. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  162. package/lib/vendor/blamejs/lib/queue.js +7 -0
  163. package/lib/vendor/blamejs/lib/redact.js +68 -11
  164. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  165. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  166. package/lib/vendor/blamejs/lib/retention.js +101 -40
  167. package/lib/vendor/blamejs/lib/router.js +212 -5
  168. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  169. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  170. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  171. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  172. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  173. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  174. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  175. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  176. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  177. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  178. package/lib/vendor/blamejs/lib/session.js +175 -77
  179. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  180. package/lib/vendor/blamejs/lib/sse.js +26 -0
  181. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  182. package/lib/vendor/blamejs/lib/static.js +177 -34
  183. package/lib/vendor/blamejs/lib/subject.js +96 -49
  184. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  185. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  186. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  187. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  188. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  189. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  190. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  191. package/lib/vendor/blamejs/package.json +2 -2
  192. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  193. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  194. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  200. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  201. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  202. package/lib/vendor/blamejs/scripts/release.js +398 -38
  203. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  204. package/lib/vendor/blamejs/test/10-state.js +140 -14
  205. package/lib/vendor/blamejs/test/20-db.js +65 -2
  206. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  207. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  208. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  209. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  210. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  211. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  212. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  213. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  214. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  215. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  220. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  221. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  222. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  223. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  224. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  225. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  226. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  227. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  228. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  229. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  230. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  231. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  232. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  233. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  234. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  235. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  236. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  237. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  238. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  240. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  248. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  249. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  250. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  251. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  256. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  258. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  270. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  271. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  272. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  273. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  277. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  278. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  291. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  302. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  308. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  310. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  311. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  312. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  313. package/lib/vendor/blamejs/test/smoke.js +79 -21
  314. package/package.json +1 -1
  315. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  316. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  317. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  318. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  319. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  320. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  321. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  322. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  323. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  324. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  325. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  326. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  327. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  328. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  329. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  330. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  331. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  332. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  334. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  335. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  336. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -1944,15 +1944,19 @@ module.exports = {
1944
1944
  // default, ed25519-sha256 opt-in). Wire it into the smtp transport
1945
1945
  // via opts.dkimSigner. See lib/mail-dkim.js for the full surface.
1946
1946
  dkim: dkim,
1947
- // Inbound mail authentication-results verification: SPF (RFC 7208),
1948
- // DMARC (RFC 7489), ARC (RFC 8617). Outbound DKIM signing lives in
1949
- // .dkim above; per-hop DKIM verification is deferred (composes with
1950
- // the existing canonicalization helpers in lib/mail-dkim.js).
1947
+ // Inbound mail authentication verification: SPF (RFC 7208), DKIM
1948
+ // verify (RFC 6376, on .dkim above alongside outbound signing),
1949
+ // DMARC (RFC 7489), ARC (RFC 8617). `.inbound.verify` is the
1950
+ // one-call receiver pipeline SPF + DKIM + From-header extraction +
1951
+ // DMARC policy + the RFC 8601 Authentication-Results header —
1952
+ // composed by b.mail.server.mx at DATA time via its guardEnvelope
1953
+ // opt and callable directly by operator-built listeners.
1951
1954
  spf: mailAuth.spf,
1952
1955
  dmarc: mailAuth.dmarc,
1953
1956
  arc: mailAuth.arc,
1954
1957
  iprev: mailAuth.iprev,
1955
1958
  authResults: mailAuth.authResults,
1959
+ inbound: mailAuth.inbound,
1956
1960
  bimi: mailBimi,
1957
1961
  // Test-only export: lets unit tests inspect the wire format without
1958
1962
  // standing up a TLS-capable SMTP fixture. Operators don't call this.
@@ -166,6 +166,29 @@ var BodyParserError = defineClass("BodyParserError", { withStatusCode: true });
166
166
  // in play — consistent prototype-pollution defense across the framework.
167
167
  var POISONED_KEYS = new Set(["__proto__", "constructor", "prototype"]);
168
168
 
169
+ // Materialize a header/parameter map from request-derived [key, value]
170
+ // pairs WITHOUT a computed member write (`target[key] = value`). A
171
+ // request-keyed computed write is the CWE-915 unsafe-reflection /
172
+ // CWE-1321 prototype-pollution sink: an attacker who controls the key
173
+ // (Content-Type parameter name, multipart part-header name,
174
+ // Content-Disposition parameter name) can target `__proto__` /
175
+ // `constructor` / `prototype` and corrupt the prototype chain. Poisoned
176
+ // keys are dropped, the remaining pairs are funneled through
177
+ // `Object.fromEntries`, and the result carries no prototype chain
178
+ // (`Object.create(null)`) so even a key that slipped a future POISONED_KEYS
179
+ // gap cannot reach Object.prototype. The returned map has plain-object
180
+ // shape (string keys → values) so existing named-property reads
181
+ // (`.boundary`, `.charset`, `["content-disposition"]`, `.name`,
182
+ // `.filename`) are unchanged.
183
+ function _mapFromPairs(pairs) {
184
+ var safe = [];
185
+ for (var i = 0; i < pairs.length; i++) {
186
+ if (POISONED_KEYS.has(pairs[i][0])) continue;
187
+ safe.push(pairs[i]);
188
+ }
189
+ return Object.assign(Object.create(null), Object.fromEntries(safe));
190
+ }
191
+
169
192
  // ---- defaults ----
170
193
 
171
194
  var DEFAULTS = Object.freeze({
@@ -221,7 +244,11 @@ function _contentType(req) {
221
244
  if (typeof ct !== "string") return { type: "", params: {} };
222
245
  var idx = ct.indexOf(";");
223
246
  var type = (idx === -1 ? ct : ct.slice(0, idx)).trim().toLowerCase();
224
- var params = {};
247
+ // Collect [name, value] pairs, then materialize via _mapFromPairs so a
248
+ // request-controlled parameter name (e.g. `boundary` / `charset` / an
249
+ // attacker-supplied `__proto__`) is never used as a computed-write key
250
+ // (CWE-915 / CWE-1321). Poisoned names are dropped at materialization.
251
+ var paramPairs = [];
225
252
  if (idx !== -1) {
226
253
  var rest = ct.slice(idx + 1);
227
254
  // RFC 9110 §8.3 + §5.6.6 — parameter values may be quoted-string
@@ -238,10 +265,10 @@ function _contentType(req) {
238
265
  var v = p.slice(eq + 1).trim();
239
266
  var _unq = structuredFields.unquoteSfString(v);
240
267
  if (_unq !== null) v = _unq;
241
- params[k] = v;
268
+ paramPairs.push([k, v]);
242
269
  }
243
270
  }
244
- return { type: type, params: params };
271
+ return { type: type, params: _mapFromPairs(paramPairs) };
245
272
  }
246
273
 
247
274
  function _typeMatches(actual, allowed) {
@@ -583,7 +610,13 @@ function _parseMultipartHeaders(rawHeaders) {
583
610
  // §5.5 — header field values MUST NOT contain CR, LF, or NUL bytes.
584
611
  // We refuse the part outright (caller surfaces the throw as 400 + drop).
585
612
  var lines = rawHeaders.split("\r\n");
586
- var out = {};
613
+ // Collect [name, value] pairs; materialize via _mapFromPairs so the
614
+ // request-controlled header name is never a computed-write key
615
+ // (CWE-915 / CWE-1321 — a part header literally named `__proto__` would
616
+ // otherwise pollute the prototype chain). Later headers of the same
617
+ // name keep last-wins (the prior `out[k] = v` overwrite semantics:
618
+ // Object.fromEntries takes the last pair for a duplicate key).
619
+ var headerPairs = [];
587
620
  for (var i = 0; i < lines.length; i++) {
588
621
  var line = lines[i];
589
622
  if (!line) continue;
@@ -609,9 +642,9 @@ function _parseMultipartHeaders(rawHeaders) {
609
642
  );
610
643
  }
611
644
  }
612
- out[k] = v;
645
+ headerPairs.push([k, v]);
613
646
  }
614
- return out;
647
+ return _mapFromPairs(headerPairs);
615
648
  }
616
649
 
617
650
  // Percent-decode an RFC 5987 ext-value's value segment under iso-8859-1.
@@ -672,14 +705,20 @@ function _parseHeaderParams(headerValue, filenameCharsets) {
672
705
  // is present, it takes precedence over the legacy `filename=`
673
706
  // companion (RFC 6266 §4.3). We surface the decoded value at
674
707
  // `filename` so downstream consumers don't need parser-aware code.
675
- var out = { _value: "" };
676
- if (!headerValue) return out;
708
+ if (!headerValue) return _mapFromPairs([["_value", ""]]);
677
709
  // RFC 6266 §4.1 + RFC 9110 §5.6.6 — parameter values may be
678
710
  // quoted-string (e.g. `filename="weird;name.txt"`). Bare
679
711
  // `.split(";")` would slice through the quoted semicolon and
680
712
  // corrupt the filename. Quote-aware shared splitter.
681
713
  var parts = structuredFields.splitTopLevel(headerValue, ";");
682
- out._value = parts[0].trim().toLowerCase();
714
+ // Collect [name, value] pairs, then materialize via _mapFromPairs so a
715
+ // request-controlled Content-Disposition parameter name (or its
716
+ // ext-value `name*` bare form) is never a computed-write key
717
+ // (CWE-915 / CWE-1321). `_value` carries the disposition type;
718
+ // `filename` (when an ext-value decoded) takes precedence over the
719
+ // legacy `filename=` companion (RFC 6266 §4.3), preserved by appending
720
+ // it last so Object.fromEntries' last-wins resolves it.
721
+ var paramPairs = [["_value", parts[0].trim().toLowerCase()]];
683
722
  var extName = null;
684
723
  for (var i = 1; i < parts.length; i++) {
685
724
  var p = parts[i].trim();
@@ -694,14 +733,14 @@ function _parseHeaderParams(headerValue, filenameCharsets) {
694
733
  if (decoded !== null) {
695
734
  var bareKey = k.slice(0, -1);
696
735
  if (bareKey === "filename") extName = decoded;
697
- out[bareKey] = decoded;
736
+ paramPairs.push([bareKey, decoded]);
698
737
  }
699
738
  continue;
700
739
  }
701
- out[k] = v;
740
+ paramPairs.push([k, v]);
702
741
  }
703
- if (extName !== null) out.filename = extName;
704
- return out;
742
+ if (extName !== null) paramPairs.push(["filename", extName]);
743
+ return _mapFromPairs(paramPairs);
705
744
  }
706
745
 
707
746
  async function _parseMultipart(req, opts, ctParams) {
@@ -1173,20 +1212,27 @@ async function _parseMultipart(req, opts, ctParams) {
1173
1212
  var fbuf = Buffer.concat(currentBuf);
1174
1213
  var text = fbuf.toString("utf8");
1175
1214
  // Repeated field name → array, matching urlencoded parser.
1176
- if (Object.prototype.hasOwnProperty.call(fields, currentField)) {
1177
- // lgtm[js/remote-property-injection] `currentField` is gated
1178
- // upstream at lib/middleware/body-parser.js:867 by
1179
- // POISONED_KEYS (__proto__ / constructor / prototype) which
1180
- // refuses the multipart part with a 400 BodyParserError before
1181
- // `currentField` is ever assigned. Reachable values cannot
1182
- // pollute the prototype chain.
1183
- if (Array.isArray(fields[currentField])) fields[currentField].push(text);
1184
- else fields[currentField] = [fields[currentField], text];
1215
+ // `currentField` is request-controlled, so the accumulation
1216
+ // never uses it as a computed-write key (`fields[key] = v`),
1217
+ // which is the CWE-915 / CWE-1321 sink: it is merged through
1218
+ // Object.fromEntries + Object.assign instead. The upstream
1219
+ // POISONED_KEYS gate (the multipart-poisoned-field check above)
1220
+ // already rejects __proto__ / constructor / prototype field
1221
+ // names with a 400 before reaching here; the entries-merge is
1222
+ // the structural backstop.
1223
+ var fieldName = currentField;
1224
+ var prior = Object.prototype.hasOwnProperty.call(fields, fieldName)
1225
+ ? fields[fieldName] : undefined;
1226
+ var nextValue;
1227
+ if (prior === undefined) {
1228
+ nextValue = text;
1229
+ } else if (Array.isArray(prior)) {
1230
+ prior.push(text);
1231
+ nextValue = prior;
1185
1232
  } else {
1186
- // lgtm[js/remote-property-injection] — see upstream POISONED_KEYS
1187
- // gate at lib/middleware/body-parser.js:867.
1188
- fields[currentField] = text;
1233
+ nextValue = [prior, text];
1189
1234
  }
1235
+ Object.assign(fields, Object.fromEntries([[fieldName, nextValue]]));
1190
1236
  }
1191
1237
  currentHeaders = null;
1192
1238
  currentField = null;
@@ -91,25 +91,36 @@ function _parseCookieHeader(header) {
91
91
  // just splits the name=value pairs. Keys that appear multiple times
92
92
  // resolve to the FIRST occurrence (browsers send pairs left-to-right
93
93
  // by registration order; the first is the most-specific path).
94
- // Output object has no prototype chain `Object.create(null)` defends
95
- // against `__proto__` / `constructor` / `prototype` cookie-name keys
96
- // polluting the prototype before the hasOwnProperty gate runs.
97
- var out = Object.create(null);
98
- if (typeof header !== "string" || header.length === 0) return out;
94
+ // Collect [name, value] pairs, then materialize the cookie map via
95
+ // Object.fromEntries onto a null-prototype object. The cookie name is
96
+ // attacker-controlled (Cookie request header), so it is never used as a
97
+ // computed-write key (`out[name] = value` / `seen[name] = true`) — that
98
+ // is the CWE-915 unsafe-reflection / CWE-1321 prototype-pollution sink.
99
+ // First-occurrence-wins de-duplication tracks names in a Set (add/has
100
+ // are method calls, not tainted-key property writes); POISONED names
101
+ // (`__proto__` / `constructor` / `prototype`) are dropped; and the
102
+ // null-prototype accumulator means even a slipped name cannot reach
103
+ // Object.prototype.
104
+ if (typeof header !== "string" || header.length === 0) return Object.create(null);
99
105
  var parts = header.split(/;\s*/);
106
+ var seen = new Set();
107
+ var pairs = [];
100
108
  for (var i = 0; i < parts.length; i++) {
101
109
  var p = parts[i];
102
110
  var eq = p.indexOf("=");
103
111
  if (eq === -1) continue;
104
112
  var k = p.slice(0, eq).trim();
105
- if (k.length === 0 || Object.prototype.hasOwnProperty.call(out, k)) continue;
113
+ if (k.length === 0) continue;
114
+ if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
115
+ if (seen.has(k)) continue; // first-occurrence wins
116
+ seen.add(k);
106
117
  var v = p.slice(eq + 1).trim();
107
118
  if (v.length >= 2 && v.charCodeAt(0) === 0x22 && v.charCodeAt(v.length - 1) === 0x22) {
108
119
  v = v.slice(1, -1);
109
120
  }
110
- out[k] = v;
121
+ pairs.push([k, v]);
111
122
  }
112
- return out;
123
+ return Object.assign(Object.create(null), Object.fromEntries(pairs));
113
124
  }
114
125
 
115
126
  // `_isHttps` defers to `requestHelpers.requestProtocol` so the
@@ -239,6 +239,15 @@ function create(opts) {
239
239
  var auditOn = opts.audit !== false;
240
240
  var algorithms = opts.algorithms;
241
241
  var iatWindowSec = opts.iatWindowSec;
242
+ // replayStore is the jti-replay defense (RFC 9449 §11.1) — REQUIRED. Reading
243
+ // it optionally and gating the check behind `if (replayStore)` would silently
244
+ // mount a proof-of-possession gate that performs no replay check, letting a
245
+ // captured proof replay indefinitely. Fail closed at config time: a missing
246
+ // store and a store lacking checkAndInsert both throw here, not at the first
247
+ // request. (The low-level b.auth.dpop.verify primitive keeps replayStore
248
+ // optional for advanced callers that track jti themselves.)
249
+ validateOpts.requireMethods(opts.replayStore, ["checkAndInsert"],
250
+ "middleware.dpop: opts.replayStore", AuthError, "auth-dpop/replay-store-required");
242
251
  var replayStore = opts.replayStore;
243
252
  var requireNonce = opts.requireNonce === true;
244
253
 
@@ -328,7 +337,7 @@ function create(opts) {
328
337
  if (iatWindowSec !== undefined) verifyOpts.iatWindowSec = iatWindowSec;
329
338
  if (accessToken) verifyOpts.accessToken = accessToken;
330
339
  if (nonce) verifyOpts.nonce = nonce;
331
- if (replayStore) verifyOpts.replayStore = replayStore;
340
+ verifyOpts.replayStore = replayStore; // required at create() — always present
332
341
 
333
342
  var result;
334
343
  try { result = await dpop().verify(proofHeader, verifyOpts); }
@@ -125,11 +125,13 @@ function _writeReject(req, res, message, reason, onDeny, problemMode) {
125
125
  * destination list, including `webidentity` (FedCM credentialed
126
126
  * requests). `deniedDest` refuses chosen destinations outright on the
127
127
  * gated methods — a FedCM `webidentity` Sec-Fetch-Dest hitting a route
128
- * that is not an identity endpoint is refused. `allowStorageAccess:
129
- * false` refuses the Storage Access API escalation (a cross-site request
130
- * carrying `Sec-Fetch-Storage-Access: active` / `inactive`) on routes
131
- * that do not participate in the Storage Access flow. Both are opt-in;
132
- * leaving them unset preserves the prior behavior exactly.
128
+ * that is not an identity endpoint is refused. The Storage Access API
129
+ * escalation (a cross-site request carrying `Sec-Fetch-Storage-Access:
130
+ * active` / `inactive`) is REFUSED BY DEFAULT (v0.15.0) on routes that do
131
+ * not participate in the Storage Access flow; operators running an
132
+ * embedded-iframe SaaS that legitimately uses the API opt back in with
133
+ * `allowStorageAccess: true`. `deniedDest` stays opt-in (unset = no
134
+ * destination is denied outright).
133
135
  *
134
136
  * @opts
135
137
  * {
@@ -138,7 +140,7 @@ function _writeReject(req, res, message, reason, onDeny, problemMode) {
138
140
  * allowMissing: boolean, // default true
139
141
  * allowedDest: string[], // cross-site allowlist of Sec-Fetch-Dest values
140
142
  * deniedDest: string[], // Sec-Fetch-Dest values refused on gated methods regardless of site (e.g. ["webidentity"])
141
- * allowStorageAccess: boolean, // default truefalse refuses Sec-Fetch-Storage-Access: active|inactive
143
+ * allowStorageAccess: boolean, // default false — refuses Sec-Fetch-Storage-Access: active|inactive; pass true to opt back in for Storage-Access-flow routes
142
144
  * strictDest: boolean, // default false — true throws at config time on an allowedDest/deniedDest value outside the known Sec-Fetch-Dest vocabulary
143
145
  * allowedNavigate: boolean, // default true
144
146
  * methods: string[], // default POST/PUT/DELETE/PATCH
@@ -178,7 +180,15 @@ function create(opts) {
178
180
  var allowCrossSite = opts.allowCrossSite === true;
179
181
  var allowMissing = opts.allowMissing !== false;
180
182
  var allowedDest = Array.isArray(opts.allowedDest) ? opts.allowedDest.slice() : null;
181
- var allowStorageAccess = opts.allowStorageAccess !== false;
183
+ // Storage Access escalation default-deny (v0.15.0): a cross-site
184
+ // credentialed request carrying Sec-Fetch-Storage-Access: active|inactive
185
+ // is REFUSED by default on the gated methods, because that header signals
186
+ // the embedded context can reach unpartitioned cross-site cookies — a
187
+ // capability a route that does not participate in the Storage Access flow
188
+ // should not silently honor. Operators running an embedded-iframe SaaS
189
+ // that legitimately uses the Storage Access API opt back in with
190
+ // allowStorageAccess: true.
191
+ var allowStorageAccess = opts.allowStorageAccess === true;
182
192
  // deniedDest → a null-prototype membership map; an operator-supplied
183
193
  // destination string is never assigned onto a plain object, so no
184
194
  // reserved name (__proto__ / constructor / prototype) can pollute it.
@@ -47,6 +47,7 @@ var validateOpts = require("../validate-opts");
47
47
  var safeBuffer = require("../safe-buffer");
48
48
  var safeJson = require("../safe-json");
49
49
  var safeSql = require("../safe-sql");
50
+ var sql = require("../sql");
50
51
  var bCrypto = require("../crypto");
51
52
  var cryptoField = require("../crypto-field");
52
53
  var vault = require("../vault");
@@ -250,17 +251,23 @@ function dbStore(opts) {
250
251
  "dbStore: opts.db must be a sqlite-shaped database with a `prepare(sql)` method", true);
251
252
  }
252
253
  var tableNameRaw = opts.tableName !== undefined ? opts.tableName : "blamejs_idempotency_keys";
253
- // Quote-and-validate via safeSql.quoteIdentifier runs
254
- // validateIdentifier internally + emits the dialect-correct quoted
255
- // form. Identifier always reaches SQL through the quoted form.
256
- var qTable;
257
- try { qTable = safeSql.quoteIdentifier(tableNameRaw, "sqlite"); }
254
+ // Validate the operator-supplied table name up front so a bad
255
+ // identifier fails at construction with the stable
256
+ // idempotency/bad-table-name code (b.sql would otherwise raise its own
257
+ // SqlBuilderError deeper in the first build). b.sql then quotes the
258
+ // name by construction in every statement it emits for this store
259
+ // (quoteName:true — this is a direct sqlite handle, not a
260
+ // clusterStorage rewrite target, so the name is quoted, not left bare).
261
+ try { safeSql.validateIdentifier(tableNameRaw, { allowReserved: true }); }
258
262
  catch (sqlErr) {
259
263
  throw new IdempotencyError("idempotency/bad-table-name",
260
264
  "dbStore: opts.tableName is not a valid SQL identifier: " +
261
265
  (sqlErr && sqlErr.message ? sqlErr.message : String(sqlErr)), true);
262
266
  }
263
- var qIndex = safeSql.quoteIdentifier(tableNameRaw + "_expires_idx", "sqlite");
267
+ // b.sql opts for every statement this store builds against the local
268
+ // sqlite handle: sqlite dialect (native `?` placeholders, double-quoted
269
+ // identifiers) + quoteName so the operator table name is emitted quoted.
270
+ var sqlOpts = { dialect: "sqlite", quoteName: true };
264
271
  var doInit = opts.init !== false;
265
272
  var hashKeys = opts.hashKeys !== false;
266
273
  var sealReq = opts.seal !== false;
@@ -309,63 +316,79 @@ function dbStore(opts) {
309
316
  });
310
317
  }
311
318
 
312
- // Derive a per-vault HMAC secret for fingerprint sealing.
313
- // The vault root key is the trust root; without it the secret is
314
- // unrecoverable. Lazy: only derived when fpSealOn is enabled AND the
315
- // vault is ready, so test fixtures that haven't initialized the
316
- // vault still construct a dbStore (the fingerprint then falls back
317
- // to bare sha3-256 with a single audit warning).
319
+ // Derive a per-vault HMAC secret for fingerprint sealing. Seed off the
320
+ // SEALED per-deployment MAC key (vault.getDerivedHashMacKey, sealed at
321
+ // rest under the vault root) NOT getDerivedHashSalt, which sits in
322
+ // PLAINTEXT on disk. With the salt-derived seed an attacker who read
323
+ // the disk could recompute the HMAC key and forge / correlate request
324
+ // fingerprints; the sealed MAC key closes that (the vault root is the
325
+ // trust root, so the secret is unrecoverable without it). Lazy: only
326
+ // derived when fpSealOn is enabled AND the vault is ready, so test
327
+ // fixtures that haven't initialized the vault still construct a
328
+ // dbStore (the fingerprint then falls back to bare sha3-256 with a
329
+ // single audit warning).
318
330
  var fpHmacSecret = null;
319
331
  if (fpSealOn) {
320
332
  try {
321
- // Use vault.aad.buildContextAad as a stable derivation input;
322
- // the derivedHashSalt is per-deployment so the same dbStore
323
- // instance across hosts converges on the same HMAC key.
324
- var fpDeriveInput = "idempotency.fingerprint:" + tableNameRaw + ":" +
325
- vault.getDerivedHashSalt().toString("hex");
326
- fpHmacSecret = bCrypto.kdf(Buffer.from(fpDeriveInput, "utf8"), C.BYTES.bytes(32));
333
+ // The MAC key is per-deployment + sealed, so the same dbStore
334
+ // instance across hosts converges on the same HMAC key while disk
335
+ // access alone cannot recover it. The table name domain-separates
336
+ // the fingerprint secret from other consumers of the MAC key.
337
+ var fpDeriveInput = Buffer.concat([
338
+ vault.getDerivedHashMacKey(),
339
+ Buffer.from("idempotency.fingerprint:" + tableNameRaw, "utf8"),
340
+ ]);
341
+ fpHmacSecret = bCrypto.kdf(fpDeriveInput, C.BYTES.bytes(32));
327
342
  } catch (_fpErr) {
328
343
  _emitAudit("idempotency.fingerprint_seal_skipped_no_vault",
329
344
  { tableName: tableNameRaw,
330
- reason: "vault.getDerivedHashSalt() unavailable; fingerprint falls back to plain sha3-256" },
345
+ reason: "vault.getDerivedHashMacKey() unavailable; fingerprint falls back to plain sha3-256" },
331
346
  "warning");
332
347
  fpHmacSecret = null;
333
348
  }
334
349
  }
335
350
 
336
351
  if (doInit) {
337
- db.prepare("CREATE TABLE IF NOT EXISTS " + qTable + " (" +
338
- "k TEXT PRIMARY KEY, " +
339
- "fingerprint TEXT NOT NULL, " +
340
- "status_code INTEGER NOT NULL, " +
341
- "headers TEXT NOT NULL, " +
342
- "body TEXT NOT NULL, " +
343
- "expires_at INTEGER NOT NULL)").run();
344
- db.prepare("CREATE INDEX IF NOT EXISTS " + qIndex + " ON " +
345
- qTable + "(expires_at)").run();
352
+ db.prepare(sql.createTable(tableNameRaw, [
353
+ { name: "k", type: "text", primaryKey: true },
354
+ { name: "fingerprint", type: "text", notNull: true },
355
+ { name: "status_code", type: "int", notNull: true },
356
+ { name: "headers", type: "text", notNull: true },
357
+ { name: "body", type: "text", notNull: true },
358
+ { name: "expires_at", type: "int", notNull: true },
359
+ ], sqlOpts).sql).run();
360
+ db.prepare(sql.createIndex(tableNameRaw + "_expires_idx", tableNameRaw,
361
+ ["expires_at"], sqlOpts).sql).run();
346
362
  }
347
363
 
348
- // Prepared statements. status_code + expires_at stay non-sealed
349
- // so audit/forensic SELECTs don't have to unseal-everything. The
350
- // `k` column is selected even when not strictly needed for read
351
- // because cryptoField.unsealRow uses it as the rowId in AAD when
352
- // the table is AAD-bound.
353
- var stmtGet = db.prepare(
354
- "SELECT k, fingerprint, status_code, headers, body, expires_at FROM " +
355
- qTable + " WHERE k = ?");
356
- var stmtUpsert = db.prepare(
357
- "INSERT INTO " + qTable +
358
- "(k, fingerprint, status_code, headers, body, expires_at) " +
359
- "VALUES (?, ?, ?, ?, ?, ?) " +
360
- "ON CONFLICT(k) DO UPDATE SET " +
361
- " fingerprint = excluded.fingerprint, " +
362
- " status_code = excluded.status_code, " +
363
- " headers = excluded.headers, " +
364
- " body = excluded.body, " +
365
- " expires_at = excluded.expires_at");
366
- var stmtDeleteStale = db.prepare("DELETE FROM " + qTable +
367
- " WHERE k = ? AND expires_at <= ?");
368
- var stmtDelete = db.prepare("DELETE FROM " + qTable + " WHERE k = ?");
364
+ // Prepared statements, composed once through b.sql and reused per call.
365
+ // b.sql binds concrete values into a params array; for a reusable
366
+ // prepared statement we keep only the emitted SQL text (its `?`
367
+ // placeholders) and bind fresh values at run time, so a build-time
368
+ // sentinel value is just a placeholder slot. status_code + expires_at
369
+ // stay non-sealed so audit/forensic SELECTs don't have to unseal-
370
+ // everything. The `k` column is selected even when not strictly needed
371
+ // for read because cryptoField.unsealRow uses it as the rowId in AAD
372
+ // when the table is AAD-bound.
373
+ var _slot = 0; // sentinel bind value; the prepared statement rebinds at call time
374
+ var stmtGet = db.prepare(sql.select(tableNameRaw, sqlOpts)
375
+ .columns(["k", "fingerprint", "status_code", "headers", "body", "expires_at"])
376
+ .where("k", _slot)
377
+ .toSql().sql);
378
+ var stmtUpsert = db.prepare(sql.upsert(tableNameRaw, sqlOpts)
379
+ .columns(["k", "fingerprint", "status_code", "headers", "body", "expires_at"])
380
+ .values({ k: _slot, fingerprint: _slot, status_code: _slot,
381
+ headers: _slot, body: _slot, expires_at: _slot })
382
+ .onConflict(["k"])
383
+ .doUpdateFromExcluded(["fingerprint", "status_code", "headers", "body", "expires_at"])
384
+ .toSql().sql);
385
+ var stmtDeleteStale = db.prepare(sql.delete(tableNameRaw, sqlOpts)
386
+ .where("k", _slot)
387
+ .where("expires_at", "<=", _slot)
388
+ .toSql().sql);
389
+ var stmtDelete = db.prepare(sql.delete(tableNameRaw, sqlOpts)
390
+ .where("k", _slot)
391
+ .toSql().sql);
369
392
 
370
393
  function _k(rawKey) {
371
394
  if (!hashKeys) return rawKey;
@@ -476,8 +499,9 @@ function dbStore(opts) {
476
499
  }
477
500
  var migrated = 0;
478
501
  var skipped = 0;
479
- var rows = db.prepare("SELECT k, fingerprint, status_code, headers, body, expires_at FROM " +
480
- qTable).all();
502
+ var rows = db.prepare(sql.select(tableNameRaw, sqlOpts)
503
+ .columns(["k", "fingerprint", "status_code", "headers", "body", "expires_at"])
504
+ .toSql().sql).all();
481
505
  for (var i = 0; i < rows.length; i += 1) {
482
506
  var r = rows[i];
483
507
  // If headers/body already start with vault.aad: this row is