@blamejs/blamejs-shop 0.4.30 → 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 (338) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/checkout.js +8 -0
  4. package/lib/order.js +71 -11
  5. package/lib/vendor/MANIFEST.json +392 -278
  6. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  7. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  8. package/lib/vendor/blamejs/.gitignore +6 -0
  9. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  10. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  11. package/lib/vendor/blamejs/README.md +8 -6
  12. package/lib/vendor/blamejs/SECURITY.md +19 -3
  13. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  14. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  15. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  16. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  17. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  18. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  19. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  20. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  21. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  22. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  23. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  24. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  25. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  26. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  27. package/lib/vendor/blamejs/index.js +4 -0
  28. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  29. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  30. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  31. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  32. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  33. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  34. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  35. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  36. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  37. package/lib/vendor/blamejs/lib/audit.js +259 -123
  38. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
  39. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  40. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  41. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
  42. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  43. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  44. package/lib/vendor/blamejs/lib/cache.js +174 -105
  45. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  46. package/lib/vendor/blamejs/lib/cli.js +19 -14
  47. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  48. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  49. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  50. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  51. package/lib/vendor/blamejs/lib/compliance.js +206 -4
  52. package/lib/vendor/blamejs/lib/consent.js +82 -29
  53. package/lib/vendor/blamejs/lib/constants.js +27 -11
  54. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  55. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  56. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  57. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  58. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  59. package/lib/vendor/blamejs/lib/db.js +249 -99
  60. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  61. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  62. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  63. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  64. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  65. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  66. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  67. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  68. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  69. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  70. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  71. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  72. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  73. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  74. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  75. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  76. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  77. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  78. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  79. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  80. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  81. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  82. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  83. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  84. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  85. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  86. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  87. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  88. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  89. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  90. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  91. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  92. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  93. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  94. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  95. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  96. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  97. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  98. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  99. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  100. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  101. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  102. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  103. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  104. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  106. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  107. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  108. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  109. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  110. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  111. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  112. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  113. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  114. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  115. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  116. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  117. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  118. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  119. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  120. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  121. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  122. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  123. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  124. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  125. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  126. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  128. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  129. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  131. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  132. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  133. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  134. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  135. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  136. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  137. package/lib/vendor/blamejs/lib/mail.js +8 -4
  138. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  139. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  140. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  141. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  142. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  143. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  144. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  145. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  146. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  147. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  148. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  149. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  150. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  151. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  152. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  153. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  154. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  155. package/lib/vendor/blamejs/lib/observability.js +124 -0
  156. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  157. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  158. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  159. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  160. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  161. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  162. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  163. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  164. package/lib/vendor/blamejs/lib/queue.js +7 -0
  165. package/lib/vendor/blamejs/lib/redact.js +68 -11
  166. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  167. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  168. package/lib/vendor/blamejs/lib/retention.js +101 -40
  169. package/lib/vendor/blamejs/lib/router.js +212 -5
  170. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  171. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  172. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  173. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  174. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  175. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  176. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  177. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  178. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  179. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  180. package/lib/vendor/blamejs/lib/session.js +175 -77
  181. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  182. package/lib/vendor/blamejs/lib/sse.js +26 -0
  183. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  184. package/lib/vendor/blamejs/lib/static.js +177 -34
  185. package/lib/vendor/blamejs/lib/subject.js +96 -49
  186. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  187. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  188. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  189. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  190. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  191. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  192. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  193. package/lib/vendor/blamejs/package.json +2 -2
  194. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  200. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  201. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  202. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  203. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  204. package/lib/vendor/blamejs/scripts/release.js +398 -38
  205. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  206. package/lib/vendor/blamejs/test/10-state.js +140 -14
  207. package/lib/vendor/blamejs/test/20-db.js +65 -2
  208. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  209. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  210. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  211. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  212. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  213. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  214. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  215. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  220. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  221. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  222. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  223. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  224. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  225. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  226. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  227. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  228. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  229. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  230. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  231. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  232. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  233. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  234. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  235. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  236. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  237. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  238. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  240. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  248. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  249. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  250. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  251. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  256. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  258. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  271. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  272. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  273. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  274. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  275. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  279. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  280. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  284. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  285. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  293. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  302. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  304. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  308. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  310. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  312. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  313. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  314. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  315. package/lib/vendor/blamejs/test/smoke.js +79 -21
  316. package/package.json +1 -1
  317. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  318. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  319. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  320. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  321. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  322. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  323. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  324. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  325. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  326. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  327. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  328. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  329. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  330. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  331. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  332. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  334. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  335. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  336. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  337. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  338. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -2090,6 +2090,239 @@ function authResultsEmit(opts) {
2090
2090
  return "Authentication-Results: " + head + ";\r\n " + clauses.join(sep);
2091
2091
  }
