@blamejs/blamejs-shop 0.5.12 → 0.5.14

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 (522) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/sales-tax-filings.js +143 -0
  4. package/lib/vendor/MANIFEST.json +632 -416
  5. package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
  6. package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
  7. package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
  8. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  9. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
  10. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
  11. package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
  12. package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
  13. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
  14. package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
  15. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
  16. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  17. package/lib/vendor/blamejs/.gitignore +2 -0
  18. package/lib/vendor/blamejs/CHANGELOG.md +122 -0
  19. package/lib/vendor/blamejs/NOTICE +26 -1
  20. package/lib/vendor/blamejs/SECURITY.md +1 -1
  21. package/lib/vendor/blamejs/api-snapshot.json +207 -5
  22. package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
  23. package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
  24. package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
  25. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
  26. package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
  27. package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
  28. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
  29. package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
  30. package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
  31. package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
  32. package/lib/vendor/blamejs/index.js +6 -0
  33. package/lib/vendor/blamejs/lib/a2a.js +4 -4
  34. package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
  35. package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
  36. package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
  37. package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
  38. package/lib/vendor/blamejs/lib/archive-read.js +8 -0
  39. package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
  40. package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
  41. package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
  42. package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
  43. package/lib/vendor/blamejs/lib/audit.js +71 -8
  44. package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
  45. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
  46. package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
  47. package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
  48. package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
  49. package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
  50. package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
  51. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
  52. package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
  53. package/lib/vendor/blamejs/lib/backup/index.js +16 -5
  54. package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
  55. package/lib/vendor/blamejs/lib/base32.js +21 -0
  56. package/lib/vendor/blamejs/lib/break-glass.js +19 -10
  57. package/lib/vendor/blamejs/lib/bundler.js +5 -1
  58. package/lib/vendor/blamejs/lib/cache-status.js +3 -7
  59. package/lib/vendor/blamejs/lib/calendar.js +21 -1
  60. package/lib/vendor/blamejs/lib/cbor.js +12 -1
  61. package/lib/vendor/blamejs/lib/cert.js +29 -11
  62. package/lib/vendor/blamejs/lib/cli.js +94 -24
  63. package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
  64. package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
  65. package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
  66. package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
  67. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
  68. package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
  69. package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
  70. package/lib/vendor/blamejs/lib/content-digest.js +2 -1
  71. package/lib/vendor/blamejs/lib/cookies.js +13 -3
  72. package/lib/vendor/blamejs/lib/cose.js +31 -16
  73. package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
  74. package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
  75. package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
  76. package/lib/vendor/blamejs/lib/crypto.js +314 -19
  77. package/lib/vendor/blamejs/lib/csp.js +11 -3
  78. package/lib/vendor/blamejs/lib/daemon.js +270 -24
  79. package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
  80. package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
  81. package/lib/vendor/blamejs/lib/db-query.js +34 -7
  82. package/lib/vendor/blamejs/lib/db.js +18 -6
  83. package/lib/vendor/blamejs/lib/dbsc.js +17 -0
  84. package/lib/vendor/blamejs/lib/dev.js +21 -2
  85. package/lib/vendor/blamejs/lib/dsr.js +157 -102
  86. package/lib/vendor/blamejs/lib/external-db.js +41 -2
  87. package/lib/vendor/blamejs/lib/file-upload.js +25 -7
  88. package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
  89. package/lib/vendor/blamejs/lib/forms.js +113 -27
  90. package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
  91. package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
  92. package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
  93. package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
  94. package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
  95. package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
  96. package/lib/vendor/blamejs/lib/guard-html.js +26 -53
  97. package/lib/vendor/blamejs/lib/guard-image.js +24 -5
  98. package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
  99. package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
  100. package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
  101. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
  102. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
  103. package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
  104. package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
  105. package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
  106. package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
  107. package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
  108. package/lib/vendor/blamejs/lib/guard-time.js +1 -1
  109. package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
  110. package/lib/vendor/blamejs/lib/html-balance.js +3 -3
  111. package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
  112. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
  113. package/lib/vendor/blamejs/lib/http-client.js +39 -7
  114. package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
  115. package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
  116. package/lib/vendor/blamejs/lib/i18n.js +35 -21
  117. package/lib/vendor/blamejs/lib/incident-report.js +8 -1
  118. package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
  119. package/lib/vendor/blamejs/lib/json-path.js +23 -1
  120. package/lib/vendor/blamejs/lib/jwk.js +20 -3
  121. package/lib/vendor/blamejs/lib/link-header.js +2 -1
  122. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
  123. package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
  124. package/lib/vendor/blamejs/lib/log-stream.js +8 -3
  125. package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
  126. package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
  127. package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
  128. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
  129. package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
  130. package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
  131. package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
  132. package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
  133. package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
  134. package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
  135. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
  136. package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
  137. package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
  138. package/lib/vendor/blamejs/lib/mail.js +15 -5
  139. package/lib/vendor/blamejs/lib/metrics.js +268 -63
  140. package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
  141. package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
  142. package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
  143. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
  144. package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
  145. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
  146. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
  147. package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
  148. package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
  149. package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
  150. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
  151. package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
  152. package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
  153. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
  154. package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
  155. package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
  156. package/lib/vendor/blamejs/lib/network-dns.js +21 -2
  157. package/lib/vendor/blamejs/lib/network-tls.js +69 -7
  158. package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
  159. package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
  160. package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
  161. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
  162. package/lib/vendor/blamejs/lib/outbox.js +1 -1
  163. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
  164. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
  165. package/lib/vendor/blamejs/lib/permissions.js +6 -3
  166. package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
  167. package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
  168. package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
  169. package/lib/vendor/blamejs/lib/pubsub.js +20 -9
  170. package/lib/vendor/blamejs/lib/queue-local.js +8 -1
  171. package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
  172. package/lib/vendor/blamejs/lib/redact.js +54 -0
  173. package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
  174. package/lib/vendor/blamejs/lib/restore.js +19 -0
  175. package/lib/vendor/blamejs/lib/retention.js +12 -4
  176. package/lib/vendor/blamejs/lib/router.js +60 -6
  177. package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
  178. package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
  179. package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
  180. package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
  181. package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
  182. package/lib/vendor/blamejs/lib/safe-object.js +80 -0
  183. package/lib/vendor/blamejs/lib/safe-path.js +52 -4
  184. package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
  185. package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
  186. package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
  187. package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
  188. package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
  189. package/lib/vendor/blamejs/lib/scheduler.js +8 -1
  190. package/lib/vendor/blamejs/lib/security-assert.js +6 -6
  191. package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
  192. package/lib/vendor/blamejs/lib/self-update.js +517 -87
  193. package/lib/vendor/blamejs/lib/server-timing.js +2 -4
  194. package/lib/vendor/blamejs/lib/session.js +34 -12
  195. package/lib/vendor/blamejs/lib/sql.js +15 -1
  196. package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
  197. package/lib/vendor/blamejs/lib/static.js +55 -13
  198. package/lib/vendor/blamejs/lib/storage.js +8 -2
  199. package/lib/vendor/blamejs/lib/subject.js +6 -1
  200. package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
  201. package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
  202. package/lib/vendor/blamejs/lib/tsa.js +34 -13
  203. package/lib/vendor/blamejs/lib/uri-template.js +8 -1
  204. package/lib/vendor/blamejs/lib/vault/index.js +13 -0
  205. package/lib/vendor/blamejs/lib/vc.js +44 -5
  206. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
  207. package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
  208. package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
  209. package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
  210. package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
  211. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
  212. package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
  213. package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
  214. package/lib/vendor/blamejs/lib/watcher.js +89 -17
  215. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
  216. package/lib/vendor/blamejs/lib/webhook.js +12 -2
  217. package/lib/vendor/blamejs/lib/ws-client.js +32 -1
  218. package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
  219. package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
  220. package/lib/vendor/blamejs/package-lock.json +2 -2
  221. package/lib/vendor/blamejs/package.json +1 -1
  222. package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
  223. package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
  224. package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
  225. package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
  226. package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
  227. package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
  228. package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
  229. package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
  230. package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
  231. package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
  232. package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
  233. package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
  234. package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
  235. package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
  236. package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
  237. package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
  238. package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
  239. package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
  240. package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
  241. package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
  242. package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
  243. package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
  244. package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
  245. package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
  246. package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
  247. package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
  248. package/lib/vendor/blamejs/socket.yml +94 -0
  249. package/lib/vendor/blamejs/test/00-primitives.js +605 -0
  250. package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
  251. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
  252. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
  253. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
  254. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
  255. package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
  256. package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
  257. package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
  258. package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
  259. package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
  260. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
  263. package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
  269. package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
  271. package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
  272. package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
  273. package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
  283. package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
  285. package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
  294. package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
  295. package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
  302. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
  303. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
  308. package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
  310. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
  312. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
  313. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
  314. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
  315. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
  316. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
  317. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
  318. package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
  319. package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
  320. package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
  321. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
  322. package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
  323. package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
  324. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
  325. package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
  326. package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
  327. package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
  328. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
  329. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
  330. package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
  331. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
  335. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
  336. package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
  337. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
  341. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
  342. package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
  344. package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
  346. package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
  347. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
  348. package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
  349. package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
  366. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
  377. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
  387. package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
  388. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
  389. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
  390. package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
  391. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
  392. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
  393. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
  396. package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
  397. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
  398. package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
  399. package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
  400. package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
  401. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
  402. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
  403. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
  404. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
  405. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
  406. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
  407. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
  408. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
  409. package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
  410. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
  411. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
  412. package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
  413. package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
  414. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
  415. package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
  416. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
  417. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
  418. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
  419. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
  420. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
  421. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
  422. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
  423. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
  424. package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
  425. package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
  426. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
  427. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
  428. package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
  429. package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
  430. package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
  431. package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
  432. package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
  433. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
  434. package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
  435. package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
  436. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
  437. package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
  438. package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
  439. package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
  440. package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
  441. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
  442. package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
  443. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
  444. package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
  445. package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
  446. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
  447. package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
  448. package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
  449. package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
  450. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
  451. package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
  452. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
  453. package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
  454. package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
  455. package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
  456. package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
  457. package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
  458. package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
  459. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
  460. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
  461. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
  462. package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
  463. package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
  464. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
  465. package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
  466. package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
  467. package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
  468. package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
  469. package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
  470. package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
  471. package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
  472. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
  473. package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
  474. package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
  475. package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
  476. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
  477. package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
  478. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
  479. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
  480. package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
  481. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
  482. package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
  483. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
  484. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
  485. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
  486. package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
  487. package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
  488. package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
  489. package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
  490. package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
  491. package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
  492. package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
  493. package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
  494. package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
  495. package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
  496. package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
  497. package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
  498. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
  499. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
  500. package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
  501. package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
  502. package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
  503. package/lib/vendor/blamejs/test/smoke.js +2 -0
  504. package/package.json +1 -1
  505. package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
  506. package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
  507. package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
  508. package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
  509. package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
  510. package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
  511. package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
  512. package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
  513. package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
  514. package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
  515. package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
  516. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
  517. package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
  518. package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
  519. package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
  520. package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
  521. package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
  522. package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
