@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
@@ -10,7 +10,7 @@
10
10
  * - SNI callback (exact + wildcard + fallback)
11
11
  * - manual refresh() with a mocked ACME client
12
12
  * - audit emission on issue / renew / renew-failed
13
- * - key escrow (encrypt-to-recipient via b.crypto.encryptEnvelope)
13
+ * - key escrow (encrypt-to-recipient via b.crypto.encrypt)
14
14
  *
15
15
  * The live ACME path against an external CA isn't exercised here
16
16
  * (no test CA shipped in the framework); the issue/renew flow is
@@ -106,6 +106,30 @@ async function _selfSignedCert(domains, validityDays) {
106
106
  return { keyPem: keyPem, certPem: cert.toString("pem") };
107
107
  }
108
108
 
109
+ async function _selfSignedCertNoSan(cn, validityDays) {
110
+ // Like _selfSignedCert but with NO SubjectAlternativeName extension —
111
+ // so the parsed cert's subjectAltName is undefined, exercising the
112
+ // `cert.subjectAltName || null` fallback in the manager's _certMeta.
113
+ var pki = require("../../lib/vendor/pki.cjs");
114
+ var x509 = pki.x509;
115
+ var keys = await crypto.webcrypto.subtle.generateKey(
116
+ { name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"]);
117
+ var now = new Date();
118
+ var cert = await x509.X509CertificateGenerator.createSelfSigned({
119
+ serialNumber: "02",
120
+ name: "CN=" + cn,
121
+ notBefore: now,
122
+ notAfter: new Date(now.getTime() + validityDays * 24 * 3600 * 1000),
123
+ signingAlgorithm: { name: "ECDSA", hash: "SHA-256" },
124
+ keys: keys,
125
+ extensions: [],
126
+ });
127
+ var pkcs8 = await crypto.webcrypto.subtle.exportKey("pkcs8", keys.privateKey);
128
+ var pkB64 = Buffer.from(pkcs8).toString("base64").match(/.{1,64}/g).join("\n");
129
+ var keyPem = "-----BEGIN PRIVATE KEY-----\n" + pkB64 + "\n-----END PRIVATE KEY-----\n";
130
+ return { keyPem: keyPem, certPem: cert.toString("pem") };
131
+ }
132
+
109
133
  function _mockAcmeClient(pem) {
110
134
  // Fulfills the b.acme.create contract the cert manager calls into.
111
135
  // Every method returns synchronously-resolved promises with the
@@ -505,10 +529,9 @@ async function testKeyEscrow() {
505
529
  var vault = _ephemeralVault();
506
530
  var pem = await _selfSignedCert(["example.com"], 90);
507
531
 
508
- // Generate an X25519 recipient for the escrow envelope. b.crypto's
509
- // encryptEnvelope accepts the recipient public key as bytes.
510
- var recipient = crypto.generateKeyPairSync("x25519");
511
- var recipientPubBytes = recipient.publicKey.export({ type: "spki", format: "der" });
532
+ // Offline break-glass recipient an ML-KEM-1024 (+ P-384 hybrid)
533
+ // keypair. b.crypto.encrypt seals the escrowed key to its public keys.
534
+ var recipientKp = b.crypto.generateEncryptionKeyPair();
512
535
 
513
536
  // Seed a fake cert so start() doesn't try to ACME.
514
537
  fs.mkdirSync(path.join(tmp, "main"), { recursive: true });
@@ -527,7 +550,7 @@ async function testKeyEscrow() {
527
550
  name: "main",
528
551
  domains: ["example.com"],
529
552
  challenge: { type: "http-01", provision: async function () {}, cleanup: async function () {} },
530
- keyEscrow: { recipient: recipientPubBytes },
553
+ keyEscrow: { recipient: { publicKey: recipientKp.publicKey, ecPublicKey: recipientKp.ecPublicKey } },
531
554
  }],
532
555
  audit: false,
533
556
  });
@@ -741,6 +764,803 @@ async function testCorruptAccountKeyClearError() {
741
764
  try { await mgr.stop(); } catch (_e) {}
742
765
  }
743
766
 
767
+ // ---- Shared fixtures for the issue / renewal / OCSP branch tests ----
768
+
769
+ var GOOD_CHALLENGE = { type: "http-01", provision: async function () {}, cleanup: async function () {} };
770
+
771
+ // Patch the acme module's `create` so the manager's internal
772
+ // `_bootAcme` (require("./acme").create) returns an injected stub
773
+ // instead of building a live RFC 8555 client. Returns a restore fn —
774
+ // ALWAYS call it in a finally so module state isn't polluted for the
775
+ // next test file sharing the process. This is collaborator injection,
776
+ // not a network call: the stub fulfils the same contract cert.js calls.
777
+ function _stubAcmeCreate(client) {
778
+ var acmeMod = require("../../lib/acme");
779
+ var orig = acmeMod.create;
780
+ acmeMod.create = function () { return client; };
781
+ return function restore() { acmeMod.create = orig; };
782
+ }
783
+
784
+ // Patch b.network.tls.ocsp.fetch (the OCSP responder call the manager
785
+ // composes for stapling). The ocsp object itself is frozen, so swap the
786
+ // whole object on the (writable) module property, preserving every other
787
+ // method. Same injection discipline as _stubAcmeCreate.
788
+ function _stubOcspFetch(fn) {
789
+ var nt = require("../../lib/network-tls");
790
+ var origOcsp = nt.ocsp;
791
+ var patched = {};
792
+ Object.keys(origOcsp).forEach(function (k) { patched[k] = origOcsp[k]; });
793
+ patched.fetch = fn;
794
+ nt.ocsp = patched;
795
+ return function restore() { nt.ocsp = origOcsp; };
796
+ }
797
+
798
+ // A flexible ACME stub. `opts` toggles the adversarial shapes each
799
+ // branch test needs (auth already valid, CA offers no matching
800
+ // challenge, ARI throws, a later retrieveCert throws).
801
+ function _makeStubAcme(pem, opts) {
802
+ opts = opts || {};
803
+ var retrieveCalls = 0;
804
+ return {
805
+ fetchDirectory: async function () { return {}; },
806
+ newAccount: async function () { return { url: "mock://acct" }; },
807
+ newOrder: async function (o) {
808
+ return {
809
+ url: "mock://order/1",
810
+ status: "pending",
811
+ authorizations: o.identifiers.map(function (id, i) { return "mock://auth/" + i; }),
812
+ finalize: "mock://order/1/finalize",
813
+ };
814
+ },
815
+ fetchAuthorization: async function (u) {
816
+ if (opts.authValid) {
817
+ return { url: u, status: "valid", identifier: { type: "dns", value: "a.example" }, challenges: [] };
818
+ }
819
+ var chs = opts.omitChallengeType
820
+ ? [{ type: "dns-01", url: u + "/d", token: "t", status: "pending" }]
821
+ : [
822
+ { type: "http-01", url: u + "/h", token: "t", status: "pending" },
823
+ { type: "dns-01", url: u + "/d", token: "t", status: "pending" },
824
+ { type: "tls-alpn-01", url: u + "/a", token: "t", status: "pending" },
825
+ ];
826
+ return { url: u, status: "pending", identifier: { type: "dns", value: "a.example" }, challenges: chs };
827
+ },
828
+ notifyChallengeReady: async function () { return {}; },
829
+ waitForAuthorization: async function (u) { return { url: u, status: "valid" }; },
830
+ keyAuthorization: function (t) { return t + ".thumb"; },
831
+ tlsAlpn01KeyAuthorization: function (t) { return t + ".alpn"; },
832
+ buildCsr: function () { return "-----BEGIN CERTIFICATE REQUEST-----\nMOCK\n-----END CERTIFICATE REQUEST-----"; },
833
+ finalize: async function () { return { url: "mock://order/1", status: "valid" }; },
834
+ retrieveCert: async function () {
835
+ retrieveCalls += 1;
836
+ if (opts.failRetrieveAfter && retrieveCalls > opts.failRetrieveAfter) {
837
+ if (Object.prototype.hasOwnProperty.call(opts, "retrieveThrowValue")) throw opts.retrieveThrowValue;
838
+ throw new Error("mock retrieveCert failed (network down)");
839
+ }
840
+ return pem;
841
+ },
842
+ renewIfDue: async function () {
843
+ if (opts.onRenewIfDue) opts.onRenewIfDue();
844
+ if (opts.renewIfDueThrows) throw new Error("mock ARI renewalInfo fetch failed");
845
+ return { shouldRenew: !!opts.renewIfDueShould };
846
+ },
847
+ };
848
+ }
849
+
850
+ // ---- _positiveFiniteOrDefault — every rejection + null-defaults path ----
851
+
852
+ function testPositiveFiniteOptRejections() {
853
+ var threw = function (fn) { try { fn(); return null; } catch (e) { return e; } };
854
+ function mk(extra) {
855
+ var base = {
856
+ storage: { type: "sealed-disk", rootDir: _tmpDir(), vault: _ephemeralVault() },
857
+ acme: { directory: "https://example/", accountKey: "auto" },
858
+ certs: [{ name: "m", domains: ["a.com"], challenge: GOOD_CHALLENGE }],
859
+ audit: false,
860
+ };
861
+ return Object.assign(base, extra);
862
+ }
863
+
864
+ // Non-number → throw (typeof branch).
865
+ var eStr = threw(function () { b.cert.create(mk({ renew: { intervalMs: "soon" } })); });
866
+ check("renew.intervalMs non-number → cert/bad-renew-interval", eStr && eStr.code === "cert/bad-renew-interval");
867
+
868
+ // Non-finite (Infinity / NaN) → throw (isFinite branch).
869
+ var eInf = threw(function () { b.cert.create(mk({ ocsp: { refreshMs: Infinity } })); });
870
+ check("ocsp.refreshMs Infinity → cert/bad-ocsp-refresh", eInf && eInf.code === "cert/bad-ocsp-refresh");
871
+ var eNaN = threw(function () { b.cert.create(mk({ renew: { minDaysBeforeExpiry: NaN } })); });
872
+ check("renew.minDaysBeforeExpiry NaN → cert/bad-renew-window", eNaN && eNaN.code === "cert/bad-renew-window");
873
+
874
+ // Zero / negative → throw (<= 0 branch).
875
+ var eZero = threw(function () { b.cert.create(mk({ renew: { intervalMs: 0 } })); });
876
+ check("renew.intervalMs 0 → cert/bad-renew-interval", eZero && eZero.code === "cert/bad-renew-interval");
877
+ var eNeg = threw(function () { b.cert.create(mk({ ocsp: { refreshMs: -5 } })); });
878
+ check("ocsp.refreshMs negative → cert/bad-ocsp-refresh", eNeg && eNeg.code === "cert/bad-ocsp-refresh");
879
+
880
+ // Explicit null → falls back to the default (no throw): exercises the
881
+ // `value === null` short-circuit at the top of _positiveFiniteOrDefault.
882
+ var eNull = threw(function () { b.cert.create(mk({ renew: { intervalMs: null, minDaysBeforeExpiry: null }, ocsp: { refreshMs: null } })); });
883
+ check("null interval/window/refresh → default (no throw)", !eNull);
884
+ }
885
+
886
+ // ---- Manifest size + per-cert shape rejections (uncovered guard rows) ----
887
+
888
+ function testManifestSizeAndShapeRejections() {
889
+ var threw = function (fn) { try { fn(); return null; } catch (e) { return e; } };
890
+ function mk(certs, extraStorage) {
891
+ return {
892
+ storage: Object.assign({ type: "sealed-disk", rootDir: _tmpDir(), vault: _ephemeralVault() }, extraStorage || {}),
893
+ acme: { directory: "https://example/", accountKey: "auto" },
894
+ certs: certs,
895
+ audit: false,
896
+ };
897
+ }
898
+
899
+ // certs array over the manager cap.
900
+ var tooMany = [];
901
+ for (var i = 0; i < 1001; i += 1) {
902
+ tooMany.push({ name: "c" + i, domains: ["a.com"], challenge: GOOD_CHALLENGE });
903
+ }
904
+ var eManyCerts = threw(function () { b.cert.create(mk(tooMany)); });
905
+ check("certs over cap → cert/too-many-certs", eManyCerts && eManyCerts.code === "cert/too-many-certs");
906
+
907
+ // domains array over the per-cert cap.
908
+ var manyDomains = [];
909
+ for (var d = 0; d < 101; d += 1) { manyDomains.push("d" + d + ".example"); }
910
+ var eManyDomains = threw(function () { b.cert.create(mk([{ name: "m", domains: manyDomains, challenge: GOOD_CHALLENGE }])); });
911
+ check("domains over cap → cert/too-many-domains", eManyDomains && eManyDomains.code === "cert/too-many-domains");
912
+
913
+ // A non-string / empty domain entry.
914
+ var eBadDomain = threw(function () { b.cert.create(mk([{ name: "m", domains: ["ok.example", 123], challenge: GOOD_CHALLENGE }])); });
915
+ check("non-string domain entry → cert/bad-domain", eBadDomain && eBadDomain.code === "cert/bad-domain");
916
+ var eEmptyDomain = threw(function () { b.cert.create(mk([{ name: "m", domains: [""], challenge: GOOD_CHALLENGE }])); });
917
+ check("empty-string domain entry → cert/bad-domain", eEmptyDomain && eEmptyDomain.code === "cert/bad-domain");
918
+
919
+ // Missing / non-object challenge block.
920
+ var eNoChallenge = threw(function () { b.cert.create(mk([{ name: "m", domains: ["a.com"] }])); });
921
+ check("missing challenge block → cert/bad-challenge", eNoChallenge && eNoChallenge.code === "cert/bad-challenge");
922
+
923
+ // challenge present but provision/cleanup not both functions.
924
+ var eBadCbs = threw(function () {
925
+ b.cert.create(mk([{ name: "m", domains: ["a.com"], challenge: { type: "http-01", provision: "nope", cleanup: function () {} } }]));
926
+ });
927
+ check("non-function challenge callbacks → cert/bad-challenge-callbacks", eBadCbs && eBadCbs.code === "cert/bad-challenge-callbacks");
928
+
929
+ // keyAlg outside the allowed set.
930
+ var eBadAlg = threw(function () {
931
+ b.cert.create(mk([{ name: "m", domains: ["a.com"], keyAlg: "ecdsa-p521", challenge: GOOD_CHALLENGE }]));
932
+ });
933
+ check("unsupported keyAlg → cert/bad-key-alg", eBadAlg && eBadAlg.code === "cert/bad-key-alg");
934
+
935
+ // keyEscrow present but recipient is neither Buffer nor string.
936
+ var eBadEscrow = threw(function () {
937
+ b.cert.create(mk([{ name: "m", domains: ["a.com"], challenge: GOOD_CHALLENGE, keyEscrow: { recipient: 123 } }]));
938
+ });
939
+ check("keyEscrow recipient wrong type → cert/bad-key-escrow", eBadEscrow && eBadEscrow.code === "cert/bad-key-escrow");
940
+
941
+ // storage.type omitted → the `|| "sealed-disk"` default is taken and
942
+ // create() succeeds (constructs without throwing).
943
+ var eNoType = threw(function () {
944
+ b.cert.create({
945
+ storage: { rootDir: _tmpDir(), vault: _ephemeralVault() },
946
+ acme: { directory: "https://example/", accountKey: "auto" },
947
+ certs: [{ name: "m", domains: ["a.com"], challenge: GOOD_CHALLENGE }],
948
+ audit: false,
949
+ });
950
+ });
951
+ check("omitted storage.type → default sealed-disk (no throw)", !eNoType);
952
+
953
+ // storage.vault omitted → falls back to b.vault.getDefaultStore()
954
+ // (the `opts.vault || vault().getDefaultStore()` default in the
955
+ // storage factory). create() must still succeed.
956
+ var eNoVault = threw(function () {
957
+ b.cert.create({
958
+ storage: { type: "sealed-disk", rootDir: _tmpDir() },
959
+ acme: { directory: "https://example/", accountKey: "auto" },
960
+ certs: [{ name: "m", domains: ["a.com"], challenge: GOOD_CHALLENGE }],
961
+ audit: false,
962
+ });
963
+ });
964
+ check("omitted storage.vault → default store (no throw)", !eNoVault);
965
+ }
966
+
967
+ // ---- getContext / refresh error branches ----
968
+
969
+ function testGetContextAndRefreshErrors() {
970
+ var tmp = _tmpDir();
971
+ var mgr = b.cert.create({
972
+ storage: { type: "sealed-disk", rootDir: tmp, vault: _ephemeralVault() },
973
+ acme: { directory: "https://example/", accountKey: "auto" },
974
+ certs: [{ name: "main", domains: ["example.com"], challenge: GOOD_CHALLENGE }],
975
+ audit: false,
976
+ });
977
+
978
+ var threw = function (fn) { try { fn(); return null; } catch (e) { return e; } };
979
+
980
+ // Unknown name (not in the manifest).
981
+ var eUnknown = threw(function () { mgr.getContext("nope"); });
982
+ check("getContext unknown name → cert/unknown-name", eUnknown && eUnknown.code === "cert/unknown-name");
983
+
984
+ // Declared but not yet loaded (start() never ran).
985
+ var eNotLoaded = threw(function () { mgr.getContext("main"); });
986
+ check("getContext before start → cert/not-loaded", eNotLoaded && eNotLoaded.code === "cert/not-loaded");
987
+
988
+ // refresh() on an unknown name.
989
+ var eRefresh = null;
990
+ return mgr.refresh("nope").then(
991
+ function () { check("refresh unknown name → should reject", false); },
992
+ function (e) { eRefresh = e; check("refresh unknown name → cert/unknown-name", eRefresh && eRefresh.code === "cert/unknown-name"); }
993
+ );
994
+ }
995
+
996
+ // ---- sniCallback error paths: no context + createSecureContext throw ----
997
+
998
+ async function testSniCallbackErrorPaths() {
999
+ // (a) No certs loaded at all → cb(cert/no-context).
1000
+ var tmp = _tmpDir();
1001
+ var mgr = b.cert.create({
1002
+ storage: { type: "sealed-disk", rootDir: tmp, vault: _ephemeralVault() },
1003
+ acme: { directory: "https://example/", accountKey: "auto" },
1004
+ certs: [{ name: "main", domains: ["example.com"], challenge: GOOD_CHALLENGE }],
1005
+ audit: false,
1006
+ });
1007
+ var noCtxErr = await new Promise(function (resolve) {
1008
+ mgr.sniCallback("anything.example", function (err) { resolve(err); });
1009
+ });
1010
+ check("sniCallback with nothing loaded → cert/no-context",
1011
+ noCtxErr && noCtxErr.code === "cert/no-context");
1012
+
1013
+ // (b) A loaded context whose KEY is garbage → tls.createSecureContext
1014
+ // throws and the callback receives that error (the try/catch tail).
1015
+ var tmp2 = _tmpDir();
1016
+ var vault = _ephemeralVault();
1017
+ var pem = await _selfSignedCert(["bad.example"], 90);
1018
+ fs.mkdirSync(path.join(tmp2, "bad"), { recursive: true });
1019
+ fs.writeFileSync(path.join(tmp2, "bad", "cert.pem.sealed"), vault.seal(Buffer.from(pem.certPem)));
1020
+ // Valid cert (so _certMeta parses + the context loads) but an
1021
+ // unparseable private key, so createSecureContext rejects the pair.
1022
+ fs.writeFileSync(path.join(tmp2, "bad", "key.pem.sealed"), vault.seal(Buffer.from("-----BEGIN PRIVATE KEY-----\nnot-a-real-key\n-----END PRIVATE KEY-----\n")));
1023
+ fs.writeFileSync(path.join(tmp2, "bad", "meta.json"), JSON.stringify({
1024
+ expiresAt: Date.now() + 90 * 86400000, issuedAt: Date.now(),
1025
+ fingerprintSha256: "bad", subject: "CN=bad.example",
1026
+ lastRenewedAt: Date.now(), keyAlg: "ecdsa-p256",
1027
+ }));
1028
+ var mgr2 = b.cert.create({
1029
+ storage: { type: "sealed-disk", rootDir: tmp2, vault: vault },
1030
+ acme: { directory: "https://example/", accountKey: "auto" },
1031
+ certs: [{ name: "bad", domains: ["bad.example"], challenge: GOOD_CHALLENGE }],
1032
+ audit: false,
1033
+ });
1034
+ await mgr2.start();
1035
+ var secCtxErr = await new Promise(function (resolve) {
1036
+ mgr2.sniCallback("bad.example", function (err) { resolve(err); });
1037
+ });
1038
+ check("sniCallback with unparseable key → createSecureContext error forwarded", secCtxErr instanceof Error);
1039
+ await mgr2.stop();
1040
+ }
1041
+
1042
+ // ---- start() after stop() is refused ----
1043
+
1044
+ async function testStartAfterStopRejects() {
1045
+ var tmp = _tmpDir();
1046
+ var mgr = b.cert.create({
1047
+ storage: { type: "sealed-disk", rootDir: tmp, vault: _ephemeralVault() },
1048
+ acme: { directory: "https://example/", accountKey: "auto" },
1049
+ certs: [{ name: "main", domains: ["example.com"], challenge: GOOD_CHALLENGE }],
1050
+ audit: false,
1051
+ });
1052
+ await mgr.stop(); // flips the stopped latch without ever starting
1053
+ var threw = null;
1054
+ try { await mgr.start(); } catch (e) { threw = e; }
1055
+ check("start() after stop() → cert/already-stopped", threw && threw.code === "cert/already-stopped");
1056
+ }
1057
+
1058
+ // ---- Full ACME issue flow via an injected stub (no network) ----
1059
+
1060
+ async function testIssueFlowHappyPath() {
1061
+ await helpers.withTestTimeout("cert issue keyAlg matrix", async function () {
1062
+ var tmp = _tmpDir();
1063
+ var vault = _ephemeralVault();
1064
+ var pem = await _selfSignedCert(["issued.example"], 90);
1065
+
1066
+ // Pre-seed a VALID sealed account JWK so _loadOrGenerateAccountKey
1067
+ // takes its read-existing branch (not the generate branch).
1068
+ var acctPair = crypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
1069
+ var acctJwk = acctPair.publicKey.export({ format: "jwk" });
1070
+ acctJwk.privatePem = acctPair.privateKey.export({ type: "pkcs8", format: "pem" });
1071
+ acctJwk.publicPem = acctPair.publicKey.export({ type: "spki", format: "pem" });
1072
+ fs.mkdirSync(path.join(tmp, "account"), { recursive: true });
1073
+ fs.writeFileSync(path.join(tmp, "account", "jwk.json.sealed"), vault.seal(Buffer.from(JSON.stringify(acctJwk))));
1074
+
1075
+ var issued = [];
1076
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem));
1077
+ var mgr = b.cert.create({
1078
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1079
+ acme: { directory: "https://example/", contactEmail: "ops@example.com", accountKey: "auto" },
1080
+ // One cert per keyAlg so every _generateLeafKeypair switch arm runs.
1081
+ // The tls-alpn-01 cert exercises the RFC 8737 key-authorization
1082
+ // branch; the last cert's cleanup throws to exercise the
1083
+ // cleanup-failure drop-silent audit inside _issueCert.
1084
+ certs: [
1085
+ { name: "ec256", domains: ["ec256.example"], keyAlg: "ecdsa-p256", challenge: GOOD_CHALLENGE },
1086
+ { name: "ec384", domains: ["ec384.example"], keyAlg: "ecdsa-p384", challenge: GOOD_CHALLENGE },
1087
+ { name: "rsa2k", domains: ["rsa2k.example"], keyAlg: "rsa-2048", challenge: { type: "dns-01", provision: async function () {}, cleanup: async function () {} } },
1088
+ // rsa3k's cleanup throws an Error with an EMPTY message (so
1089
+ // `cleanupErr.message` is falsy); rsa4k's throws an Error with a
1090
+ // message. Together they cover both arms of the cleanup-failure
1091
+ // audit's `(cleanupErr && cleanupErr.message) || String(cleanupErr)`.
1092
+ { name: "rsa3k", domains: ["rsa3k.example"], keyAlg: "rsa-3072", challenge: { type: "tls-alpn-01", provision: async function () {}, cleanup: async function () { throw new Error(""); } } },
1093
+ { name: "rsa4k", domains: ["rsa4k.example"], keyAlg: "rsa-4096", challenge: { type: "http-01", provision: async function () {}, cleanup: async function () { throw new Error("cleanup boom"); } } },
1094
+ ],
1095
+ ocsp: { stapling: false },
1096
+ audit: false,
1097
+ });
1098
+ mgr.on("cert.issued", function (ev) { issued.push(ev.name); });
1099
+ try {
1100
+ await mgr.start();
1101
+ ["ec256", "ec384", "rsa2k", "rsa3k", "rsa4k"].forEach(function (n) {
1102
+ var ctx = mgr.getContext(n);
1103
+ check("issue: " + n + " context has the retrieved cert PEM",
1104
+ ctx.cert.indexOf("BEGIN CERTIFICATE") !== -1);
1105
+ check("issue: " + n + " context has a fingerprint",
1106
+ typeof ctx.fingerprintSha256 === "string" && ctx.fingerprintSha256.length > 0);
1107
+ // meta.json was persisted to disk by _persistCert.
1108
+ check("issue: " + n + " meta.json persisted",
1109
+ fs.existsSync(path.join(tmp, n, "meta.json")));
1110
+ });
1111
+ check("issue: cert.issued fired for every manifest cert", issued.length === 5);
1112
+ } finally {
1113
+ await mgr.stop();
1114
+ restore();
1115
+ }
1116
+ }, { timeoutMs: 120000 });
1117
+ }
1118
+
1119
+ async function testIssueNoMatchingChallenge() {
1120
+ var tmp = _tmpDir();
1121
+ var vault = _ephemeralVault();
1122
+ var pem = await _selfSignedCert(["nomatch.example"], 90);
1123
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem, { omitChallengeType: true }));
1124
+ var mgr = b.cert.create({
1125
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1126
+ acme: { directory: "https://example/", accountKey: "auto" },
1127
+ // Requests http-01 but the stubbed CA only offers dns-01.
1128
+ certs: [{ name: "m", domains: ["nomatch.example"], challenge: GOOD_CHALLENGE }],
1129
+ ocsp: { stapling: false },
1130
+ audit: false,
1131
+ });
1132
+ var threw = null;
1133
+ try { await mgr.start(); } catch (e) { threw = e; }
1134
+ finally { await mgr.stop(); restore(); }
1135
+ check("issue: CA offers no matching challenge → cert/no-matching-challenge",
1136
+ threw && threw.code === "cert/no-matching-challenge");
1137
+ }
1138
+
1139
+ async function testIssueValidAuthSkipsProvision() {
1140
+ var tmp = _tmpDir();
1141
+ var vault = _ephemeralVault();
1142
+ var pem = await _selfSignedCert(["already.example"], 90);
1143
+ var provisioned = false;
1144
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem, { authValid: true }));
1145
+ var mgr = b.cert.create({
1146
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1147
+ // A provided accountKey object (not "auto") — exercises the
1148
+ // else-arm of `accountKey === "auto" || !accountKey` in _bootAcme
1149
+ // (the manager uses the supplied key rather than generating one).
1150
+ acme: { directory: "https://example/", accountKey: { privatePem: "PRIV", publicPem: "PUB" } },
1151
+ certs: [{ name: "m", domains: ["already.example"],
1152
+ challenge: { type: "http-01", provision: async function () { provisioned = true; }, cleanup: async function () {} } }],
1153
+ ocsp: { stapling: false },
1154
+ audit: false,
1155
+ });
1156
+ try {
1157
+ await mgr.start();
1158
+ // The authorization was already `valid`, so the manager skipped the
1159
+ // challenge solve entirely (the `continue`) and still finalized.
1160
+ check("issue: already-valid authorization skips provision", provisioned === false);
1161
+ check("issue: already-valid authorization still yields a context",
1162
+ mgr.getContext("m").cert.indexOf("BEGIN CERTIFICATE") !== -1);
1163
+ } finally { await mgr.stop(); restore(); }
1164
+ }
1165
+
1166
+ // Key escrow seals the renewed private key to the operator's offline
1167
+ // break-glass recipient (an ML-KEM-1024 keypair from
1168
+ // b.crypto.generateEncryptionKeyPair) via b.crypto.encrypt, writing
1169
+ // <name>/key.pem.escrow. The operator recovers it offline with
1170
+ // b.crypto.decrypt. Issue #446 — the prior implementation called a
1171
+ // nonexistent b.crypto.encryptEnvelope and threw on the first issue.
1172
+ async function testKeyEscrowSealsRecoverableEnvelope() {
1173
+ var tmp = _tmpDir();
1174
+ var vault = _ephemeralVault();
1175
+ var pem = await _selfSignedCert(["escrow.example"], 90);
1176
+ var kp = b.crypto.generateEncryptionKeyPair();
1177
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem));
1178
+ var mgr = b.cert.create({
1179
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1180
+ acme: { directory: "https://example/", accountKey: "auto" },
1181
+ certs: [{ name: "m", domains: ["escrow.example"], challenge: GOOD_CHALLENGE,
1182
+ keyEscrow: { recipient: { publicKey: kp.publicKey, ecPublicKey: kp.ecPublicKey } } }],
1183
+ ocsp: { stapling: false },
1184
+ audit: false,
1185
+ });
1186
+ var threw = null;
1187
+ try { await mgr.start(); } catch (e) { threw = e; }
1188
+ finally { await mgr.stop(); restore(); }
1189
+ check("keyEscrow write path no longer throws", threw === null);
1190
+
1191
+ var escrowPath = path.join(tmp, "m", "key.pem.escrow");
1192
+ check("keyEscrow: escrow envelope written to <name>/key.pem.escrow",
1193
+ fs.existsSync(escrowPath));
1194
+
1195
+ // Break-glass recovery: the offline operator decrypts the escrow with
1196
+ // the recipient private key(s) and gets a usable private-key PEM back.
1197
+ var envelope = fs.readFileSync(escrowPath, "utf8").trim();
1198
+ var recovered = b.crypto.decrypt(envelope,
1199
+ { privateKey: kp.privateKey, ecPrivateKey: kp.ecPrivateKey });
1200
+ var recoveredPem = Buffer.isBuffer(recovered) ? recovered.toString("utf8") : recovered;
1201
+ check("keyEscrow: recovered plaintext is a PEM private key",
1202
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----/.test(recoveredPem));
1203
+
1204
+ // An unrecognized recipient shape is refused at config time.
1205
+ var badThrew = null;
1206
+ try {
1207
+ b.cert.create({
1208
+ storage: { type: "sealed-disk", rootDir: _tmpDir(), vault: _ephemeralVault() },
1209
+ acme: { directory: "https://example/", accountKey: "auto" },
1210
+ certs: [{ name: "b", domains: ["b.example"], challenge: GOOD_CHALLENGE,
1211
+ keyEscrow: { recipient: 123 } }],
1212
+ });
1213
+ } catch (e) { badThrew = e; }
1214
+ check("keyEscrow: non-string / non-object recipient refused at config time",
1215
+ badThrew && badThrew.code === "cert/bad-key-escrow");
1216
+
1217
+ // An object-form recipient with an empty publicKey is refused too: the
1218
+ // object path must require a non-empty key like the string path does, or a
1219
+ // "" key slips through config and fails deeper at b.crypto.encrypt time.
1220
+ var emptyKeyThrew = null;
1221
+ try {
1222
+ b.cert.create({
1223
+ storage: { type: "sealed-disk", rootDir: _tmpDir(), vault: _ephemeralVault() },
1224
+ acme: { directory: "https://example/", accountKey: "auto" },
1225
+ certs: [{ name: "c", domains: ["c.example"], challenge: GOOD_CHALLENGE,
1226
+ keyEscrow: { recipient: { publicKey: "" } } }],
1227
+ });
1228
+ } catch (e) { emptyKeyThrew = e; }
1229
+ check("keyEscrow: object recipient with empty publicKey refused at config time",
1230
+ emptyKeyThrew && emptyKeyThrew.code === "cert/bad-key-escrow");
1231
+
1232
+ // A present-but-empty ecPublicKey (the optional P-384 hybrid leg) is refused
1233
+ // too — an empty hybrid key must not silently downgrade to ML-KEM-only.
1234
+ var emptyEcThrew = null;
1235
+ try {
1236
+ b.cert.create({
1237
+ storage: { type: "sealed-disk", rootDir: _tmpDir(), vault: _ephemeralVault() },
1238
+ acme: { directory: "https://example/", accountKey: "auto" },
1239
+ certs: [{ name: "d", domains: ["d.example"], challenge: GOOD_CHALLENGE,
1240
+ keyEscrow: { recipient: { publicKey: "ml-kem-pem", ecPublicKey: "" } } }],
1241
+ });
1242
+ } catch (e) { emptyEcThrew = e; }
1243
+ check("keyEscrow: object recipient with empty ecPublicKey refused at config time",
1244
+ emptyEcThrew && emptyEcThrew.code === "cert/bad-key-escrow");
1245
+ }
1246
+
1247
+ // ---- Corrupt sealed cert that unseals but won't parse → re-issue ----
1248
+
1249
+ async function testUnparseableSealedCertReissues() {
1250
+ var tmp = _tmpDir();
1251
+ var vault = _ephemeralVault();
1252
+ var keyPem = (await _selfSignedCert(["parse.example"], 90)).keyPem;
1253
+ var pem = await _selfSignedCert(["parse.example"], 90);
1254
+
1255
+ fs.mkdirSync(path.join(tmp, "main"), { recursive: true });
1256
+ // Sealed blob unseals cleanly (XOR vault) but the plaintext is NOT a
1257
+ // certificate, so _certMeta's X509Certificate parse throws and the
1258
+ // manager routes to re-issue (distinct from an unseal failure).
1259
+ fs.writeFileSync(path.join(tmp, "main", "cert.pem.sealed"), vault.seal(Buffer.from("this is definitely not a certificate")));
1260
+ fs.writeFileSync(path.join(tmp, "main", "key.pem.sealed"), vault.seal(Buffer.from(keyPem)));
1261
+ fs.writeFileSync(path.join(tmp, "main", "meta.json"), JSON.stringify({
1262
+ expiresAt: Date.now() + 90 * 86400000, issuedAt: Date.now(),
1263
+ fingerprintSha256: "ff", subject: "CN=parse.example",
1264
+ lastRenewedAt: Date.now(), keyAlg: "ecdsa-p256",
1265
+ }));
1266
+
1267
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem));
1268
+ var mgr = b.cert.create({
1269
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1270
+ acme: { directory: "https://example/", accountKey: "auto" },
1271
+ certs: [{ name: "main", domains: ["parse.example"], challenge: GOOD_CHALLENGE }],
1272
+ ocsp: { stapling: false },
1273
+ audit: false,
1274
+ });
1275
+ try {
1276
+ await mgr.start();
1277
+ check("unparseable sealed cert → re-issued to a valid context",
1278
+ mgr.getContext("main").cert.indexOf("BEGIN CERTIFICATE") !== -1);
1279
+ } finally { await mgr.stop(); restore(); }
1280
+ }
1281
+
1282
+ // ---- readSealed returns a non-Buffer (string) unseal result ----
1283
+
1284
+ async function testReadSealedStringUnseal() {
1285
+ // A vault whose unseal returns a STRING (not a Buffer) — exercises
1286
+ // readSealed's `Buffer.isBuffer(plain) ? plain : Buffer.from(plain)`
1287
+ // else-arm. PEM is ASCII so the utf8 round-trip is lossless.
1288
+ var key = crypto.randomBytes(32);
1289
+ var stringVault = {
1290
+ seal: function (buf) {
1291
+ var out = Buffer.alloc(buf.length);
1292
+ for (var i = 0; i < buf.length; i++) out[i] = buf[i] ^ key[i % key.length];
1293
+ return out;
1294
+ },
1295
+ unseal: function (buf) {
1296
+ var out = Buffer.alloc(buf.length);
1297
+ for (var i = 0; i < buf.length; i++) out[i] = buf[i] ^ key[i % key.length];
1298
+ return out.toString("utf8");
1299
+ },
1300
+ };
1301
+ var tmp = _tmpDir();
1302
+ var pem = await _selfSignedCert(["strvault.example"], 90);
1303
+ fs.mkdirSync(path.join(tmp, "main"), { recursive: true });
1304
+ fs.writeFileSync(path.join(tmp, "main", "cert.pem.sealed"), stringVault.seal(Buffer.from(pem.certPem)));
1305
+ fs.writeFileSync(path.join(tmp, "main", "key.pem.sealed"), stringVault.seal(Buffer.from(pem.keyPem)));
1306
+ fs.writeFileSync(path.join(tmp, "main", "meta.json"), JSON.stringify({
1307
+ expiresAt: Date.now() + 90 * 86400000, issuedAt: Date.now(),
1308
+ fingerprintSha256: "ff", subject: "CN=strvault.example",
1309
+ lastRenewedAt: Date.now(), keyAlg: "ecdsa-p256",
1310
+ }));
1311
+ var mgr = b.cert.create({
1312
+ storage: { type: "sealed-disk", rootDir: tmp, vault: stringVault },
1313
+ acme: { directory: "https://example/", accountKey: "auto" },
1314
+ certs: [{ name: "main", domains: ["strvault.example"], challenge: GOOD_CHALLENGE }],
1315
+ ocsp: { stapling: false },
1316
+ audit: false,
1317
+ });
1318
+ try {
1319
+ await mgr.start();
1320
+ check("readSealed string unseal → context still loads cert PEM",
1321
+ mgr.getContext("main").cert.indexOf("BEGIN CERTIFICATE") !== -1);
1322
+ } finally { await mgr.stop(); }
1323
+ }
1324
+
1325
+ // ---- Renewal scheduler: due cert renews successfully (+ ARI honored) ----
1326
+
1327
+ async function testSchedulerRenewsDueCert() {
1328
+ await helpers.withTestTimeout("scheduler renews due cert", async function () {
1329
+ var tmp = _tmpDir();
1330
+ var vault = _ephemeralVault();
1331
+ var pem = await _selfSignedCert(["renew.example"], 90);
1332
+ var renewed = [];
1333
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem)); // renewIfDue → { shouldRenew:false }
1334
+ var mgr = b.cert.create({
1335
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1336
+ acme: { directory: "https://example/", accountKey: "auto" },
1337
+ certs: [{ name: "main", domains: ["renew.example"], challenge: GOOD_CHALLENGE }],
1338
+ // A huge renewal window forces every scheduler tick to treat the
1339
+ // cert as due; a short interval makes the tick fire promptly.
1340
+ renew: { intervalMs: 30, minDaysBeforeExpiry: 100000 },
1341
+ ocsp: { stapling: false },
1342
+ audit: false,
1343
+ });
1344
+ mgr.on("cert.renewed", function (ev) { renewed.push(ev.name); });
1345
+ try {
1346
+ await mgr.start(); // initial issue (cert.issued), boots acmeClient so ARI runs
1347
+ await helpers.waitUntil(function () { return renewed.length >= 1; },
1348
+ { timeoutMs: 5000, label: "scheduler: cert.renewed fired" });
1349
+ check("scheduler renews a due cert (ARI honored, time-based renew)", renewed.length >= 1);
1350
+ } finally { await mgr.stop(); restore(); }
1351
+ });
1352
+ }
1353
+
1354
+ // ---- Renewal scheduler: renew failure + ARI-fetch failure both survive ----
1355
+
1356
+ async function testSchedulerRenewFailureAndAriCatch() {
1357
+ await helpers.withTestTimeout("scheduler renew failure", async function () {
1358
+ var tmp = _tmpDir();
1359
+ var vault = _ephemeralVault();
1360
+ var pem = await _selfSignedCert(["fail.example"], 90);
1361
+ var failures = [];
1362
+ // First retrieveCert (during start's issue) succeeds; every later one
1363
+ // throws → the scheduled renewal fails. renewIfDue always throws →
1364
+ // the ARI try/catch fall-through is exercised too.
1365
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem, { failRetrieveAfter: 1, renewIfDueThrows: true }));
1366
+ var mgr = b.cert.create({
1367
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1368
+ acme: { directory: "https://example/", accountKey: "auto" },
1369
+ certs: [{ name: "main", domains: ["fail.example"], challenge: GOOD_CHALLENGE }],
1370
+ renew: { intervalMs: 30, minDaysBeforeExpiry: 100000 },
1371
+ ocsp: { stapling: false },
1372
+ audit: false,
1373
+ });
1374
+ mgr.on("cert.renew-failed", function (ev) { failures.push(ev); });
1375
+ try {
1376
+ await mgr.start(); // succeeds (issue #1), meta persisted, acmeClient booted
1377
+ await helpers.waitUntil(function () { return failures.length >= 1; },
1378
+ { timeoutMs: 5000, label: "scheduler: cert.renew-failed fired" });
1379
+ check("scheduler: failed renewal emits cert.renew-failed (ARI throw survived)",
1380
+ failures.length >= 1 && failures[0].name === "main" && failures[0].error);
1381
+ } finally { await mgr.stop(); restore(); }
1382
+
1383
+ // Second manager: the renewal failure carries an EMPTY message, so
1384
+ // the renew-failed audit's `(e && e.message) || String(e)` takes its
1385
+ // String(e) fallback arm.
1386
+ var tmp2 = _tmpDir();
1387
+ var pem2 = await _selfSignedCert(["fail2.example"], 90);
1388
+ var failures2 = [];
1389
+ var restore2 = _stubAcmeCreate(_makeStubAcme(pem2.certPem, { failRetrieveAfter: 1, retrieveThrowValue: new Error("") }));
1390
+ var mgr2 = b.cert.create({
1391
+ storage: { type: "sealed-disk", rootDir: tmp2, vault: _ephemeralVault() },
1392
+ acme: { directory: "https://example/", accountKey: "auto" },
1393
+ certs: [{ name: "main", domains: ["fail2.example"], challenge: GOOD_CHALLENGE }],
1394
+ renew: { intervalMs: 30, minDaysBeforeExpiry: 100000 },
1395
+ ocsp: { stapling: false },
1396
+ audit: false,
1397
+ });
1398
+ mgr2.on("cert.renew-failed", function (ev) { failures2.push(ev); });
1399
+ try {
1400
+ await mgr2.start();
1401
+ await helpers.waitUntil(function () { return failures2.length >= 1; },
1402
+ { timeoutMs: 5000, label: "scheduler: cert.renew-failed (non-Error) fired" });
1403
+ check("scheduler: empty-message renewal failure still emits cert.renew-failed",
1404
+ failures2.length >= 1 && failures2[0].error instanceof Error && failures2[0].error.message === "");
1405
+ } finally { await mgr2.stop(); restore2(); }
1406
+ });
1407
+ }
1408
+
1409
+ // ---- OCSP stapling refresh: success (staple cached) + responder failure ----
1410
+
1411
+ async function testOcspStaplingRefresh() {
1412
+ await helpers.withTestTimeout("ocsp stapling refresh", async function () {
1413
+ var vault = _ephemeralVault();
1414
+ // A two-cert chain (leaf + issuer) so _refreshOcspFor gets past the
1415
+ // "no issuer in the served chain" (chain.length < 2) short-circuit.
1416
+ var leaf = await _selfSignedCert(["ocsp.example"], 90);
1417
+ var issuer = await _selfSignedCert(["issuer.example"], 90);
1418
+ var chainPem = leaf.certPem.trim() + "\n" + issuer.certPem.trim() + "\n";
1419
+
1420
+ function seed(dir) {
1421
+ fs.mkdirSync(path.join(dir, "main"), { recursive: true });
1422
+ fs.writeFileSync(path.join(dir, "main", "cert.pem.sealed"), vault.seal(Buffer.from(chainPem)));
1423
+ fs.writeFileSync(path.join(dir, "main", "key.pem.sealed"), vault.seal(Buffer.from(leaf.keyPem)));
1424
+ fs.writeFileSync(path.join(dir, "main", "meta.json"), JSON.stringify({
1425
+ expiresAt: Date.now() + 90 * 86400000, issuedAt: Date.now(),
1426
+ fingerprintSha256: "ff", subject: "CN=ocsp.example",
1427
+ lastRenewedAt: Date.now(), keyAlg: "ecdsa-p256",
1428
+ }));
1429
+ }
1430
+ function mk(dir) {
1431
+ return b.cert.create({
1432
+ storage: { type: "sealed-disk", rootDir: dir, vault: vault },
1433
+ acme: { directory: "https://example/", accountKey: "auto" },
1434
+ certs: [{ name: "main", domains: ["ocsp.example"], challenge: GOOD_CHALLENGE }],
1435
+ ocsp: { stapling: true, refreshMs: 100000 },
1436
+ audit: false,
1437
+ });
1438
+ }
1439
+
1440
+ // (a) Responder returns a DER — the manager caches it on the context.
1441
+ var tmpA = _tmpDir();
1442
+ seed(tmpA);
1443
+ var restoreA = _stubOcspFetch(async function (o) {
1444
+ check("ocsp.fetch received leaf + issuer PEMs",
1445
+ typeof o.leafPem === "string" && typeof o.issuerPem === "string" && o.leafPem !== o.issuerPem);
1446
+ return { ocspDer: Buffer.from("mock-ocsp-der") };
1447
+ });
1448
+ var mgrA = mk(tmpA);
1449
+ try {
1450
+ await mgrA.start(); // OCSP initial refresh runs in the background
1451
+ var staple = await helpers.waitUntil(function () {
1452
+ var r = mgrA.getContext("main").ocspResponse;
1453
+ return r ? r : false;
1454
+ }, { timeoutMs: 5000, label: "ocsp: staple cached on context" });
1455
+ check("ocsp: validated DER cached on getContext().ocspResponse",
1456
+ Buffer.isBuffer(staple) && staple.toString() === "mock-ocsp-der");
1457
+ } finally { await mgrA.stop(); restoreA(); }
1458
+
1459
+ // (b) Responder throws — the failure is swallowed (fail-soft) and the
1460
+ // staple stays absent; the manager does not crash.
1461
+ var tmpB = _tmpDir();
1462
+ seed(tmpB);
1463
+ var fetchCalls = 0;
1464
+ var restoreB = _stubOcspFetch(async function () {
1465
+ fetchCalls += 1;
1466
+ throw new Error("mock OCSP responder unreachable");
1467
+ });
1468
+ var mgrB = mk(tmpB);
1469
+ try {
1470
+ await mgrB.start();
1471
+ await helpers.waitUntil(function () { return fetchCalls >= 1; },
1472
+ { timeoutMs: 5000, label: "ocsp: responder invoked" });
1473
+ check("ocsp: responder failure is fail-soft (no staple, no crash)",
1474
+ mgrB.getContext("main").ocspResponse === null);
1475
+ } finally { await mgrB.stop(); restoreB(); }
1476
+
1477
+ // (c) Responder throws an Error with an EMPTY message — the
1478
+ // refresh-failed audit's `(e && e.message) || String(e)` takes its
1479
+ // String(e) fallback arm.
1480
+ var tmpC = _tmpDir();
1481
+ seed(tmpC);
1482
+ var fetchCallsC = 0;
1483
+ var restoreC = _stubOcspFetch(async function () { fetchCallsC += 1; throw new Error(""); });
1484
+ var mgrC = mk(tmpC);
1485
+ try {
1486
+ await mgrC.start();
1487
+ await helpers.waitUntil(function () { return fetchCallsC >= 1; },
1488
+ { timeoutMs: 5000, label: "ocsp: empty-message responder invoked" });
1489
+ check("ocsp: empty-message responder failure is also fail-soft",
1490
+ mgrC.getContext("main").ocspResponse === null);
1491
+ } finally { await mgrC.stop(); restoreC(); }
1492
+ });
1493
+ }
1494
+
1495
+ // ---- _certMeta with a cert that carries no SubjectAlternativeName ----
1496
+
1497
+ async function testCertMetaNoSubjectAltName() {
1498
+ // A cert with no SAN extension → the parsed subjectAltName is
1499
+ // undefined and _certMeta falls back to null (the `|| null` arm).
1500
+ var tmp = _tmpDir();
1501
+ var vault = _ephemeralVault();
1502
+ var pem = await _selfSignedCertNoSan("nosan.example", 90);
1503
+ fs.mkdirSync(path.join(tmp, "main"), { recursive: true });
1504
+ fs.writeFileSync(path.join(tmp, "main", "cert.pem.sealed"), vault.seal(Buffer.from(pem.certPem)));
1505
+ fs.writeFileSync(path.join(tmp, "main", "key.pem.sealed"), vault.seal(Buffer.from(pem.keyPem)));
1506
+ fs.writeFileSync(path.join(tmp, "main", "meta.json"), JSON.stringify({
1507
+ expiresAt: Date.now() + 90 * 86400000, issuedAt: Date.now(),
1508
+ fingerprintSha256: "ff", subject: "CN=nosan.example",
1509
+ lastRenewedAt: Date.now(), keyAlg: "ecdsa-p256",
1510
+ }));
1511
+ var mgr = b.cert.create({
1512
+ storage: { type: "sealed-disk", rootDir: tmp, vault: vault },
1513
+ acme: { directory: "https://example/", accountKey: "auto" },
1514
+ certs: [{ name: "main", domains: ["nosan.example"], challenge: GOOD_CHALLENGE }],
1515
+ ocsp: { stapling: false },
1516
+ audit: false,
1517
+ });
1518
+ try {
1519
+ await mgr.start(); // _ensureCert → _certMeta parses the no-SAN cert
1520
+ check("no-SAN cert still loads a usable context",
1521
+ mgr.getContext("main").cert.indexOf("BEGIN CERTIFICATE") !== -1);
1522
+ } finally { await mgr.stop(); }
1523
+ }
1524
+
1525
+ // ---- Renewal scheduler ARI-decision arms with a not-yet-due cert ----
1526
+
1527
+ async function testSchedulerAriDecisionArms() {
1528
+ await helpers.withTestTimeout("scheduler ARI decision arms", async function () {
1529
+ // A freshly-issued cert is comfortably inside its validity window, so
1530
+ // the time-based test says "not due". With the ACME client booted,
1531
+ // each tick still consults ARI. Two managers cover both ARI verdicts:
1532
+ // one where ARI forces a renew (shouldRenew := true), and one where
1533
+ // ARI declines and the tick returns early at `if (!shouldRenew)`.
1534
+ async function runOne(ariSays, label) {
1535
+ var tmp = _tmpDir();
1536
+ var pem = await _selfSignedCert([label + ".example"], 90);
1537
+ var ariCalls = 0;
1538
+ var restore = _stubAcmeCreate(_makeStubAcme(pem.certPem, {
1539
+ renewIfDueShould: ariSays,
1540
+ onRenewIfDue: function () { ariCalls += 1; },
1541
+ }));
1542
+ var mgr = b.cert.create({
1543
+ storage: { type: "sealed-disk", rootDir: tmp, vault: _ephemeralVault() },
1544
+ acme: { directory: "https://example/", accountKey: "auto" },
1545
+ certs: [{ name: "main", domains: [label + ".example"], challenge: GOOD_CHALLENGE }],
1546
+ // Default-ish 14-day window so the fresh 90-day cert is NOT
1547
+ // time-due; the ARI verdict is the only lever this tick.
1548
+ renew: { intervalMs: 30, minDaysBeforeExpiry: 14 },
1549
+ ocsp: { stapling: false },
1550
+ audit: false,
1551
+ });
1552
+ try {
1553
+ await mgr.start(); // issues → boots acmeClient so the ARI branch runs
1554
+ await helpers.waitUntil(function () { return ariCalls >= 1; },
1555
+ { timeoutMs: 5000, label: "scheduler: renewIfDue consulted (" + label + ")" });
1556
+ check("scheduler consults ARI on a not-yet-due cert (" + label + ")", ariCalls >= 1);
1557
+ } finally { await mgr.stop(); restore(); }
1558
+ }
1559
+ await runOne(true, "ariforce"); // ARI true → shouldRenew := true arm
1560
+ await runOne(false, "aridecline"); // ARI false → `if (!shouldRenew) return` arm
1561
+ });
1562
+ }
1563
+
744
1564
  async function run() {
745
1565
  testSurface();
746
1566
  testFactoryRefusesBadOpts();
@@ -754,6 +1574,23 @@ async function run() {
754
1574
  await testCorruptSealedCertReissues();
755
1575
  await testStaleMetaDoesNotServeExpiringCert();
756
1576
  await testCorruptAccountKeyClearError();
1577
+ // Error / adversarial / option-default branch coverage.
1578
+ testPositiveFiniteOptRejections();
1579
+ testManifestSizeAndShapeRejections();
1580
+ await testGetContextAndRefreshErrors();
1581
+ await testSniCallbackErrorPaths();
1582
+ await testStartAfterStopRejects();
1583
+ await testIssueFlowHappyPath();
1584
+ await testIssueNoMatchingChallenge();
1585
+ await testIssueValidAuthSkipsProvision();
1586
+ await testKeyEscrowSealsRecoverableEnvelope();
1587
+ await testUnparseableSealedCertReissues();
1588
+ await testReadSealedStringUnseal();
1589
+ await testCertMetaNoSubjectAltName();
1590
+ await testSchedulerRenewsDueCert();
1591
+ await testSchedulerRenewFailureAndAriCatch();
1592
+ await testSchedulerAriDecisionArms();
1593
+ await testOcspStaplingRefresh();
757
1594
  }
758
1595
 
759
1596
  module.exports = { run: run };