2092
2092
 
2093
+ // ---- Inbound message-authentication pipeline (RFC 7489 §6.6) ----
2094
+ //
2095
+ // One call runs the receiver-side authentication set on a message as it
2096
+ // arrives: SPF (RFC 7208) on the envelope identity, DKIM (RFC 6376) on
2097
+ // the message bytes, DMARC (RFC 7489 / DMARCbis) policy + alignment on
2098
+ // the From-header domain, and — when an authserv-id is supplied — the
2099
+ // RFC 8601 Authentication-Results header the receiver prepends before
2100
+ // delivery. b.mail.server.mx composes this at DATA time via its
2101
+ // guardEnvelope opt; operators running their own listeners (or doing
2102
+ // post-delivery verification in an agent) call it directly:
2103
+ //
2104
+ // var v = await b.mail.inbound.verify({
2105
+ // ip: "203.0.113.5",
2106
+ // helo: "mail.sender.example",
2107
+ // mailFrom: "bounce@sender.example",
2108
+ // message: rfc5322Bytes, // string or Buffer
2109
+ // authservId: "mx.example.com",
2110
+ // });
2111
+ // // → { spf, dkim, from, dmarc, authResults }
2112
+ // if (v.dmarc.recommendedAction === "reject") { /* refuse 550 5.7.1 */ }
2113
+ //
2114
+ // From-header discipline (RFC 7489 §6.6.1): DMARC evaluates exactly one
2115
+ // author domain. A message with zero From fields, several From fields,
2116
+ // or several author addresses in one field is the header-duplication
2117
+ // spoofing shape — an attacker pairs an aligned-but-hidden From with the
2118
+ // one the mail client displays (the CVE-2024-7208 / CVE-2024-7209
2119
+ // hosted-relay spoofing class rides on exactly this ambiguity). Those
2120
+ // messages return `dmarc.result: "permerror"` with
2121
+ // `recommendedAction: "reject"` instead of picking one of the Froms.
2122
+
2123
+ // RFC 5322 §2.1 — the header block ends at the first empty line. SMTP
2124
+ // wire format is CRLF; bare-LF input is accepted defensively for
2125
+ // operator-fed strings that lost CRs in their own tooling.
2126
+ function _splitHeaderBlock(message) {
2127
+ var idx = message.indexOf("\r\n\r\n");
2128
+ if (idx !== -1) return { headers: message.slice(0, idx), body: message.slice(idx + 4) };
2129
+ idx = message.indexOf("\n\n");
2130
+ if (idx !== -1) return { headers: message.slice(0, idx), body: message.slice(idx + 2) };
2131
+ return { headers: message, body: "" };
2132
+ }
2133
+
2134
+ // Quote-aware single pass over a From field value (RFC 5322 phrase
2135
+ // quoting): counts angle-addr pairs that contain an `@` (a `<` inside
2136
+ // a quoted-string is display-name text — `"John <Jr.> Smith" <u@d>`
2137
+ // is one author, not two) and top-level commas (address-list
2138
+ // separators; a comma inside a quoted display-name like
2139
+ // `"Doe, John" <j@d>` does not count). Records the content of the
2140
+ // last @-bearing angle-addr for extraction.
2141
+ function _countFromAuthors(value) {
2142
+ var inQuote = false, inAngle = false, escaped = false;
2143
+ var angleAddrs = 0, topCommas = 0, angleStart = -1;
2144
+ var lastAddr = null;
2145
+ for (var i = 0; i < value.length; i += 1) {
2146
+ var ch = value.charAt(i);
2147
+ if (escaped) { escaped = false; continue; }
2148
+ if (ch === "\\") { escaped = true; continue; }
2149
+ if (ch === "\"" && !inAngle) { inQuote = !inQuote; continue; }
2150
+ if (inQuote) continue;
2151
+ if (ch === "<" && !inAngle) { inAngle = true; angleStart = i; continue; }
2152
+ if (ch === ">" && inAngle) {
2153
+ inAngle = false;
2154
+ var inner = value.slice(angleStart + 1, i).trim();
2155
+ if (inner.indexOf("@") !== -1) { angleAddrs += 1; lastAddr = inner; }
2156
+ continue;
2157
+ }
2158
+ if (ch === "," && !inAngle) topCommas += 1;
2159
+ }
2160
+ return { angleAddrs: angleAddrs, topCommas: topCommas, lastAddr: lastAddr };
2161
+ }
2162
+
2163
+ // Unfold (RFC 5322 §2.2.3), collect every From: field, and extract the
2164
+ // author address. `count` is the number of From fields, widened by
2165
+ // multiple-author detection inside a single field: several @-bearing
2166
+ // angle-addrs, or a bare address-list separated by top-level commas
2167
+ // (RFC 7489 §6.6.1 — a multi-author From is the header-duplication
2168
+ // spoofing shape and must not have "one" author picked from it).
2169
+ function _extractFromHeaders(headerBlock) {
2170
+ var unfolded = headerBlock.replace(/\r?\n[ \t]+/g, " ");
2171
+ var lines = unfolded.split(/\r?\n/);
2172
+ var fromValues = [];
2173
+ for (var i = 0; i < lines.length; i += 1) {
2174
+ var m = /^From[ \t]*:(.*)$/i.exec(lines[i]);
2175
+ if (m) fromValues.push(m[1].trim());
2176
+ }
2177
+ if (fromValues.length === 0) return { count: 0, address: null, domain: null };
2178
+ var count = fromValues.length;
2179
+ var value = fromValues[0];
2180
+ var authors = _countFromAuthors(value);
2181
+ if (count === 1) {
2182
+ if (authors.angleAddrs > 1) count = authors.angleAddrs;
2183
+ else if (authors.topCommas > 0) count = authors.topCommas + 1;
2184
+ }
2185
+ var address;
2186
+ if (authors.angleAddrs >= 1) {
2187
+ // count > 1 is refused by the caller before the address is used;
2188
+ // for the single-author case this is that author's angle-addr.
2189
+ address = authors.lastAddr;
2190
+ } else {
2191
+ // Bare addr-spec form. An RFC 5322 addr-spec cannot contain
2192
+ // whitespace or commas — their presence means an address list or
2193
+ // display-name soup; extracting "the" domain from it would pick
2194
+ // one of several authors (the §6.6.1 forbidden move), so the
2195
+ // field is treated as unparsable instead.
2196
+ address = value.trim();
2197
+ if (/[\s,]/.test(address)) address = null;
2198
+ }
2199
+ var at = address ? address.lastIndexOf("@") : -1;
2200
+ var domain = (at > 0 && address && at < address.length - 1)
2201
+ ? address.slice(at + 1).toLowerCase()
2202
+ : null;
2203
+ return { count: count, address: address || null, domain: domain };
2204
+ }
2205
+
2206
+ async function inboundVerify(opts) {
2207
+ validateOpts.requireObject(opts, "inbound.verify", MailAuthError, "mail-auth/inbound-bad-input");
2208
+ validateOpts(opts, ["ip", "helo", "mailFrom", "message", "dnsLookup", "domainExists",
2209
+ "maxSignatures", "clockSkewMs", "minRsaBits", "authservId"],
2210
+ "mail.inbound.verify");
2211
+ validateOpts.requireNonEmptyString(opts.ip, "inbound.verify: ip",
2212
+ MailAuthError, "mail-auth/inbound-bad-ip");
2213
+ if (opts.authservId !== undefined && opts.authservId !== null) {
2214
+ validateOpts.requireNonEmptyString(opts.authservId, "inbound.verify: authservId",
2215
+ MailAuthError, "mail-auth/inbound-bad-authserv-id");
2216
+ }
2217
+ var message = opts.message;
2218
+ if (Buffer.isBuffer(message)) {
2219
+ // DKIM canonicalization re-encodes the string form as UTF-8
2220
+ // (lib/mail-dkim.js hashes Buffer.from(canonicalized, "utf8")), so
2221
+ // the byte→string decode must be utf8 for valid-UTF-8 content to
2222
+ // round-trip exactly. Non-UTF-8 8-bit content cannot survive any
2223
+ // decode + utf8 re-encode; such messages verify as DKIM fail and
2224
+ // DMARC falls back to the SPF identity (RFC 7489 §4.2 — one
2225
+ // aligned authenticator is sufficient to pass).
2226
+ message = message.toString("utf8");
2227
+ }
2228
+ if (typeof message !== "string" || message.length === 0) {
2229
+ throw new MailAuthError("mail-auth/inbound-bad-message",
2230
+ "inbound.verify: message must be a non-empty string or Buffer (the full RFC 5322 message)");
2231
+ }
2232
+ var mailFrom = (typeof opts.mailFrom === "string" && opts.mailFrom.length > 0) ? opts.mailFrom : null;
2233
+ var helo = (typeof opts.helo === "string" && opts.helo.length > 0) ? opts.helo : null;
2234
+
2235
+ // SPF — envelope identity: MAIL FROM, falling back to HELO for the
2236
+ // null reverse-path (RFC 7208 §2.4). DNS failures surface as the
2237
+ // RFC's temperror result, not as throws.
2238
+ var spf;
2239
+ if (mailFrom || helo) {
2240
+ spf = await spfVerify({
2241
+ ip: opts.ip,
2242
+ mailFrom: mailFrom || undefined,
2243
+ helo: helo || undefined,
2244
+ dnsLookup: opts.dnsLookup,
2245
+ });
2246
+ } else {
2247
+ spf = { result: "none", domain: null,
2248
+ explanation: "no MAIL FROM or HELO identity supplied", lookupCount: 0 };
2249
+ }
2250
+
2251
+ // DKIM — every signature on the message (bounded by maxSignatures;
2252
+ // a signature-less message verifies as a single `none` entry).
2253
+ var dkimVerifyOpts = { dnsLookup: opts.dnsLookup };
2254
+ if (opts.clockSkewMs !== undefined) dkimVerifyOpts.clockSkewMs = opts.clockSkewMs;
2255
+ if (opts.maxSignatures !== undefined) dkimVerifyOpts.maxSignatures = opts.maxSignatures;
2256
+ if (opts.minRsaBits !== undefined) dkimVerifyOpts.minRsaBits = opts.minRsaBits;
2257
+ var dkimResults = await dkim.verify(message, dkimVerifyOpts);
2258
+
2259
+ // From header + DMARC policy/alignment.
2260
+ var from = _extractFromHeaders(_splitHeaderBlock(message).headers);
2261
+ var dmarc;
2262
+ if (from.count === 1 && from.address && from.domain) {
2263
+ dmarc = await dmarcEvaluate({
2264
+ from: from.address,
2265
+ spf: spf,
2266
+ dkim: dkimResults,
2267
+ dnsLookup: opts.dnsLookup,
2268
+ domainExists: opts.domainExists,
2269
+ });
2270
+ // RFC 7489 §6.6.2 — a fail verdict computed while an authenticator
2271
+ // returned temperror is not final: the very lookup that failed
2272
+ // transiently could have produced the aligned pass. Surface
2273
+ // temperror so the caller defers (the sender retries) instead of
2274
+ // permanently refusing a legitimate sender during a DNS blip. A
2275
+ // pass verdict stands — one aligned authenticator is sufficient
2276
+ // regardless of the other's transient failure.
2277
+ if (dmarc.result === "fail" &&
2278
+ (spf.result === "temperror" ||
2279
+ dkimResults.some(function (d) { return d.result === "temperror"; }))) {
2280
+ dmarc.result = "temperror";
2281
+ dmarc.recommendedAction = null;
2282
+ dmarc.explanation = (dmarc.explanation ? dmarc.explanation + "; " : "") +
2283
+ "fail computed while an authenticator returned temperror — transient, retry";
2284
+ }
2285
+ } else {
2286
+ dmarc = {
2287
+ result: "permerror",
2288
+ recommendedAction: "reject",
2289
+ policy: null,
2290
+ alignment: { spf: false, dkim: false },
2291
+ orgDomain: null,
2292
+ explanation: from.count === 0
2293
+ ? "message has no From header (RFC 7489 §6.6.1)"
2294
+ : (from.count > 1
2295
+ ? "message carries " + from.count + " From authors (RFC 7489 §6.6.1 — multi-From spoofing shape)"
2296
+ : "From header has no parsable author domain"),
2297
+ };
2298
+ }
2299
+
2300
+ // RFC 8601 Authentication-Results — only when the caller identifies
2301
+ // itself (the authserv-id is the receiver's own name; there is no
2302
+ // sensible default the framework could invent).
2303
+ var authResults = null;
2304
+ if (opts.authservId) {
2305
+ var arResults = [];
2306
+ var spfEntry = { method: "spf", result: spf.result };
2307
+ if (mailFrom) spfEntry.smtpMailfrom = mailFrom;
2308
+ else if (helo) spfEntry.smtpHelo = helo;
2309
+ arResults.push(spfEntry);
2310
+ for (var di = 0; di < dkimResults.length; di += 1) {
2311
+ var d = dkimResults[di];
2312
+ var dkimEntry = { method: "dkim", result: d.result };
2313
+ if (typeof d.d === "string" && d.d.length > 0) dkimEntry.domain = d.d;
2314
+ if (typeof d.s === "string" && d.s.length > 0) dkimEntry.selector = d.s;
2315
+ arResults.push(dkimEntry);
2316
+ }
2317
+ var dmarcEntry = { method: "dmarc", result: dmarc.result };
2318
+ if (from.address) dmarcEntry.from = from.address;
2319
+ arResults.push(dmarcEntry);
2320
+ authResults = authResultsEmit({ authservId: opts.authservId, results: arResults });
2321
+ }
2322
+
2323
+ return { spf: spf, dkim: dkimResults, from: from, dmarc: dmarc, authResults: authResults };
2324
+ }
2325
+
2093
2326
  // ---- DMARC aggregate (RUA) report parser (RFC 7489 §7.2 / draft-ietf-dmarc-aggregate-reporting) ----