@@ -12,6 +12,7 @@ var helpers = require("../helpers");
12
12
  var b = helpers.b;
13
13
  var check = helpers.check;
14
14
  var _bodyRes = helpers._bodyRes;
15
+ var _mockRes = helpers._mockRes;
15
16
 
16
17
  function testSurface() {
17
18
  check("b.requestHelpers exposed", typeof b.requestHelpers === "object");
@@ -508,6 +509,11 @@ async function run() {
508
509
  testTrustedClientIpResolves();
509
510
  testTrustedProxyMappedPeerNormalized();
510
511
  testTrustedProtocol();
512
+ testRequestProtocolNoProxy();
513
+ testRequestProtocolPeerGatedTrustedProxy();
514
+ testRequestProtocolPeerGatedUntrustedProxyIgnoresForgedHeader();
515
+ testRequestProtocolLegacyTrustProxyTrue();
516
+ testAppendVary();
511
517
  testTrustedClientIpValidates();
512
518
  testResolveRoutePrefersRoutePattern();
513
519
  testResolveRouteFallsBackToUrl();
@@ -627,6 +633,94 @@ function testMakeSkipMatcher() {
627
633
  catch (e) { return e instanceof Error; } })());
628
634
  }
629
635
 
636
+ function testAppendVary() {
637
+ // Append preserves prior tokens (compression + auth helpers each add one).
638
+ var res = _mockRes();
639
+ res.setHeader("Vary", "Accept-Encoding");
640
+ b.requestHelpers.appendVary(res, "Authorization");
641
+ check("appendVary: appends without dropping the prior token",
642
+ res.getHeader("Vary") === "Accept-Encoding, Authorization");
643
+
644
+ // Idempotent — re-adding an existing token (case-insensitive) is a no-op.
645
+ b.requestHelpers.appendVary(res, "accept-encoding");
646
+ check("appendVary: re-adding an existing token (case-insensitive) is a no-op",
647
+ res.getHeader("Vary") === "Accept-Encoding, Authorization");
648
+
649
+ // First token when Vary is unset.
650
+ var fresh = _mockRes();
651
+ b.requestHelpers.appendVary(fresh, "Origin");
652
+ check("appendVary: sets Vary when none existed", fresh.getHeader("Vary") === "Origin");
653
+
654
+ // Empty-string Vary is treated as unset.
655
+ var emptyVary = _mockRes();
656
+ emptyVary.setHeader("Vary", "");
657
+ b.requestHelpers.appendVary(emptyVary, "Cookie");
658
+ check("appendVary: empty existing Vary treated as unset", emptyVary.getHeader("Vary") === "Cookie");
659
+
660
+ // Silent no-op when res doesn't expose getHeader/setHeader (never throws).
661
+ var threw = null;
662
+ try {
663
+ b.requestHelpers.appendVary(null, "X");
664
+ b.requestHelpers.appendVary({}, "X");
665
+ b.requestHelpers.appendVary({ getHeader: function () { return null; } }, "X");
666
+ } catch (e) { threw = e; }
667
+ check("appendVary: no-ops (no throw) on a res without header methods", threw === null);
668
+ }
669
+
670
+ function testRequestProtocolNoProxy() {
671
+ check("requestProtocol: encrypted socket → https",
672
+ b.requestHelpers.requestProtocol({ socket: { encrypted: true } }) === "https");
673
+ check("requestProtocol: plain socket → http",
674
+ b.requestHelpers.requestProtocol({ socket: { encrypted: false } }) === "http");
675
+ check("requestProtocol: connection.encrypted fallback → https",
676
+ b.requestHelpers.requestProtocol({ connection: { encrypted: true } }) === "https");
677
+ check("requestProtocol: undefined req → http", b.requestHelpers.requestProtocol(undefined) === "http");
678
+ check("requestProtocol: null req → http", b.requestHelpers.requestProtocol(null) === "http");
679
+ }
680
+
681
+ function testRequestProtocolPeerGatedTrustedProxy() {
682
+ // Predicate (peer-gated): X-Forwarded-Proto honored only when the immediate
683
+ // TCP peer is a trusted proxy — the leftmost hop is returned.
684
+ var trust = function (addr) { return addr.indexOf("10.") === 0; };
685
+ var viaProxy = {
686
+ socket: { encrypted: false, remoteAddress: "10.0.0.9" },
687
+ headers: { "x-forwarded-proto": "https, http" },
688
+ };
689
+ check("requestProtocol: XFP via trusted proxy peer → https",
690
+ b.requestHelpers.requestProtocol(viaProxy, { trustProxy: trust }) === "https");
691
+ }
692
+
693
+ function testRequestProtocolPeerGatedUntrustedProxyIgnoresForgedHeader() {
694
+ // The bypass: a direct caller whose socket peer is NOT a trusted proxy
695
+ // cannot forge the scheme — the forged X-Forwarded-Proto is ignored and the
696
+ // real (cleartext) socket wins.
697
+ var trust = function (addr) { return addr.indexOf("10.") === 0; };
698
+ var forged = {
699
+ socket: { encrypted: false, remoteAddress: "198.51.100.66" },
700
+ headers: { "x-forwarded-proto": "https" },
701
+ };
702
+ check("requestProtocol: forged XFP from an untrusted peer → http (ignored)",
703
+ b.requestHelpers.requestProtocol(forged, { trustProxy: trust }) === "http");
704
+ // Even a peer-gated request with no forwarded header falls back to the socket.
705
+ var realTls = { socket: { encrypted: true, remoteAddress: "198.51.100.66" }, headers: {} };
706
+ check("requestProtocol: peer-gated real-TLS socket without XFP → https",
707
+ b.requestHelpers.requestProtocol(realTls, { trustProxy: trust }) === "https");
708
+ }
709
+
710
+ function testRequestProtocolLegacyTrustProxyTrue() {
711
+ // Legacy trustProxy:true reads the leftmost hop WITHOUT checking the peer —
712
+ // spoofable, documented as safe only behind a header-rewriting edge.
713
+ var behindEdge = {
714
+ socket: { encrypted: false, remoteAddress: "203.0.113.1" },
715
+ headers: { "x-forwarded-proto": "https, http" },
716
+ };
717
+ check("requestProtocol: legacy trustProxy:true → leftmost forwarded hop",
718
+ b.requestHelpers.requestProtocol(behindEdge, { trustProxy: true }) === "https");
719
+ // Default (no trustProxy) ignores X-Forwarded-Proto entirely.
720
+ check("requestProtocol: default ignores X-Forwarded-Proto",
721
+ b.requestHelpers.requestProtocol(behindEdge) === "http");
722
+ }
723
+
630
724
  module.exports = { run: run };