2094
2327
  //
2095
2328
  // MTAs that publish a DMARC `rua=` policy receive aggregate reports
@@ -2971,6 +3204,9 @@ module.exports = {
2971
3204
  authResults: Object.freeze({
2972
3205
  emit: authResultsEmit,
2973
3206
  }),
3207
+ inbound: Object.freeze({
3208
+ verify: inboundVerify,
3209
+ }),
2974
3210
  MailAuthError: MailAuthError,
2975
3211
  SPF_DNS_LOOKUP_LIMIT: SPF_DNS_LOOKUP_LIMIT,
2976
3212
  };
@@ -102,6 +102,7 @@ var cms = require("./cms-codec");
102
102
  var asn1 = require("./asn1-der");
103
103
  var pqcSoftware = require("./pqc-software");
104
104
  var bCrypto = require("./crypto");
105
+ var gateContract = require("./gate-contract");
105
106
  var { defineClass } = require("./framework-error");
106
107
 
107
108
  var MailCryptoError = defineClass("MailCryptoError", { alwaysPermanent: true });
@@ -121,12 +122,7 @@ var REFUSED_HASHES = ["md5", "sha1"];
121
122
  // encryption is added, it composes the same set with the @intro EFAIL
122
123
  // defenses applied.
123
124
  var PROFILES = ["strict", "balanced", "permissive"];
124
- var COMPLIANCE_POSTURES = {
125
- hipaa: "strict",
126
- "pci-dss": "strict",
127
- gdpr: "strict",
128
- soc2: "strict",
129
- };
125
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
130
126
 
131
127
  // ---- Public surface (v0.10.16 lights up — composes b.cms) ----
132
128
 
@@ -1242,6 +1242,7 @@ module.exports = {
1242
1242
  RSA_MIN_BITS: RSA_MIN_BITS,
1243
1243
  RSA_LEGACY_MIN_BITS: RSA_LEGACY_MIN_BITS,
1244
1244
  DKIM_MAX_SIGNATURES_PER_MESSAGE: DKIM_MAX_SIGNATURES_PER_MESSAGE,
1245
+ DKIM_MAX_SIGNATURES_PER_MESSAGE_CEILING: DKIM_MAX_SIGNATURES_PER_MESSAGE_CEILING,
1245
1246
  DKIM_CLOCK_SKEW_MS_MAX: DKIM_CLOCK_SKEW_MS_MAX,
1246
1247
  _canonHeaderRelaxedForTest: _canonHeaderRelaxed,
1247
1248
  _canonBodyRelaxedForTest: _canonBodyRelaxed,
@@ -102,6 +102,7 @@ var { defineClass } = require("./framework-error");
102
102
  var bCrypto = require("./crypto");
103
103
  var lazyRequire = require("./lazy-require");
104
104
  var ipUtils = require("./ip-utils");
105
+ var gateContract = require("./gate-contract");
105
106
 
106
107
  var audit = lazyRequire(function () { return require("./audit"); });
107
108
 
@@ -126,12 +127,7 @@ var PROFILES = Object.freeze({
126
127
  permissive: { minDelayMs: C.TIME.seconds(30), whitelistTtlMs: C.TIME.days(30), ipv4Prefix: 32, ipv6Prefix: 128 }, // RFC 6647 §4.4 prefixes
127
128
  });
128
129
 
129
- var COMPLIANCE_POSTURES = Object.freeze({
130
- hipaa: "strict",
131
- "pci-dss": "strict",
132
- gdpr: "strict",
133
- soc2: "strict",
134
- });
130
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
135
131
 
136
132
  var IPV4_RE = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/; // allow:regex-no-length-cap — anchored + per-octet repeat-cap
137
133
  var IPV6_RE = /^[0-9a-fA-F:]+$/; // allow:regex-no-length-cap — length-checked separately
@@ -104,6 +104,7 @@
104
104
  var { defineClass } = require("./framework-error");
105
105
  var lazyRequire = require("./lazy-require");
106
106
  var ipUtils = require("./ip-utils");
107
+ var gateContract = require("./gate-contract");
107
108
 
108
109
  var audit = lazyRequire(function () { return require("./audit"); });
109
110
 
@@ -145,12 +146,7 @@ var PROFILES = Object.freeze({
145
146
  },
146
147
  });