631
725
 
632
726
  if (require.main === module) {
@@ -0,0 +1,401 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) blamejs contributors
3
+ "use strict";
4
+ /**
5
+ * b.middleware.requireBoundKey — Bearer-API-key auth with scope +
6
+ * bound-fields + peer-cert-fingerprint binding.
7
+ *
8
+ * Security-critical middleware: every missing / mismatched / expired /
9
+ * malformed binding MUST fail closed (401/403/400/500/503, never
10
+ * next()). These tests drive the real middleware run through
11
+ * b.testing.mockReq / mockRes and assert it refuses on every hostile
12
+ * or omitted input, and only calls next() when every check passes.
13
+ */
14
+
15
+ var helpers = require("../helpers");
16
+ var b = helpers.b;
17
+ var check = helpers.check;
18
+
19
+ // Drive the async middleware to completion. Returns the captured
20
+ // response, whether next() ran, and the (possibly mutated) req.
21
+ async function _drive(mw, req) {
22
+ var res = b.testing.mockRes();
23
+ var nextCalled = false;
24
+ var threw = null;
25
+ try {
26
+ await mw(req, res, function () { nextCalled = true; });
27
+ } catch (e) {
28
+ threw = e;
29
+ }
30
+ return {
31
+ res: res,
32
+ captured: res._captured(),
33
+ nextCalled: nextCalled,
34
+ threw: threw,
35
+ req: req,
36
+ };
37
+ }
38
+
39
+ function _bearerReq(token, extra) {
40
+ var opts = extra || {};
41
+ opts.headers = Object.assign({ authorization: "Bearer " + token }, opts.headers || {});
42
+ return b.testing.mockReq(opts);
43
+ }
44
+
45
+ // A resolver that only knows one key.
46
+ function _resolverFor(record) {
47
+ return async function (apiKey) {
48
+ return apiKey === "valid-key" ? record : null;
49
+ };
50
+ }
51
+
52
+ async function run() {
53
+ var RequireBoundKeyError = b.middleware.requireBoundKey.RequireBoundKeyError ||
54
+ require("../../lib/middleware/require-bound-key").RequireBoundKeyError;
55
+
56
+ // ---------------------------------------------------------------
57
+ // Config-time validation — entry-point tier THROWS on bad opts.
58
+ // ---------------------------------------------------------------
59
+ var threwNoResolver = false;
60
+ try { b.middleware.requireBoundKey({ audit: false }); }
61
+ catch (e) { threwNoResolver = e instanceof RequireBoundKeyError; }
62
+ check("config: missing resolver throws RequireBoundKeyError", threwNoResolver);
63
+
64
+ var threwBadResolver = false;
65
+ try { b.middleware.requireBoundKey({ resolver: "not-a-fn", audit: false }); }
66
+ catch (e) { threwBadResolver = e instanceof RequireBoundKeyError; }
67
+ check("config: non-function resolver throws", threwBadResolver);
68
+
69
+ var threwEmptyScope = false;
70
+ try {
71
+ b.middleware.requireBoundKey({
72
+ resolver: async function () { return null; },
73
+ requiredScopes: ["ok", ""], audit: false,
74
+ });
75
+ } catch (e) { threwEmptyScope = e instanceof RequireBoundKeyError; }
76
+ check("config: empty-string scope throws bad-scope", threwEmptyScope);
77
+
78
+ var threwNonStringScope = false;
79
+ try {
80
+ b.middleware.requireBoundKey({
81
+ resolver: async function () { return null; },
82
+ requiredScopes: [123], audit: false,
83
+ });
84
+ } catch (e) { threwNonStringScope = e instanceof RequireBoundKeyError; }
85
+ check("config: non-string scope throws bad-scope", threwNonStringScope);
86
+
87
+ var threwBadGetter = false;
88
+ try {
89
+ b.middleware.requireBoundKey({
90
+ resolver: async function () { return null; },
91
+ getBoundField: { tenantId: "not-a-fn" }, audit: false,
92
+ });
93
+ } catch (e) { threwBadGetter = e instanceof RequireBoundKeyError; }
94
+ check("config: non-function bound-field getter throws", threwBadGetter);
95
+
96
+ var threwUnknownOpt = false;
97
+ try {
98
+ b.middleware.requireBoundKey({
99
+ resolver: async function () { return null; },
100
+ notAnOpt: true, audit: false,
101
+ });
102
+ } catch (_e) { threwUnknownOpt = true; }
103
+ check("config: unknown opt rejected by validateOpts", threwUnknownOpt);
104
+
105
+ // ---------------------------------------------------------------
106
+ // Bearer header parsing — fail closed on every non-token shape.
107
+ // ---------------------------------------------------------------
108
+ var okRecord = { id: "k1", scopes: ["webhook.ingest"], boundFields: {} };
109
+ var scopedMw = b.middleware.requireBoundKey({
110
+ resolver: _resolverFor(okRecord),
111
+ requiredScopes: ["webhook.ingest"],
112
+ audit: false,
113
+ });
114
+
115
+ var noHeader = await _drive(scopedMw, b.testing.mockReq({ headers: {} }));
116
+ check("parse: no Authorization header → 401 no-bearer-token",
117
+ noHeader.captured.status === 401 && !noHeader.nextCalled);
118
+ check("parse: no-bearer-token body carries reason",
119
+ /no-bearer-token/.test(noHeader.captured.body));
120
+ check("parse: 401 no-token challenge omits error code (RFC 6750 §3)",
121
+ noHeader.captured.headers["www-authenticate"] === 'Bearer realm="api"');
122
+ check("parse: refusal carries Cache-Control no-store",
123
+ /no-store/.test(String(noHeader.captured.headers["cache-control"])));
124
+
125
+ var basicAuth = await _drive(scopedMw,
126
+ b.testing.mockReq({ headers: { authorization: "Basic dXNlcjpwYXNz" } }));
127
+ check("parse: non-Bearer scheme → 401, fail closed",
128
+ basicAuth.captured.status === 401 && !basicAuth.nextCalled);
129
+
130
+ var lowerBearer = await _drive(scopedMw,
131
+ b.testing.mockReq({ headers: { authorization: "bearer valid-key" } }));
132
+ check("parse: lowercase 'bearer' scheme is not accepted (case-sensitive) → 401",
133
+ lowerBearer.captured.status === 401 && !lowerBearer.nextCalled);
134
+
135
+ var emptyToken = await _drive(scopedMw,
136
+ b.testing.mockReq({ headers: { authorization: "Bearer " } }));
137
+ check("parse: 'Bearer ' with no token → 401, fail closed",
138
+ emptyToken.captured.status === 401 && !emptyToken.nextCalled);
139
+
140
+ var spacedToken = await _drive(scopedMw,
141
+ b.testing.mockReq({ headers: { authorization: "Bearer has space" } }));
142
+ check("parse: token containing a space is rejected → 401",
143
+ spacedToken.captured.status === 401 && !spacedToken.nextCalled);
144
+
145
+ // Uppercase header name still resolves (some proxies capitalize).
146
+ var upperName = await _drive(scopedMw,
147
+ b.testing.mockReq({ headers: { Authorization: "Bearer valid-key" } }));
148
+ check("parse: 'Authorization' (capitalized) header accepted → next()",
149
+ upperName.nextCalled === true);
150
+
151
+ // ---------------------------------------------------------------
152
+ // Resolver contract — fail closed on throw / null / non-object.
153
+ // ---------------------------------------------------------------
154
+ var throwingMw = b.middleware.requireBoundKey({
155
+ resolver: async function () { throw new Error("db down"); },
156
+ audit: false,
157
+ });
158
+ var resolverThrew = await _drive(throwingMw, _bearerReq("anything"));
159
+ check("resolver: throw → 503 resolver-unavailable, fail closed",
160
+ resolverThrew.captured.status === 503 && !resolverThrew.nextCalled && !resolverThrew.threw);
161
+ check("resolver: 503 challenge advertises scheme without auth-error code",
162
+ resolverThrew.captured.headers["www-authenticate"] === 'Bearer realm="api"');
163
+
164
+ var unknownKeyMw = b.middleware.requireBoundKey({
165
+ resolver: _resolverFor(okRecord), audit: false,
166
+ });
167
+ var unknownKey = await _drive(unknownKeyMw, _bearerReq("bogus-key"));
168
+ check("resolver: unknown key (null record) → 401 key-unknown-or-revoked",
169
+ unknownKey.captured.status === 401 && !unknownKey.nextCalled &&
170
+ /key-unknown-or-revoked/.test(unknownKey.captured.body));
171
+ check("resolver: 401 invalid_token challenge on unknown key",
172
+ /invalid_token/.test(String(unknownKey.captured.headers["www-authenticate"])));
173
+
174
+ var nonObjMw = b.middleware.requireBoundKey({
175
+ resolver: async function () { return "i-am-a-string"; }, audit: false,
176
+ });
177
+ var nonObj = await _drive(nonObjMw, _bearerReq("valid-key"));
178
+ check("resolver: non-object return → 401, fail closed",
179
+ nonObj.captured.status === 401 && !nonObj.nextCalled);
180
+
181
+ var undefMw = b.middleware.requireBoundKey({
182
+ resolver: async function () { return undefined; }, audit: false,
183
+ });
184
+ var undef = await _drive(undefMw, _bearerReq("valid-key"));
185
+ check("resolver: undefined return → 401, fail closed",
186
+ undef.captured.status === 401 && !undef.nextCalled);
187
+
188
+ // ---------------------------------------------------------------
189
+ // Scope check — required scope not held → 403 insufficient_scope.
190
+ // ---------------------------------------------------------------
191
+ var missingScopeMw = b.middleware.requireBoundKey({
192
+ resolver: _resolverFor({ id: "k2", scopes: ["other.scope"], boundFields: {} }),
193
+ requiredScopes: ["webhook.ingest"], audit: false,
194
+ });
195
+ var missingScope = await _drive(missingScopeMw, _bearerReq("valid-key"));
196
+ check("scope: required scope not held → 403 missing-scope, fail closed",
197
+ missingScope.captured.status === 403 && !missingScope.nextCalled &&
198
+ /missing-scope/.test(missingScope.captured.body));
199
+ check("scope: 403 challenge is insufficient_scope",
200
+ /insufficient_scope/.test(String(missingScope.captured.headers["www-authenticate"])));
201
+
202
+ // A record with a non-array `scopes` must be treated as no scopes.
203
+ var badScopesMw = b.middleware.requireBoundKey({
204
+ resolver: _resolverFor({ id: "k3", scopes: "webhook.ingest", boundFields: {} }),
205
+ requiredScopes: ["webhook.ingest"], audit: false,
206
+ });
207
+ var badScopes = await _drive(badScopesMw, _bearerReq("valid-key"));
208
+ check("scope: string (non-array) scopes treated as empty → 403, fail closed",
209
+ badScopes.captured.status === 403 && !badScopes.nextCalled);
210
+
211
+ // ---------------------------------------------------------------
212
+ // Bound-field binding — missing / mismatched / getter-error close.
213
+ // ---------------------------------------------------------------
214
+ var boundRecord = { id: "k4", scopes: [], boundFields: { tenantId: "acme" } };
215
+
216
+ // Registered bound field but no getter configured → 500 (misconfig).
217
+ var noGetterMw = b.middleware.requireBoundKey({
218
+ resolver: _resolverFor(boundRecord), audit: false,
219
+ });
220
+ var noGetter = await _drive(noGetterMw, _bearerReq("valid-key"));
221
+ check("bound-field: registered field w/o getter → 500 bound-field-no-getter, fail closed",
222
+ noGetter.captured.status === 500 && !noGetter.nextCalled &&
223
+ /bound-field-no-getter/.test(noGetter.captured.body));
224
+
225
+ var tenantGetterMw = b.middleware.requireBoundKey({
226
+ resolver: _resolverFor(boundRecord),
227
+ getBoundField: { tenantId: function (req) { return req.headers["x-tenant-id"]; } },
228
+ audit: false,
229
+ });
230
+
231
+ // Field absent on request → 400 bound-field-missing.
232
+ var fieldMissing = await _drive(tenantGetterMw, _bearerReq("valid-key"));
233
+ check("bound-field: absent on request → 400 bound-field-missing, fail closed",
234
+ fieldMissing.captured.status === 400 && !fieldMissing.nextCalled &&
235
+ /bound-field-missing/.test(fieldMissing.captured.body));
236
+ check("bound-field: 400 challenge is invalid_request",
237
+ /invalid_request/.test(String(fieldMissing.captured.headers["www-authenticate"])));
238
+
239
+ // Field present but WRONG value → 403 bound-field-mismatch.
240
+ var fieldWrong = await _drive(tenantGetterMw,
241
+ _bearerReq("valid-key", { headers: { "x-tenant-id": "evil-corp" } }));
242
+ check("bound-field: mismatched value → 403 bound-field-mismatch, fail closed",
243
+ fieldWrong.captured.status === 403 && !fieldWrong.nextCalled &&
244
+ /bound-field-mismatch/.test(fieldWrong.captured.body));
245
+
246
+ // Field present with an empty string → treated as missing → 400.
247
+ var fieldEmpty = await _drive(tenantGetterMw,
248
+ _bearerReq("valid-key", { headers: { "x-tenant-id": "" } }));
249
+ check("bound-field: empty-string value → 400 bound-field-missing, fail closed",
250
+ fieldEmpty.captured.status === 400 && !fieldEmpty.nextCalled);
251
+
252
+ // Getter throwing → 400 bound-field-getter-threw (no crash).
253
+ var getterThrowsMw = b.middleware.requireBoundKey({
254
+ resolver: _resolverFor(boundRecord),
255
+ getBoundField: { tenantId: function () { throw new Error("boom"); } },
256
+ audit: false,
257
+ });
258
+ var getterThrew = await _drive(getterThrowsMw, _bearerReq("valid-key"));
259
+ check("bound-field: getter throw → 400 bound-field-getter-threw, no uncaught crash",
260
+ getterThrew.captured.status === 400 && !getterThrew.nextCalled && !getterThrew.threw);
261
+
262
+ // Getter returns a non-string (number) → treated as missing → 400.
263
+ var getterNumberMw = b.middleware.requireBoundKey({
264
+ resolver: _resolverFor(boundRecord),
265
+ getBoundField: { tenantId: function () { return 12345; } },
266
+ audit: false,
267
+ });
268
+ var getterNumber = await _drive(getterNumberMw, _bearerReq("valid-key"));
269
+ check("bound-field: non-string getter return → 400 bound-field-missing, fail closed",
270
+ getterNumber.captured.status === 400 && !getterNumber.nextCalled);
271
+
272
+ // Correct bound-field value → passes.
273
+ var fieldOk = await _drive(tenantGetterMw,
274
+ _bearerReq("valid-key", { headers: { "x-tenant-id": "acme" } }));
275
+ check("bound-field: correct value → next() called",
276
+ fieldOk.nextCalled === true && fieldOk.captured.status === null);
277
+
278
+ // ---------------------------------------------------------------
279
+ // Peer-cert fingerprint pinning — the mTLS cross-check.
280
+ // ---------------------------------------------------------------
281
+ var rawCert = Buffer.from("blamejs-test-peer-cert-der-bytes-not-a-real-x509");
282
+ var fp = b.crypto.hashCertFingerprint(rawCert);
283
+ var pinnedRecord = { id: "k5", scopes: [], boundFields: {}, peerCertFingerprints: [fp.hex] };
284
+
285
+ var pinnedMw = b.middleware.requireBoundKey({
286
+ resolver: _resolverFor(pinnedRecord), audit: false,
287
+ });
288
+
289
+ // No peer cert presented at all → 401 peer-cert-required.
290
+ var noPeer = await _drive(pinnedMw, _bearerReq("valid-key"));
291
+ check("peer-cert: pinned key + no peer cert → 401 peer-cert-required, fail closed",
292
+ noPeer.captured.status === 401 && !noPeer.nextCalled &&
293
+ /peer-cert-required/.test(noPeer.captured.body));
294
+
295
+ // Peer cert whose fingerprint is NOT pinned → 403 peer-cert-not-pinned.
296
+ var wrongCert = Buffer.from("some-entirely-different-peer-cert-bytes");
297
+ var wrongReq = _bearerReq("valid-key");
298
+ wrongReq.peerCert = { raw: wrongCert };
299
+ var notPinned = await _drive(pinnedMw, wrongReq);
300
+ check("peer-cert: unpinned fingerprint → 403 peer-cert-not-pinned, fail closed",
301
+ notPinned.captured.status === 403 && !notPinned.nextCalled &&
302
+ /peer-cert-not-pinned/.test(notPinned.captured.body));
303
+
304
+ // Peer cert whose fingerprint IS pinned (derived from raw) → passes.
305
+ var goodReq = _bearerReq("valid-key");
306
+ goodReq.peerCert = { raw: rawCert };
307
+ var pinnedOk = await _drive(pinnedMw, goodReq);
308
+ check("peer-cert: pinned fingerprint derived from raw cert → next() called",
309
+ pinnedOk.nextCalled === true);
310
+
311
+ // Pre-attached req.peerFingerprint (from an upstream requireMtls) that
312
+ // matches, with the raw cert also present → passes.
313
+ var preFpReq = _bearerReq("valid-key");
314
+ preFpReq.peerCert = { raw: rawCert };
315
+ preFpReq.peerFingerprint = { hex: fp.hex, colon: fp.colon };
316
+ var preFpOk = await _drive(pinnedMw, preFpReq);
317
+ check("peer-cert: pre-attached matching peerFingerprint + raw → next() called",
318
+ preFpOk.nextCalled === true);
319
+
320
+ // tolerateMissingPeerCert bypass — dev-fixture escape hatch. Pinned
321
+ // key, no cert, but the opt is explicitly set → passes (audited).
322
+ var tolerateMw = b.middleware.requireBoundKey({
323
+ resolver: _resolverFor(pinnedRecord),
324
+ tolerateMissingPeerCert: true, audit: false,
325
+ });
326
+ var tolerated = await _drive(tolerateMw, _bearerReq("valid-key"));
327
+ check("peer-cert: tolerateMissingPeerCert bypass → next() called (audited)",
328
+ tolerated.nextCalled === true);
329
+
330
+ // Fail-closed edge — req.peerFingerprint set by upstream but the raw
331
+ // cert is NOT attached. Must refuse cleanly, never throw an uncaught
332
+ // TypeError (which would hang the request instead of returning a
333
+ // structured refusal).
334
+ var fpNoCertReq = _bearerReq("valid-key");
335
+ fpNoCertReq.peerFingerprint = { hex: fp.hex, colon: fp.colon };
336
+ var fpNoCert = await _drive(pinnedMw, fpNoCertReq);
337
+ check("peer-cert: peerFingerprint present but no raw cert → clean refusal, no uncaught crash",
338
+ fpNoCert.threw === null && !fpNoCert.nextCalled &&
339
+ (fpNoCert.captured.status === 401 || fpNoCert.captured.status === 403));
340
+
341
+ // ---------------------------------------------------------------
342
+ // Success path — req.apiKey populated, bearer secret never re-exposed.
343
+ // ---------------------------------------------------------------
344
+ var successMw = b.middleware.requireBoundKey({
345
+ resolver: _resolverFor({
346
+ id: "k9", scopes: ["webhook.ingest", "extra"],
347
+ boundFields: { tenantId: "acme" },
348
+ }),
349
+ requiredScopes: ["webhook.ingest"],
350
+ getBoundField: { tenantId: function (req) { return req.headers["x-tenant-id"]; } },
351
+ audit: false,
352
+ });
353
+ var success = await _drive(successMw,
354
+ _bearerReq("valid-key", { headers: { "x-tenant-id": "acme" } }));
355
+ check("success: all checks pass → next() called", success.nextCalled === true);
356
+ check("success: req.apiKey.id attached", success.req.apiKey && success.req.apiKey.id === "k9");
357
+ check("success: req.apiKey.scopes copied", success.req.apiKey &&
358
+ success.req.apiKey.scopes.indexOf("webhook.ingest") !== -1);
359
+ check("success: req.apiKey never re-exposes the bearer secret",
360
+ success.req.apiKey && JSON.stringify(success.req.apiKey).indexOf("valid-key") === -1);
361
+ check("success: req.apiKey.boundFields is a copy of registered",
362
+ success.req.apiKey && success.req.apiKey.boundFields.tenantId === "acme");
363
+
364
+ // ---------------------------------------------------------------
365
+ // Refusal customization — onDeny hook + problemDetails mode.
366
+ // ---------------------------------------------------------------
367
+ var onDenyCalls = [];
368
+ var onDenyMw = b.middleware.requireBoundKey({
369
+ resolver: _resolverFor(okRecord), audit: false,
370
+ onDeny: function (req, res, info) {
371
+ onDenyCalls.push(info);
372
+ res.writeHead(418, { "content-type": "text/plain" });
373
+ res.end("teapot");
374
+ },
375
+ });
376
+ var onDenyRes = await _drive(onDenyMw, b.testing.mockReq({ headers: {} }));
377
+ check("onDeny: hook owns the refusal (418) and receives reason info",
378
+ onDenyRes.captured.status === 418 && onDenyCalls.length === 1 &&
379
+ onDenyCalls[0].reason === "no-bearer-token" && !onDenyRes.nextCalled);
380
+
381
+ var problemMw = b.middleware.requireBoundKey({
382
+ resolver: _resolverFor(okRecord), audit: false, problemDetails: true,
383
+ });
384
+ var problemRes = await _drive(problemMw,
385
+ b.testing.mockReq({ headers: { accept: "application/problem+json" } }));
386
+ // problemDetails.respond commits status via res.statusCode; the machine
387
+ // status also rides in the RFC 9457 document body.
388
+ check("problemDetails: emits application/problem+json and fails closed",
389
+ /application\/problem\+json/.test(String(problemRes.captured.headers["content-type"])) &&
390
+ /"status":\s*401/.test(problemRes.captured.body) &&
391
+ !problemRes.nextCalled && !problemRes.threw);
392
+ }
393
+
394
+ module.exports = { run: run };
395
+
396
+ if (require.main === module) {
397
+ run().then(
398
+ function () { console.log("OK — " + helpers.getChecks() + " checks passed"); },
399
+ function (e) { console.error("FAIL:", e.stack || e); process.exit(1); }
400
+ );
401
+ }
@@ -0,0 +1,154 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) blamejs contributors
3
+ "use strict";
4
+ /**
5
+ * b.restore — empty-manifest silent-wipe defense.
6
+ *
7
+ * The bundle writer refuses to emit a bundle with zero file entries
8
+ * (backup-bundle/empty). The shared manifest validator — the guard the
9
+ * restore path relies on when it parses an untrusted / tampered
10
+ * manifest — must mirror that refusal. Otherwise an attacker with write
11
+ * access to an unsigned bundle in storage strips every file entry from
12
+ * the manifest (keeping the legitimate vaultKeyEnc, which still
13
+ * decrypts), and the operator's next restore succeeds with fileCount 0,
14
+ * swapping an EMPTY staging dir into place — a silent destructive wipe
15
+ * of the live dataDir with no error signal.
16
+ *
17
+ * Root: b.backupManifest.validate accepts files: []. Fix it there (the
18
+ * single guard parse() / create() / serialize() all route through) so a
19
+ * zero-entry manifest is refused before it can reach the restore swap.
20
+ */
21
+
22
+ var helpers = require("../helpers");
23
+ var b = helpers.b;
24
+ var check = helpers.check;
25
+ var fs = helpers.fs;
26
+ var os = helpers.os;
27
+ var path = helpers.path;
28
+
29
+ function _validManifestArgs() {
30
+ return {
31
+ vaultKeySalt: "ab12",
32
+ vaultKeyEnc: Buffer.from("wrapped-vault-key").toString("base64"),
33
+ files: [{
34
+ relativePath: "db.enc",
35
+ encryptedPath: "files/db.enc.enc",
36
+ size: 10,
37
+ encryptedSize: 50,
38
+ checksum: "a".repeat(128),
39
+ salt: "cd34",
40
+ kind: "raw",
41
+ }],
42
+ };
43
+ }
44
+
45
+ function _seed() {
46
+ var root = fs.mkdtempSync(path.join(os.tmpdir(), "blamejs-empty-manifest-"));
47
+ var dataDir = path.join(root, "data");
48
+ fs.mkdirSync(dataDir);
49
+ fs.writeFileSync(path.join(dataDir, "db.enc"), "ORIG-DB-CONTENT");
50
+ fs.writeFileSync(path.join(dataDir, "db.key.enc"), "SEALED-DEK");
51
+ return { root: root, dataDir: dataDir, storageRoot: path.join(root, "store") };
52
+ }
53
+
54
+ async function run() {
55
+ // --- 1. The shared validator refuses a zero-entry files array. ---
56
+ var argsEmpty = _validManifestArgs();
57
+ argsEmpty.files = [];
58
+ var vEmpty = b.backupManifest.validate({
59
+ version: 1, framework: "blamejs", frameworkVersion: "0.0.0",
60
+ createdAt: new Date().toISOString(),
61
+ vaultKeySalt: argsEmpty.vaultKeySalt, vaultKeyEnc: argsEmpty.vaultKeyEnc,
62
+ files: [],
63
+ });
64
+ check("validate: zero-entry files array is REFUSED",
65
+ vEmpty.ok === false &&
66
+ vEmpty.errors.some(function (e) { return /files/.test(e); }));
67
+
68
+ // A non-empty valid manifest still validates (no false-positive).
69
+ var vOk = b.backupManifest.validate(Object.assign(
70
+ { version: 1, framework: "blamejs", frameworkVersion: "0.0.0",
71
+ createdAt: new Date().toISOString() },
72
+ _validManifestArgs()));
73
+ check("validate: non-empty valid manifest still passes", vOk.ok === true);
74
+
75
+ // --- 2. parse() of an empty-files manifest throws. ---
76
+ var mkEmptyJson = JSON.stringify({
77
+ version: 1, framework: "blamejs", frameworkVersion: "0.0.0",
78
+ createdAt: new Date().toISOString(),
79
+ vaultKeySalt: "ab12", vaultKeyEnc: Buffer.from("x").toString("base64"),
80
+ files: [],
81
+ });
82
+ var parseThrew = null;
83
+ try { b.backupManifest.parse(mkEmptyJson); } catch (e) { parseThrew = e; }
84
+ check("parse: empty-files manifest is rejected",
85
+ parseThrew && parseThrew.code === "backup-manifest/invalid");
86
+
87
+ // --- 3. End-to-end: a tampered empty-files bundle must NOT wipe the
88
+ // live dataDir; restore must fail-closed. ---
89
+ var pp = Buffer.from("operator-passphrase-not-secret");
90
+ var fx = _seed();
91
+ try {
92
+ function storage() { return b.backup.diskStorage({ root: fx.storageRoot }); }
93
+ var r = await b.backup.create({
94
+ dataDir: fx.dataDir, storage: storage(), passphrase: pp,
95
+ files: [
96
+ { relativePath: "db.enc", kind: "raw", required: true },
97
+ { relativePath: "db.key.enc", kind: "raw", required: true },
98
+ ],
99
+ vaultKeyJson: '{"vault":"orig"}', audit: false,
100
+ }).run();
101
+
102
+ // Belt-and-suspenders: a valid (signed, non-empty) bundle restored with an
103
+ // opts.filter that matches NO manifest entry yields a zero-file extract.
104
+ // The manifest parses fine, but swapping the empty staging dir over the
105
+ // live dataDir would wipe it — restore.run must refuse rather than destroy.
106
+ var filterThrew = null;
107
+ try {
108
+ await b.restore.create({
109
+ dataDir: fx.dataDir, storage: storage(), passphrase: pp,
110
+ rollbackRoot: path.join(fx.root, "rb-filter"), audit: false,
111
+ }).run({ bundleId: r.bundleId, filter: function () { return false; } });
112
+ } catch (e) { filterThrew = e; }
113
+ check("restore: a filter matching no manifest entry is REFUSED (no zero-file wipe)",
114
+ filterThrew && filterThrew.code === "restore/empty-extract-refused");
115
+ check("restore: live dataDir INTACT after the refused zero-file filter restore",
116
+ fs.readFileSync(path.join(fx.dataDir, "db.enc")).toString() === "ORIG-DB-CONTENT" &&
117
+ fs.readFileSync(path.join(fx.dataDir, "db.key.enc")).toString() === "SEALED-DEK");
118
+
119
+ var bdir = path.join(fx.storageRoot, r.bundleId);
120
+ var manifest = JSON.parse(fs.readFileSync(path.join(bdir, "manifest.json"), "utf8"));
121
+
122
+ // Attacker strips every file entry (keeps the legit vaultKeyEnc that
123
+ // still decrypts under the operator passphrase) and drops the signature.
124
+ manifest.files = [];
125
+ delete manifest.signature;
126
+ fs.writeFileSync(path.join(bdir, "manifest.json"), JSON.stringify(manifest));
127
+
128
+ var threw = null;
129
+ try {
130
+ await b.restore.create({
131
+ dataDir: fx.dataDir, storage: storage(), passphrase: pp,
132
+ rollbackRoot: path.join(fx.root, "rb"), audit: false,
133
+ }).run({ bundleId: r.bundleId });
134
+ } catch (e) { threw = e; }
135
+
136
+ check("restore: tampered empty-files bundle is REFUSED (fail-closed)",
137
+ threw && /^restore\//.test(threw.code || ""));
138
+ check("restore: live dataDir is INTACT after the refused restore",
139
+ fs.existsSync(path.join(fx.dataDir, "db.enc")) &&
140
+ fs.existsSync(path.join(fx.dataDir, "db.key.enc")) &&
141
+ fs.readFileSync(path.join(fx.dataDir, "db.enc")).toString() === "ORIG-DB-CONTENT");
142
+ } finally {
143
+ fs.rmSync(fx.root, { recursive: true, force: true });
144
+ }
145
+
146
+ console.log("OK — restore empty-manifest wipe defense (" + helpers.getChecks() + " checks)");
147
+ }
148
+
149
+ module.exports = { run: run };
150
+
151
+ if (require.main === module) {
152
+ run().then(function () { process.exit(0); })
153
+ .catch(function (err) { process.exitCode = 1; throw err; });
154
+ }