147
148
 
148
- var COMPLIANCE_POSTURES = Object.freeze({
149
- hipaa: "strict",
150
- "pci-dss": "strict",
151
- gdpr: "strict",
152
- soc2: "strict",
153
- });
149
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
154
150
 
155
151
  // Operator-extensible default list of generic-rDNS patterns the
156
152
  // framework ships. Each is a RegExp — case-insensitive — designed
@@ -72,7 +72,7 @@ var C = require("./constants");
72
72
  var validateOpts = require("./validate-opts");
73
73
  var numericBounds = require("./numeric-bounds");
74
74
  var safeJson = require("./safe-json");
75
- var safeSql = require("./safe-sql");
75
+ var sql = require("./sql");
76
76
  var { defineClass } = require("./framework-error");
77
77
  var lazyRequire = require("./lazy-require");
78
78
 
@@ -213,33 +213,40 @@ function create(opts) {
213
213
  // / `messageId` / `archivedAt` / `sizeBytes` / `regimes` / `legalHold`
214
214
  // queryable without unsealing the payload. The payload (headers +
215
215
  // body) lives in the WORM bucket sealed via b.cryptoField.sealRow.
216
- // Route every identifier through safeSql.quoteIdentifier — the
217
- // shared substrate validates the unquoted name AND emits the
218
- // dialect-correct quoted form. Index names must be built from the
219
- // unquoted base then quoted independently; appending suffixes to
220
- // an already-quoted token produces invalid SQL like
221
- // `"_mail_journal_x"_archived_at_idx`.
222
- var rawTable = "_mail_journal_" + namespace.replace(/-/g, "_");
223
- var qTable = safeSql.quoteIdentifier(rawTable);
224
- var qIdxArchAt = safeSql.quoteIdentifier(rawTable + "_archived_at_idx");
225
- var qIdxMsgId = safeSql.quoteIdentifier(rawTable + "_message_id_idx");
226
- opts.db.runSql(
227
- "CREATE TABLE IF NOT EXISTS " + qTable + " (" +
228
- "journal_id TEXT PRIMARY KEY, " +
229
- "direction TEXT NOT NULL, " +
230
- "actor_id TEXT, " +
231
- "message_id TEXT, " +
232
- "archived_at INTEGER NOT NULL, " +
233
- "size_bytes INTEGER NOT NULL, " +
234
- "regimes TEXT NOT NULL, " +
235
- "floor_until INTEGER NOT NULL, " +
236
- "legal_hold INTEGER NOT NULL DEFAULT 0, " +
237
- "storage_key TEXT NOT NULL UNIQUE, " +
238
- "sealed_payload BLOB NOT NULL" +
239
- ");" +
240
- "CREATE INDEX IF NOT EXISTS " + qIdxArchAt + " ON " + qTable + " (archived_at);" +
241
- "CREATE INDEX IF NOT EXISTS " + qIdxMsgId + " ON " + qTable + " (message_id);"
242
- );
216
+ //
217
+ // The journal table is an operator-namespaced local table (NOT a
218
+ // framework `_blamejs_` table that clusterStorage rewrites), so every
219
+ // statement composes b.sql with quoteName:true b.sql validates the
220
+ // identifier through b.safeSql and emits the dialect-quoted form,
221
+ // running against opts.db (the local sqlite handle) directly. `_t()`
222
+ // opens each verb builder pre-bound to this table so the name resolves
223
+ // in exactly one place.
224
+ var rawTable = "_mail_journal_" + namespace.replace(/-/g, "_");
225
+ var TBL_OPTS = { dialect: "sqlite", quoteName: true };
226
+ function _t(verb) { return sql[verb](rawTable, TBL_OPTS); }
227
+
228
+ // Bootstrap DDL CREATE TABLE + the archived_at / message_id indexes.
229
+ // runSql is a multi-statement helper, so the three b.sql DDL strings
230
+ // join with `;` into one call (each b.sql build is a single validated
231
+ // statement; the join is the multi-statement boundary runSql expects).
232
+ var ddl = [
233
+ sql.createTable(rawTable, [
234
+ { name: "journal_id", type: "text", primaryKey: true },
235
+ { name: "direction", type: "text", notNull: true },
236
+ { name: "actor_id", type: "text" },
237
+ { name: "message_id", type: "text" },
238
+ { name: "archived_at", type: "int", notNull: true },
239
+ { name: "size_bytes", type: "int", notNull: true },
240
+ { name: "regimes", type: "text", notNull: true },
241
+ { name: "floor_until", type: "int", notNull: true },
242
+ { name: "legal_hold", type: "int", notNull: true, default: 0 },
243
+ { name: "storage_key", type: "text", notNull: true, unique: true },
244
+ { name: "sealed_payload", type: "blob", notNull: true },
245
+ ], TBL_OPTS).sql,
246
+ sql.createIndex(rawTable + "_archived_at_idx", rawTable, ["archived_at"], TBL_OPTS).sql,
247
+ sql.createIndex(rawTable + "_message_id_idx", rawTable, ["message_id"], TBL_OPTS).sql,
248
+ ].join(";");
249
+ opts.db.runSql(ddl);
243
250
 
244
251
  async function record(req) {
245
252
  validateOpts.requireObject(req, "mail.journal.record",
@@ -292,13 +299,24 @@ function create(opts) {
292
299
 
293
300
  var regimesJson = JSON.stringify(opts.regimes);
294
301
  var floorUntil = archivedAt + floorMs;
295
- opts.db.runSql(
296
- "INSERT INTO " + qTable + " (journal_id, direction, actor_id, message_id, " +
297
- "archived_at, size_bytes, regimes, floor_until, legal_hold, storage_key, sealed_payload) " +
298
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?);",
299
- [journalId, req.direction, req.actorId, req.messageId,
300
- archivedAt, sizeBytes, regimesJson, floorUntil, storageKey, sealedBlob]
301
- );
302
+ // legal_hold is omitted from the INSERT so the column's
303
+ // `NOT NULL DEFAULT 0` applies (the prior inline `0` SQL literal) — b.sql
304
+ // binds every value it is given, so leaving the column out keeps the row
305
+ // unsealed-at-rest default without binding a redundant constant. b.sql
306
+ // quotes every column + binds every remaining value as a placeholder.
307
+ var insBuilt = _t("insert").values({
308
+ journal_id: journalId,
309
+ direction: req.direction,
310
+ actor_id: req.actorId,
311
+ message_id: req.messageId,
312
+ archived_at: archivedAt,
313
+ size_bytes: sizeBytes,
314
+ regimes: regimesJson,
315
+ floor_until: floorUntil,
316
+ storage_key: storageKey,
317
+ sealed_payload: sealedBlob,
318
+ }).toSql();
319
+ opts.db.runSql(insBuilt.sql, insBuilt.params);
302
320
 
303
321
  _emit("mail.journal.record", "success", {
304
322
  journalId: journalId,
@@ -317,11 +335,12 @@ function create(opts) {
317
335
  throw new MailJournalError("mail-journal/bad-id",
318
336
  "mail.journal.getById: journalId must be a non-empty string");
319
337
  }
320
- var rows = opts.db.runSql(
321
- "SELECT direction, message_id, archived_at, size_bytes, regimes, floor_until, " +
322
- "legal_hold, storage_key, sealed_payload FROM " + qTable + " WHERE journal_id = ?;",
323
- [journalId]
324
- );
338
+ var gbBuilt = _t("select")
339
+ .columns(["direction", "message_id", "archived_at", "size_bytes", "regimes",
340
+ "floor_until", "legal_hold", "storage_key", "sealed_payload"])
341
+ .where("journal_id", journalId)
342
+ .toSql();
343
+ var rows = opts.db.runSql(gbBuilt.sql, gbBuilt.params);
325
344
  if (!rows || rows.length === 0) return null;
326
345
  var r = rows[0];
327
346
  var unsealed = safeJson.parse(opts.vault.unseal(r.sealed_payload));
@@ -344,30 +363,27 @@ function create(opts) {
344
363
 
345
364
  function list(filter) {
346
365
  filter = filter || {};
366
+ var limit = numericBounds.isPositiveFiniteInt(filter.limit) ? Math.min(filter.limit, 1000) : 100; // list page cap
367
+ // Each filter term is an optional .where() leaf (AND-composed); b.sql
368
+ // quotes the columns + binds the values. A diagnostic clause list is
369
+ // kept for the audit metadata (the prior `filter: clauses` field).
347
370
  var clauses = [];
348
- var args = [];
371
+ var qb = _t("select").columns(["journal_id", "direction", "actor_id", "message_id",
372
+ "archived_at", "size_bytes", "regimes", "floor_until", "legal_hold", "storage_key"]);
349
373
  if (filter.direction && ALLOWED_DIRECTIONS[filter.direction]) {
350
- clauses.push("direction = ?");
351
- args.push(filter.direction);
374
+ qb.where("direction", filter.direction); clauses.push("direction = ?");
352
375
  }
353
376
  if (typeof filter.since === "number" && numericBounds.isPositiveFiniteInt(filter.since)) {
354
- clauses.push("archived_at >= ?");
355
- args.push(filter.since);
377
+ qb.whereOp("archived_at", ">=", filter.since); clauses.push("archived_at >= ?");
356
378
  }
357
379
  if (typeof filter.until === "number" && numericBounds.isPositiveFiniteInt(filter.until)) {
358
- clauses.push("archived_at < ?");
359
- args.push(filter.until);
380
+ qb.whereOp("archived_at", "<", filter.until); clauses.push("archived_at < ?");
360
381
  }
361
382
  if (filter.actorId && typeof filter.actorId === "string") {
362
- clauses.push("actor_id = ?");
363
- args.push(filter.actorId);
383
+ qb.where("actor_id", filter.actorId); clauses.push("actor_id = ?");
364
384
  }
365
- var limit = numericBounds.isPositiveFiniteInt(filter.limit) ? Math.min(filter.limit, 1000) : 100; // list page cap
366
- var where = clauses.length > 0 ? " WHERE " + clauses.join(" AND ") : "";
367
- var sql = "SELECT journal_id, direction, actor_id, message_id, archived_at, " +
368
- "size_bytes, regimes, floor_until, legal_hold, storage_key FROM " +
369
- qTable + where + " ORDER BY archived_at DESC LIMIT " + limit + ";";
370
- var rows = opts.db.runSql(sql, args);
385
+ var listBuilt = qb.orderBy("archived_at", "desc").limit(limit).toSql();
386
+ var rows = opts.db.runSql(listBuilt.sql, listBuilt.params);
371
387
  _emit("mail.journal.list", "success", { count: rows ? rows.length : 0, filter: clauses });
372
388
  return (rows || []).map(function (r) {
373
389
  return {
@@ -387,11 +403,15 @@ function create(opts) {
387
403
 
388
404
  function expireSurface(now) {
389
405
  if (now === undefined) now = Date.now();
390
- var rows = opts.db.runSql(
391
- "SELECT journal_id, archived_at, floor_until, message_id, regimes FROM " +
392
- qTable + " WHERE floor_until < ? AND legal_hold = 0 ORDER BY archived_at ASC LIMIT 1000;", // expiry-surface cap
393
- [now]
394
- );
406
+ // legal_hold = 0 binds as a value (the prior inline `0` literal).
407
+ var esBuilt = _t("select")
408
+ .columns(["journal_id", "archived_at", "floor_until", "message_id", "regimes"])
409
+ .whereOp("floor_until", "<", now)
410
+ .where("legal_hold", 0)
411
+ .orderBy("archived_at", "asc")
412
+ .limit(1000) // expiry-surface cap
413
+ .toSql();
414
+ var rows = opts.db.runSql(esBuilt.sql, esBuilt.params);
395
415
  _emit("mail.journal.expire_surface", "success", { count: rows ? rows.length : 0, now: now });
396
416
  return (rows || []).map(function (r) {
397
417
  return {
@@ -409,10 +429,11 @@ function create(opts) {
409
429
  throw new MailJournalError("mail-journal/bad-id",
410
430
  "mail.journal.setLegalHold: journalId required");
411
431
  }
412
- opts.db.runSql(
413
- "UPDATE " + qTable + " SET legal_hold = ? WHERE journal_id = ?;",
414
- [onHold ? 1 : 0, journalId]
415
- );
432
+ var lhBuilt = _t("update")
433
+ .set("legal_hold", onHold ? 1 : 0)
434
+ .where("journal_id", journalId)
435
+ .toSql();
436
+ opts.db.runSql(lhBuilt.sql, lhBuilt.params);
416
437
  _emit("mail.journal.legal_hold_change", "success", { journalId: journalId, onHold: !!onHold });
417
438
  }
418
439
 
@@ -86,6 +86,7 @@ var C = require("./constants");
86
86
  var { defineClass } = require("./framework-error");
87
87
  var lazyRequire = require("./lazy-require");
88
88
  var ipUtils = require("./ip-utils");
89
+ var gateContract = require("./gate-contract");
89
90
 
90
91
  var audit = lazyRequire(function () { return require("./audit"); });
91
92
 
@@ -105,12 +106,7 @@ var PROFILES = Object.freeze({
105
106
  permissive: { maxConcurrent: 32, perListTimeoutMs: C.TIME.seconds(20), maxListsPerQuery: 64 }, // list-count cap
106
107
  });
107
108
 
108
- var COMPLIANCE_POSTURES = Object.freeze({
109
- hipaa: "strict",
110
- "pci-dss": "strict",
111
- gdpr: "strict",
112
- soc2: "strict",
113
- });
109
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
114
110
 
115
111
  /**
116
112
  * @primitive b.mail.rbl.create
@@ -85,6 +85,7 @@ var lazyRequire = require("./lazy-require");
85
85
  var validateOpts = require("./validate-opts");
86
86
  var numericBounds = require("./numeric-bounds");
87
87
  var safeIcap = require("./safe-icap");
88
+ var gateContract = require("./gate-contract");
88
89
 
89
90
  var audit = lazyRequire(function () { return require("./audit"); });
90
91
  var guardArchive = lazyRequire(function () { return require("./guard-archive"); });
@@ -107,12 +108,7 @@ var PROFILES = Object.freeze({
107
108
  permissive: { timeoutMs: C.TIME.seconds(120), maxMessageBytes: C.BYTES.mib(150), maxResponseBytes: C.BYTES.mib(300) }, // operator-facing default mailbox cap
108
109
  });
109
110
 
110
- var COMPLIANCE_POSTURES = Object.freeze({
111
- hipaa: "strict",
112
- "pci-dss": "strict",
113
- gdpr: "strict",
114
- soc2: "strict",
115
- });
111
+ var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
116
112
 
117
113
  var ALLOWED_PROTOCOLS = Object.freeze({
118
114
  "icap": true,