@blamejs/blamejs-shop 0.0.44
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.
- package/CHANGELOG.md +87 -0
- package/LICENSE +17 -0
- package/README.md +117 -0
- package/SECURITY.md +139 -0
- package/lib/admin.js +952 -0
- package/lib/analytics.js +267 -0
- package/lib/cart.js +279 -0
- package/lib/catalog-import.js +344 -0
- package/lib/catalog.js +769 -0
- package/lib/checkout.js +320 -0
- package/lib/config.js +151 -0
- package/lib/customers.js +322 -0
- package/lib/email.js +242 -0
- package/lib/externaldb-d1.js +283 -0
- package/lib/index.js +57 -0
- package/lib/inventory-alerts.js +198 -0
- package/lib/newsletter.js +142 -0
- package/lib/order.js +380 -0
- package/lib/payment.js +318 -0
- package/lib/pricing.js +185 -0
- package/lib/r2-bridge.js +169 -0
- package/lib/shipping.js +185 -0
- package/lib/storefront.js +2160 -0
- package/lib/subscriptions.js +410 -0
- package/lib/tax.js +161 -0
- package/lib/theme.js +194 -0
- package/lib/vendor/MANIFEST.json +19 -0
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +23 -0
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +34 -0
- package/lib/vendor/blamejs/.clusterfuzzlite/project.yaml +16 -0
- package/lib/vendor/blamejs/.dockerignore +45 -0
- package/lib/vendor/blamejs/.gitattributes +42 -0
- package/lib/vendor/blamejs/.github/CODEOWNERS +4 -0
- package/lib/vendor/blamejs/.github/FUNDING.yml +2 -0
- package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/bug_report.md +58 -0
- package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/feature_request.md +99 -0
- package/lib/vendor/blamejs/.github/PULL_REQUEST_TEMPLATE.md +77 -0
- package/lib/vendor/blamejs/.github/dependabot.yml +37 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +148 -0
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +107 -0
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +122 -0
- package/lib/vendor/blamejs/.github/workflows/ci.yml +511 -0
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +50 -0
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +655 -0
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +406 -0
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +101 -0
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +134 -0
- package/lib/vendor/blamejs/.gitignore +102 -0
- package/lib/vendor/blamejs/.gitleaks.toml +166 -0
- package/lib/vendor/blamejs/.hadolint.yaml +18 -0
- package/lib/vendor/blamejs/.npmrc +5 -0
- package/lib/vendor/blamejs/.pinact.yaml +17 -0
- package/lib/vendor/blamejs/ARCHITECTURE.md +158 -0
- package/lib/vendor/blamejs/CHANGELOG.md +1351 -0
- package/lib/vendor/blamejs/CODE_OF_CONDUCT.md +86 -0
- package/lib/vendor/blamejs/CONTRIBUTING.md +156 -0
- package/lib/vendor/blamejs/GOVERNANCE.md +201 -0
- package/lib/vendor/blamejs/LICENSE +201 -0
- package/lib/vendor/blamejs/LTS-CALENDAR.md +29 -0
- package/lib/vendor/blamejs/MIGRATING.md +29 -0
- package/lib/vendor/blamejs/NOTICE +81 -0
- package/lib/vendor/blamejs/README.md +304 -0
- package/lib/vendor/blamejs/SECURITY.md +432 -0
- package/lib/vendor/blamejs/api-snapshot.json +48709 -0
- package/lib/vendor/blamejs/assets/BlameJS_Logo.png +0 -0
- package/lib/vendor/blamejs/assets/BlameJS_Logo.svg +129 -0
- package/lib/vendor/blamejs/bench/README.md +77 -0
- package/lib/vendor/blamejs/bench/_helpers.js +70 -0
- package/lib/vendor/blamejs/bench/baseline.json +183 -0
- package/lib/vendor/blamejs/bench/crypto-hash.bench.js +19 -0
- package/lib/vendor/blamejs/bench/crypto-symmetric.bench.js +28 -0
- package/lib/vendor/blamejs/bench/run.js +140 -0
- package/lib/vendor/blamejs/bench/safe-json.bench.js +31 -0
- package/lib/vendor/blamejs/bin/blamejs.js +13 -0
- package/lib/vendor/blamejs/docker/caddy/Caddyfile +46 -0
- package/lib/vendor/blamejs/docker/coredns/Corefile +37 -0
- package/lib/vendor/blamejs/docker/haproxy/haproxy.cfg +52 -0
- package/lib/vendor/blamejs/docker/init/generate-certs.sh +118 -0
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +87 -0
- package/lib/vendor/blamejs/docker/mitmproxy/config.yaml +16 -0
- package/lib/vendor/blamejs/docker/mongo/init-tls.sh +17 -0
- package/lib/vendor/blamejs/docker/mysql/my.cnf +12 -0
- package/lib/vendor/blamejs/docker/nats/nats.conf +33 -0
- package/lib/vendor/blamejs/docker/postgres/init-tls.sh +17 -0
- package/lib/vendor/blamejs/docker/postgres/postgresql.conf +18 -0
- package/lib/vendor/blamejs/docker/rabbitmq/rabbitmq.conf +18 -0
- package/lib/vendor/blamejs/docker/redis/redis.conf +15 -0
- package/lib/vendor/blamejs/docker/squid/squid.conf +24 -0
- package/lib/vendor/blamejs/docker/syslog/syslog-ng.conf +34 -0
- package/lib/vendor/blamejs/docker-compose.test.yml +545 -0
- package/lib/vendor/blamejs/docs/cis-postgres-crosswalk.md +102 -0
- package/lib/vendor/blamejs/docs/cis-sqlite-equivalent.md +92 -0
- package/lib/vendor/blamejs/eslint.config.mjs +204 -0
- package/lib/vendor/blamejs/examples/wiki/Caddyfile +40 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +218 -0
- package/lib/vendor/blamejs/examples/wiki/Dockerfile +120 -0
- package/lib/vendor/blamejs/examples/wiki/README.md +157 -0
- package/lib/vendor/blamejs/examples/wiki/cli-snapshot.json +250 -0
- package/lib/vendor/blamejs/examples/wiki/docker-compose.prod.yml +231 -0
- package/lib/vendor/blamejs/examples/wiki/docker-compose.yml +166 -0
- package/lib/vendor/blamejs/examples/wiki/env-snapshot.json +217 -0
- package/lib/vendor/blamejs/examples/wiki/lib/auto-site-entries.js +139 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +555 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-cli.js +507 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-env-vars.js +435 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-errors.js +282 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-vendored-deps.js +321 -0
- package/lib/vendor/blamejs/examples/wiki/lib/nav.js +15 -0
- package/lib/vendor/blamejs/examples/wiki/lib/opts-resolver.js +75 -0
- package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +508 -0
- package/lib/vendor/blamejs/examples/wiki/lib/section.js +276 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +587 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +318 -0
- package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +122 -0
- package/lib/vendor/blamejs/examples/wiki/migrations/0001-pages-schema.js +74 -0
- package/lib/vendor/blamejs/examples/wiki/package.json +18 -0
- package/lib/vendor/blamejs/examples/wiki/public/img/blamejs-logo.png +0 -0
- package/lib/vendor/blamejs/examples/wiki/public/img/blamejs-logo.svg +129 -0
- package/lib/vendor/blamejs/examples/wiki/public/robots.txt +5 -0
- package/lib/vendor/blamejs/examples/wiki/public/vendor/MANIFEST.json +30 -0
- package/lib/vendor/blamejs/examples/wiki/public/vendor/prism.css +1 -0
- package/lib/vendor/blamejs/examples/wiki/public/vendor/prism.js +15 -0
- package/lib/vendor/blamejs/examples/wiki/public/wiki.css +1250 -0
- package/lib/vendor/blamejs/examples/wiki/routes/admin.js +366 -0
- package/lib/vendor/blamejs/examples/wiki/routes/integration.js +230 -0
- package/lib/vendor/blamejs/examples/wiki/routes/pages.js +266 -0
- package/lib/vendor/blamejs/examples/wiki/scripts/backfill-module-metadata.js +214 -0
- package/lib/vendor/blamejs/examples/wiki/seeders/prod/0001-default-pages.js +35 -0
- package/lib/vendor/blamejs/examples/wiki/seeders/prod/pages/_index.js +34 -0
- package/lib/vendor/blamejs/examples/wiki/seeders/prod/pages/api.js +76 -0
- package/lib/vendor/blamejs/examples/wiki/server.js +129 -0
- package/lib/vendor/blamejs/examples/wiki/site.config.js +197 -0
- package/lib/vendor/blamejs/examples/wiki/snippets/README.md +38 -0
- package/lib/vendor/blamejs/examples/wiki/snippets/auth/password-hash.example.js +15 -0
- package/lib/vendor/blamejs/examples/wiki/src/editor.js +103 -0
- package/lib/vendor/blamejs/examples/wiki/src/wiki.js +349 -0
- package/lib/vendor/blamejs/examples/wiki/test/AUDIT.md +155 -0
- package/lib/vendor/blamejs/examples/wiki/test/codebase-patterns.test.js +594 -0
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +741 -0
- package/lib/vendor/blamejs/examples/wiki/test/find-missing-pages.js +254 -0
- package/lib/vendor/blamejs/examples/wiki/test/integration.js +391 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-cli-snapshot.js +379 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-env-snapshot.js +346 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-nav-coverage.js +212 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-site-coverage.js +252 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-source-comment-blocks.js +107 -0
- package/lib/vendor/blamejs/examples/wiki/views/_layout.html +115 -0
- package/lib/vendor/blamejs/examples/wiki/views/admin/api-keys.html +51 -0
- package/lib/vendor/blamejs/examples/wiki/views/admin/dashboard.html +22 -0
- package/lib/vendor/blamejs/examples/wiki/views/admin/edit.html +17 -0
- package/lib/vendor/blamejs/examples/wiki/views/home.html +85 -0
- package/lib/vendor/blamejs/examples/wiki/views/login.html +18 -0
- package/lib/vendor/blamejs/examples/wiki/views/page.html +5 -0
- package/lib/vendor/blamejs/examples/wiki/views/partials/nav.html +13 -0
- package/lib/vendor/blamejs/examples/wiki/views/search.html +19 -0
- package/lib/vendor/blamejs/examples/wiki/wiki.config.js +15 -0
- package/lib/vendor/blamejs/fuzz/README.md +137 -0
- package/lib/vendor/blamejs/fuzz/_expected.js +35 -0
- package/lib/vendor/blamejs/fuzz/guard-agent-registry.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-csv.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/01-basic.csv +3 -0
- package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/02-formula.csv +1 -0
- package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/03-hyperlink.csv +1 -0
- package/lib/vendor/blamejs/fuzz/guard-dsn.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-email.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-email_seed_corpus/01-basic.eml +5 -0
- package/lib/vendor/blamejs/fuzz/guard-envelope.fuzz.js +24 -0
- package/lib/vendor/blamejs/fuzz/guard-event-bus-payload.fuzz.js +24 -0
- package/lib/vendor/blamejs/fuzz/guard-event-bus-topic.fuzz.js +20 -0
- package/lib/vendor/blamejs/fuzz/guard-html.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/01-basic.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/02-script.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/03-event.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/04-jsurl.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-idempotency-key.fuzz.js +20 -0
- package/lib/vendor/blamejs/fuzz/guard-imap-command.fuzz.js +35 -0
- package/lib/vendor/blamejs/fuzz/guard-jmap.fuzz.js +41 -0
- package/lib/vendor/blamejs/fuzz/guard-json.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/01-basic.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/02-proto.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/03-dupkey.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/04-nan.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/05-bom.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-list-id.fuzz.js +21 -0
- package/lib/vendor/blamejs/fuzz/guard-list-unsubscribe.fuzz.js +25 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-compose.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-move.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-query.fuzz.js +27 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-reply.fuzz.js +23 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-sieve.fuzz.js +36 -0
- package/lib/vendor/blamejs/fuzz/guard-managesieve-command.fuzz.js +26 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/01-basic.md +2 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/02-jsurl.md +1 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/03-jsimg.md +1 -0
- package/lib/vendor/blamejs/fuzz/guard-message-id.fuzz.js +26 -0
- package/lib/vendor/blamejs/fuzz/guard-pop3-command.fuzz.js +23 -0
- package/lib/vendor/blamejs/fuzz/guard-posture-chain.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-saga-config.fuzz.js +32 -0
- package/lib/vendor/blamejs/fuzz/guard-smtp-command.fuzz.js +27 -0
- package/lib/vendor/blamejs/fuzz/guard-snapshot-envelope.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-stream-args.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-svg.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-svg_seed_corpus/01-basic.svg +1 -0
- package/lib/vendor/blamejs/fuzz/guard-svg_seed_corpus/02-script.svg +1 -0
- package/lib/vendor/blamejs/fuzz/guard-tenant-id.fuzz.js +20 -0
- package/lib/vendor/blamejs/fuzz/guard-trace-context.fuzz.js +30 -0
- package/lib/vendor/blamejs/fuzz/guard-xml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-xml_seed_corpus/01-basic.xml +1 -0
- package/lib/vendor/blamejs/fuzz/guard-xml_seed_corpus/02-xxe.xml +1 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/01-basic.yaml +2 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/02-anchor.yaml +2 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/03-norway.yaml +1 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/04-multidoc.yaml +4 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-ini.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-ini_seed_corpus/01-basic.ini +2 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-toml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-toml_seed_corpus/01-basic.toml +4 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-xml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-xml_seed_corpus/01-basic.xml +1 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-yaml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-yaml_seed_corpus/01-basic.yaml +4 -0
- package/lib/vendor/blamejs/fuzz/safe-decompress.fuzz.js +49 -0
- package/lib/vendor/blamejs/fuzz/safe-dns.fuzz.js +29 -0
- package/lib/vendor/blamejs/fuzz/safe-ical.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/safe-icap.fuzz.js +42 -0
- package/lib/vendor/blamejs/fuzz/safe-json.fuzz.js +25 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/01-object.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/02-array.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/03-string.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/04-proto.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/05-deep.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/01-basic.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/02-filter.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/03-deepscan.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/04-slice.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-mime.fuzz.js +27 -0
- package/lib/vendor/blamejs/fuzz/safe-mount-info.fuzz.js +33 -0
- package/lib/vendor/blamejs/fuzz/safe-sieve.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/safe-smtp.fuzz.js +64 -0
- package/lib/vendor/blamejs/fuzz/safe-url.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/01-basic.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/02-userinfo.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/03-dangerous.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/04-data.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/05-ipv6.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/06-idn.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-vcard.fuzz.js +16 -0
- package/lib/vendor/blamejs/index.js +678 -0
- package/lib/vendor/blamejs/keys/release-pqc-pub.json +7 -0
- package/lib/vendor/blamejs/lib/_test/crypto-fixtures.js +67 -0
- package/lib/vendor/blamejs/lib/a2a-tasks.js +598 -0
- package/lib/vendor/blamejs/lib/a2a.js +407 -0
- package/lib/vendor/blamejs/lib/acme.js +1448 -0
- package/lib/vendor/blamejs/lib/agent-audit.js +45 -0
- package/lib/vendor/blamejs/lib/agent-event-bus.js +382 -0
- package/lib/vendor/blamejs/lib/agent-idempotency.js +497 -0
- package/lib/vendor/blamejs/lib/agent-orchestrator.js +717 -0
- package/lib/vendor/blamejs/lib/agent-posture-chain.js +366 -0
- package/lib/vendor/blamejs/lib/agent-saga.js +321 -0
- package/lib/vendor/blamejs/lib/agent-snapshot.js +676 -0
- package/lib/vendor/blamejs/lib/agent-stream.js +269 -0
- package/lib/vendor/blamejs/lib/agent-tenant.js +632 -0
- package/lib/vendor/blamejs/lib/agent-trace.js +281 -0
- package/lib/vendor/blamejs/lib/ai-adverse-decision.js +184 -0
- package/lib/vendor/blamejs/lib/ai-content-detect.js +268 -0
- package/lib/vendor/blamejs/lib/ai-input.js +201 -0
- package/lib/vendor/blamejs/lib/ai-model-manifest.js +363 -0
- package/lib/vendor/blamejs/lib/ai-pref.js +340 -0
- package/lib/vendor/blamejs/lib/api-key.js +721 -0
- package/lib/vendor/blamejs/lib/api-snapshot.js +458 -0
- package/lib/vendor/blamejs/lib/app-shutdown.js +557 -0
- package/lib/vendor/blamejs/lib/app.js +365 -0
- package/lib/vendor/blamejs/lib/archive.js +547 -0
- package/lib/vendor/blamejs/lib/arg-parser.js +697 -0
- package/lib/vendor/blamejs/lib/argon2-builtin.js +173 -0
- package/lib/vendor/blamejs/lib/asn1-der.js +424 -0
- package/lib/vendor/blamejs/lib/asyncapi-bindings.js +160 -0
- package/lib/vendor/blamejs/lib/asyncapi-traits.js +143 -0
- package/lib/vendor/blamejs/lib/asyncapi.js +575 -0
- package/lib/vendor/blamejs/lib/atomic-file.js +1023 -0
- package/lib/vendor/blamejs/lib/audit-chain.js +266 -0
- package/lib/vendor/blamejs/lib/audit-daily-review.js +389 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +751 -0
- package/lib/vendor/blamejs/lib/audit-tools.js +1113 -0
- package/lib/vendor/blamejs/lib/audit.js +1671 -0
- package/lib/vendor/blamejs/lib/auth/aal.js +169 -0
- package/lib/vendor/blamejs/lib/auth/access-lock.js +220 -0
- package/lib/vendor/blamejs/lib/auth/acr-vocabulary.js +265 -0
- package/lib/vendor/blamejs/lib/auth/ato-kill-switch.js +112 -0
- package/lib/vendor/blamejs/lib/auth/auth-time-tracker.js +111 -0
- package/lib/vendor/blamejs/lib/auth/bot-challenge.js +573 -0
- package/lib/vendor/blamejs/lib/auth/ciba.js +637 -0
- package/lib/vendor/blamejs/lib/auth/dpop.js +516 -0
- package/lib/vendor/blamejs/lib/auth/elevation-grant.js +306 -0
- package/lib/vendor/blamejs/lib/auth/fal.js +229 -0
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +681 -0
- package/lib/vendor/blamejs/lib/auth/jwt-external.js +519 -0
- package/lib/vendor/blamejs/lib/auth/jwt.js +430 -0
- package/lib/vendor/blamejs/lib/auth/lockout.js +449 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +2141 -0
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +657 -0
- package/lib/vendor/blamejs/lib/auth/oid4vp.js +531 -0
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +600 -0
- package/lib/vendor/blamejs/lib/auth/passkey.js +676 -0
- package/lib/vendor/blamejs/lib/auth/password.js +693 -0
- package/lib/vendor/blamejs/lib/auth/saml.js +2109 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-disclosure.js +95 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +225 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +197 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +728 -0
- package/lib/vendor/blamejs/lib/auth/status-list.js +272 -0
- package/lib/vendor/blamejs/lib/auth/step-up-policy.js +335 -0
- package/lib/vendor/blamejs/lib/auth/step-up.js +454 -0
- package/lib/vendor/blamejs/lib/auth-bot-challenge.js +505 -0
- package/lib/vendor/blamejs/lib/auth-header.js +148 -0
- package/lib/vendor/blamejs/lib/backup/bundle.js +265 -0
- package/lib/vendor/blamejs/lib/backup/crypto.js +176 -0
- package/lib/vendor/blamejs/lib/backup/index.js +1001 -0
- package/lib/vendor/blamejs/lib/backup/manifest.js +443 -0
- package/lib/vendor/blamejs/lib/boot-gates.js +174 -0
- package/lib/vendor/blamejs/lib/breach-deadline.js +272 -0
- package/lib/vendor/blamejs/lib/break-glass.js +1753 -0
- package/lib/vendor/blamejs/lib/budr.js +205 -0
- package/lib/vendor/blamejs/lib/bundler.js +461 -0
- package/lib/vendor/blamejs/lib/cache-redis.js +256 -0
- package/lib/vendor/blamejs/lib/cache-status.js +288 -0
- package/lib/vendor/blamejs/lib/cache.js +1331 -0
- package/lib/vendor/blamejs/lib/calendar.js +1240 -0
- package/lib/vendor/blamejs/lib/canonical-json.js +143 -0
- package/lib/vendor/blamejs/lib/cdn-cache-control.js +473 -0
- package/lib/vendor/blamejs/lib/cert.js +763 -0
- package/lib/vendor/blamejs/lib/chain-writer.js +259 -0
- package/lib/vendor/blamejs/lib/circuit-breaker.js +101 -0
- package/lib/vendor/blamejs/lib/cli-helpers.js +237 -0
- package/lib/vendor/blamejs/lib/cli.js +2328 -0
- package/lib/vendor/blamejs/lib/client-hints.js +318 -0
- package/lib/vendor/blamejs/lib/cloud-events.js +277 -0
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +317 -0
- package/lib/vendor/blamejs/lib/cluster-storage.js +351 -0
- package/lib/vendor/blamejs/lib/cluster.js +1017 -0
- package/lib/vendor/blamejs/lib/cms-codec.js +826 -0
- package/lib/vendor/blamejs/lib/codepoint-class.js +262 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +190 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +205 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-risk.js +189 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +200 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +821 -0
- package/lib/vendor/blamejs/lib/compliance-eaa.js +204 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions-aliases.js +167 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +206 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions-fuzzy.js +297 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions.js +569 -0
- package/lib/vendor/blamejs/lib/compliance.js +1558 -0
- package/lib/vendor/blamejs/lib/config-drift.js +426 -0
- package/lib/vendor/blamejs/lib/config.js +446 -0
- package/lib/vendor/blamejs/lib/consent.js +369 -0
- package/lib/vendor/blamejs/lib/constants.js +209 -0
- package/lib/vendor/blamejs/lib/content-credentials.js +704 -0
- package/lib/vendor/blamejs/lib/cookies.js +560 -0
- package/lib/vendor/blamejs/lib/cra-report.js +299 -0
- package/lib/vendor/blamejs/lib/credential-hash.js +394 -0
- package/lib/vendor/blamejs/lib/crypto-field.js +1017 -0
- package/lib/vendor/blamejs/lib/crypto-hpke-pq.js +187 -0
- package/lib/vendor/blamejs/lib/crypto-hpke.js +256 -0
- package/lib/vendor/blamejs/lib/crypto.js +1908 -0
- package/lib/vendor/blamejs/lib/csp.js +271 -0
- package/lib/vendor/blamejs/lib/csv.js +418 -0
- package/lib/vendor/blamejs/lib/daemon.js +481 -0
- package/lib/vendor/blamejs/lib/dark-patterns.js +488 -0
- package/lib/vendor/blamejs/lib/data-act.js +328 -0
- package/lib/vendor/blamejs/lib/db-collection.js +587 -0
- package/lib/vendor/blamejs/lib/db-declare-row-policy.js +267 -0
- package/lib/vendor/blamejs/lib/db-declare-view.js +420 -0
- package/lib/vendor/blamejs/lib/db-file-lifecycle.js +333 -0
- package/lib/vendor/blamejs/lib/db-query.js +802 -0
- package/lib/vendor/blamejs/lib/db-role-context.js +50 -0
- package/lib/vendor/blamejs/lib/db-schema.js +322 -0
- package/lib/vendor/blamejs/lib/db.js +3111 -0
- package/lib/vendor/blamejs/lib/dbsc.js +299 -0
- package/lib/vendor/blamejs/lib/ddl-change-control.js +523 -0
- package/lib/vendor/blamejs/lib/deprecate.js +377 -0
- package/lib/vendor/blamejs/lib/dev.js +405 -0
- package/lib/vendor/blamejs/lib/dora.js +402 -0
- package/lib/vendor/blamejs/lib/dr-runbook.js +368 -0
- package/lib/vendor/blamejs/lib/dsr.js +1188 -0
- package/lib/vendor/blamejs/lib/dual-control.js +526 -0
- package/lib/vendor/blamejs/lib/early-hints.js +212 -0
- package/lib/vendor/blamejs/lib/error-page.js +420 -0
- package/lib/vendor/blamejs/lib/events.js +214 -0
- package/lib/vendor/blamejs/lib/external-db-migrate.js +659 -0
- package/lib/vendor/blamejs/lib/external-db.js +1877 -0
- package/lib/vendor/blamejs/lib/fapi2.js +394 -0
- package/lib/vendor/blamejs/lib/fda-21cfr11.js +395 -0
- package/lib/vendor/blamejs/lib/fdx.js +370 -0
- package/lib/vendor/blamejs/lib/fedcm.js +264 -0
- package/lib/vendor/blamejs/lib/file-type.js +360 -0
- package/lib/vendor/blamejs/lib/file-upload.js +1256 -0
- package/lib/vendor/blamejs/lib/flag-cache.js +136 -0
- package/lib/vendor/blamejs/lib/flag-evaluation-context.js +135 -0
- package/lib/vendor/blamejs/lib/flag-providers.js +279 -0
- package/lib/vendor/blamejs/lib/flag-targeting.js +210 -0
- package/lib/vendor/blamejs/lib/flag.js +346 -0
- package/lib/vendor/blamejs/lib/forms.js +525 -0
- package/lib/vendor/blamejs/lib/framework-error.js +724 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +845 -0
- package/lib/vendor/blamejs/lib/framework-sha1-hibp.js +34 -0
- package/lib/vendor/blamejs/lib/fsm.js +469 -0
- package/lib/vendor/blamejs/lib/gate-contract.js +1661 -0
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +261 -0
- package/lib/vendor/blamejs/lib/graphql-federation.js +234 -0
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +179 -0
- package/lib/vendor/blamejs/lib/guard-all.js +555 -0
- package/lib/vendor/blamejs/lib/guard-archive.js +901 -0
- package/lib/vendor/blamejs/lib/guard-auth.js +451 -0
- package/lib/vendor/blamejs/lib/guard-cidr.js +676 -0
- package/lib/vendor/blamejs/lib/guard-csv.js +1176 -0
- package/lib/vendor/blamejs/lib/guard-domain.js +814 -0
- package/lib/vendor/blamejs/lib/guard-dsn.js +382 -0
- package/lib/vendor/blamejs/lib/guard-email.js +951 -0
- package/lib/vendor/blamejs/lib/guard-envelope.js +294 -0
- package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +217 -0
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +150 -0
- package/lib/vendor/blamejs/lib/guard-filename.js +956 -0
- package/lib/vendor/blamejs/lib/guard-graphql.js +731 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-aria.js +164 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-forms.js +144 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-tables.js +154 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-tagwalk.js +44 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag.js +470 -0
- package/lib/vendor/blamejs/lib/guard-html.js +1209 -0
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +151 -0
- package/lib/vendor/blamejs/lib/guard-image.js +584 -0
- package/lib/vendor/blamejs/lib/guard-imap-command.js +337 -0
- package/lib/vendor/blamejs/lib/guard-jmap.js +321 -0
- package/lib/vendor/blamejs/lib/guard-json.js +935 -0
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +512 -0
- package/lib/vendor/blamejs/lib/guard-jwt.js +772 -0
- package/lib/vendor/blamejs/lib/guard-list-id.js +318 -0
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +412 -0
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +282 -0
- package/lib/vendor/blamejs/lib/guard-mail-move.js +202 -0
- package/lib/vendor/blamejs/lib/guard-mail-query.js +310 -0
- package/lib/vendor/blamejs/lib/guard-mail-reply.js +172 -0
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +207 -0
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +566 -0
- package/lib/vendor/blamejs/lib/guard-markdown.js +768 -0
- package/lib/vendor/blamejs/lib/guard-message-id.js +267 -0
- package/lib/vendor/blamejs/lib/guard-mime.js +609 -0
- package/lib/vendor/blamejs/lib/guard-oauth.js +650 -0
- package/lib/vendor/blamejs/lib/guard-pdf.js +569 -0
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +317 -0
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +201 -0
- package/lib/vendor/blamejs/lib/guard-regex.js +632 -0
- package/lib/vendor/blamejs/lib/guard-saga-config.js +157 -0
- package/lib/vendor/blamejs/lib/guard-shell.js +522 -0
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +594 -0
- package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +168 -0
- package/lib/vendor/blamejs/lib/guard-stream-args.js +166 -0
- package/lib/vendor/blamejs/lib/guard-svg.js +1163 -0
- package/lib/vendor/blamejs/lib/guard-template.js +490 -0
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +138 -0
- package/lib/vendor/blamejs/lib/guard-time.js +586 -0
- package/lib/vendor/blamejs/lib/guard-trace-context.js +172 -0
- package/lib/vendor/blamejs/lib/guard-uuid.js +548 -0
- package/lib/vendor/blamejs/lib/guard-xml.js +666 -0
- package/lib/vendor/blamejs/lib/guard-yaml.js +726 -0
- package/lib/vendor/blamejs/lib/hal.js +125 -0
- package/lib/vendor/blamejs/lib/handlers.js +350 -0
- package/lib/vendor/blamejs/lib/honeytoken.js +168 -0
- package/lib/vendor/blamejs/lib/html-balance.js +347 -0
- package/lib/vendor/blamejs/lib/http-client-cache.js +923 -0
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +519 -0
- package/lib/vendor/blamejs/lib/http-client.js +2152 -0
- package/lib/vendor/blamejs/lib/http-message-signature.js +589 -0
- package/lib/vendor/blamejs/lib/http2-teardown.js +34 -0
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +398 -0
- package/lib/vendor/blamejs/lib/i18n.js +931 -0
- package/lib/vendor/blamejs/lib/iab-mspa.js +257 -0
- package/lib/vendor/blamejs/lib/iab-tcf.js +461 -0
- package/lib/vendor/blamejs/lib/importmap-integrity.js +90 -0
- package/lib/vendor/blamejs/lib/inbox.js +435 -0
- package/lib/vendor/blamejs/lib/incident-report.js +314 -0
- package/lib/vendor/blamejs/lib/ip-utils.js +102 -0
- package/lib/vendor/blamejs/lib/jobs.js +185 -0
- package/lib/vendor/blamejs/lib/jose-jwe-experimental.js +228 -0
- package/lib/vendor/blamejs/lib/jsonapi.js +230 -0
- package/lib/vendor/blamejs/lib/keychain.js +865 -0
- package/lib/vendor/blamejs/lib/lazy-require.js +48 -0
- package/lib/vendor/blamejs/lib/legal-hold.js +374 -0
- package/lib/vendor/blamejs/lib/local-db-thin.js +321 -0
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +369 -0
- package/lib/vendor/blamejs/lib/log-stream-local.js +146 -0
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +410 -0
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +286 -0
- package/lib/vendor/blamejs/lib/log-stream-syslog.js +310 -0
- package/lib/vendor/blamejs/lib/log-stream-webhook.js +199 -0
- package/lib/vendor/blamejs/lib/log-stream.js +584 -0
- package/lib/vendor/blamejs/lib/log.js +625 -0
- package/lib/vendor/blamejs/lib/lro.js +200 -0
- package/lib/vendor/blamejs/lib/mail-agent.js +786 -0
- package/lib/vendor/blamejs/lib/mail-arc-sign.js +417 -0
- package/lib/vendor/blamejs/lib/mail-arf.js +343 -0
- package/lib/vendor/blamejs/lib/mail-auth.js +2144 -0
- package/lib/vendor/blamejs/lib/mail-bimi.js +1047 -0
- package/lib/vendor/blamejs/lib/mail-bounce.js +955 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +1286 -0
- package/lib/vendor/blamejs/lib/mail-crypto-smime.js +789 -0
- package/lib/vendor/blamejs/lib/mail-crypto.js +108 -0
- package/lib/vendor/blamejs/lib/mail-dav.js +1224 -0
- package/lib/vendor/blamejs/lib/mail-deploy.js +1119 -0
- package/lib/vendor/blamejs/lib/mail-dkim.js +1250 -0
- package/lib/vendor/blamejs/lib/mail-greylist.js +448 -0
- package/lib/vendor/blamejs/lib/mail-helo.js +473 -0
- package/lib/vendor/blamejs/lib/mail-journal.js +435 -0
- package/lib/vendor/blamejs/lib/mail-mdn.js +424 -0
- package/lib/vendor/blamejs/lib/mail-rbl.js +392 -0
- package/lib/vendor/blamejs/lib/mail-require-tls.js +198 -0
- package/lib/vendor/blamejs/lib/mail-scan.js +502 -0
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +629 -0
- package/lib/vendor/blamejs/lib/mail-server-imap.js +1858 -0
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +1565 -0
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +908 -0
- package/lib/vendor/blamejs/lib/mail-server-mx.js +969 -0
- package/lib/vendor/blamejs/lib/mail-server-pop3.js +915 -0
- package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +315 -0
- package/lib/vendor/blamejs/lib/mail-server-registry.js +378 -0
- package/lib/vendor/blamejs/lib/mail-server-submission.js +1396 -0
- package/lib/vendor/blamejs/lib/mail-server-tls.js +445 -0
- package/lib/vendor/blamejs/lib/mail-sieve.js +557 -0
- package/lib/vendor/blamejs/lib/mail-spam-score.js +284 -0
- package/lib/vendor/blamejs/lib/mail-srs.js +248 -0
- package/lib/vendor/blamejs/lib/mail-store-fts.js +394 -0
- package/lib/vendor/blamejs/lib/mail-store.js +929 -0
- package/lib/vendor/blamejs/lib/mail-unsubscribe.js +400 -0
- package/lib/vendor/blamejs/lib/mail.js +1971 -0
- package/lib/vendor/blamejs/lib/mcp-tool-registry.js +473 -0
- package/lib/vendor/blamejs/lib/mcp.js +950 -0
- package/lib/vendor/blamejs/lib/metrics.js +1503 -0
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +177 -0
- package/lib/vendor/blamejs/lib/middleware/ai-act-disclosure.js +203 -0
- package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +981 -0
- package/lib/vendor/blamejs/lib/middleware/assetlinks.js +137 -0
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +171 -0
- package/lib/vendor/blamejs/lib/middleware/attach-user.js +220 -0
- package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +293 -0
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +1519 -0
- package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +183 -0
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +217 -0
- package/lib/vendor/blamejs/lib/middleware/clear-site-data.js +122 -0
- package/lib/vendor/blamejs/lib/middleware/compose-pipeline.js +355 -0
- package/lib/vendor/blamejs/lib/middleware/compression.js +489 -0
- package/lib/vendor/blamejs/lib/middleware/cookies.js +130 -0
- package/lib/vendor/blamejs/lib/middleware/cors.js +386 -0
- package/lib/vendor/blamejs/lib/middleware/csp-nonce.js +388 -0
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +167 -0
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +499 -0
- package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +243 -0
- package/lib/vendor/blamejs/lib/middleware/db-role-for.js +304 -0
- package/lib/vendor/blamejs/lib/middleware/dpop.js +402 -0
- package/lib/vendor/blamejs/lib/middleware/error-handler.js +69 -0
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +168 -0
- package/lib/vendor/blamejs/lib/middleware/flag-context.js +110 -0
- package/lib/vendor/blamejs/lib/middleware/gpc.js +153 -0
- package/lib/vendor/blamejs/lib/middleware/headers.js +242 -0
- package/lib/vendor/blamejs/lib/middleware/health.js +438 -0
- package/lib/vendor/blamejs/lib/middleware/host-allowlist.js +189 -0
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +964 -0
- package/lib/vendor/blamejs/lib/middleware/index.js +183 -0
- package/lib/vendor/blamejs/lib/middleware/nel.js +214 -0
- package/lib/vendor/blamejs/lib/middleware/network-allowlist.js +237 -0
- package/lib/vendor/blamejs/lib/middleware/no-cache.js +106 -0
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +177 -0
- package/lib/vendor/blamejs/lib/middleware/protected-resource-metadata.js +277 -0
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +556 -0
- package/lib/vendor/blamejs/lib/middleware/request-id.js +79 -0
- package/lib/vendor/blamejs/lib/middleware/request-log.js +205 -0
- package/lib/vendor/blamejs/lib/middleware/require-aal.js +138 -0
- package/lib/vendor/blamejs/lib/middleware/require-auth.js +144 -0
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +290 -0
- package/lib/vendor/blamejs/lib/middleware/require-content-type.js +113 -0
- package/lib/vendor/blamejs/lib/middleware/require-methods.js +97 -0
- package/lib/vendor/blamejs/lib/middleware/require-mtls.js +212 -0
- package/lib/vendor/blamejs/lib/middleware/require-step-up.js +226 -0
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +375 -0
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +285 -0
- package/lib/vendor/blamejs/lib/middleware/security-txt.js +170 -0
- package/lib/vendor/blamejs/lib/middleware/span-http-server.js +280 -0
- package/lib/vendor/blamejs/lib/middleware/speculation-rules.js +323 -0
- package/lib/vendor/blamejs/lib/middleware/sse.js +200 -0
- package/lib/vendor/blamejs/lib/middleware/trace-log-correlation.js +167 -0
- package/lib/vendor/blamejs/lib/middleware/trace-propagate.js +148 -0
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +749 -0
- package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +164 -0
- package/lib/vendor/blamejs/lib/migration-files.js +37 -0
- package/lib/vendor/blamejs/lib/migrations.js +385 -0
- package/lib/vendor/blamejs/lib/mime-parse.js +198 -0
- package/lib/vendor/blamejs/lib/money.js +699 -0
- package/lib/vendor/blamejs/lib/mtls-ca.js +572 -0
- package/lib/vendor/blamejs/lib/mtls-engine-default.js +501 -0
- package/lib/vendor/blamejs/lib/network-byte-quota.js +308 -0
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +533 -0
- package/lib/vendor/blamejs/lib/network-dns.js +1930 -0
- package/lib/vendor/blamejs/lib/network-heartbeat.js +425 -0
- package/lib/vendor/blamejs/lib/network-nts.js +574 -0
- package/lib/vendor/blamejs/lib/network-proxy.js +265 -0
- package/lib/vendor/blamejs/lib/network-smtp-policy.js +836 -0
- package/lib/vendor/blamejs/lib/network-tls.js +3126 -0
- package/lib/vendor/blamejs/lib/network.js +346 -0
- package/lib/vendor/blamejs/lib/nis2-report.js +181 -0
- package/lib/vendor/blamejs/lib/nist-crosswalk.js +293 -0
- package/lib/vendor/blamejs/lib/nonce-store.js +177 -0
- package/lib/vendor/blamejs/lib/notify.js +683 -0
- package/lib/vendor/blamejs/lib/ntp-check.js +458 -0
- package/lib/vendor/blamejs/lib/numeric-bounds.js +111 -0
- package/lib/vendor/blamejs/lib/numeric-checks.js +40 -0
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +349 -0
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +488 -0
- package/lib/vendor/blamejs/lib/object-store/gcs-bucket-ops.js +351 -0
- package/lib/vendor/blamejs/lib/object-store/gcs.js +515 -0
- package/lib/vendor/blamejs/lib/object-store/http-put.js +153 -0
- package/lib/vendor/blamejs/lib/object-store/http-request.js +38 -0
- package/lib/vendor/blamejs/lib/object-store/index.js +197 -0
- package/lib/vendor/blamejs/lib/object-store/local.js +163 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +1133 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +957 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +420 -0
- package/lib/vendor/blamejs/lib/observability-tracer.js +395 -0
- package/lib/vendor/blamejs/lib/observability.js +720 -0
- package/lib/vendor/blamejs/lib/openapi-paths-builder.js +248 -0
- package/lib/vendor/blamejs/lib/openapi-schema-walk.js +192 -0
- package/lib/vendor/blamejs/lib/openapi-security.js +169 -0
- package/lib/vendor/blamejs/lib/openapi-yaml.js +154 -0
- package/lib/vendor/blamejs/lib/openapi.js +489 -0
- package/lib/vendor/blamejs/lib/otel-export.js +278 -0
- package/lib/vendor/blamejs/lib/outbox.js +547 -0
- package/lib/vendor/blamejs/lib/pagination.js +542 -0
- package/lib/vendor/blamejs/lib/parsers/index.js +91 -0
- package/lib/vendor/blamejs/lib/parsers/safe-env.js +642 -0
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +293 -0
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +784 -0
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +390 -0
- package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +1015 -0
- package/lib/vendor/blamejs/lib/permissions.js +793 -0
- package/lib/vendor/blamejs/lib/pick.js +105 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +351 -0
- package/lib/vendor/blamejs/lib/pqc-gate.js +279 -0
- package/lib/vendor/blamejs/lib/pqc-software.js +271 -0
- package/lib/vendor/blamejs/lib/problem-details.js +482 -0
- package/lib/vendor/blamejs/lib/process-spawn.js +196 -0
- package/lib/vendor/blamejs/lib/promise-pool.js +162 -0
- package/lib/vendor/blamejs/lib/protobuf-encoder.js +190 -0
- package/lib/vendor/blamejs/lib/protocol-dispatcher.js +161 -0
- package/lib/vendor/blamejs/lib/public-suffix.js +403 -0
- package/lib/vendor/blamejs/lib/pubsub-cluster.js +154 -0
- package/lib/vendor/blamejs/lib/pubsub-redis.js +167 -0
- package/lib/vendor/blamejs/lib/pubsub.js +463 -0
- package/lib/vendor/blamejs/lib/queue-local.js +476 -0
- package/lib/vendor/blamejs/lib/queue-redis.js +745 -0
- package/lib/vendor/blamejs/lib/queue-sqs.js +319 -0
- package/lib/vendor/blamejs/lib/queue.js +1016 -0
- package/lib/vendor/blamejs/lib/redact.js +1007 -0
- package/lib/vendor/blamejs/lib/redis-client.js +520 -0
- package/lib/vendor/blamejs/lib/render.js +285 -0
- package/lib/vendor/blamejs/lib/request-helpers.js +767 -0
- package/lib/vendor/blamejs/lib/resource-access-lock.js +116 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +340 -0
- package/lib/vendor/blamejs/lib/restore-rollback.js +365 -0
- package/lib/vendor/blamejs/lib/restore.js +409 -0
- package/lib/vendor/blamejs/lib/retention.js +640 -0
- package/lib/vendor/blamejs/lib/retry.js +523 -0
- package/lib/vendor/blamejs/lib/router.js +1289 -0
- package/lib/vendor/blamejs/lib/safe-async.js +1184 -0
- package/lib/vendor/blamejs/lib/safe-buffer.js +562 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +297 -0
- package/lib/vendor/blamejs/lib/safe-dns.js +665 -0
- package/lib/vendor/blamejs/lib/safe-ical.js +634 -0
- package/lib/vendor/blamejs/lib/safe-icap.js +502 -0
- package/lib/vendor/blamejs/lib/safe-json.js +946 -0
- package/lib/vendor/blamejs/lib/safe-jsonpath.js +285 -0
- package/lib/vendor/blamejs/lib/safe-mime.js +831 -0
- package/lib/vendor/blamejs/lib/safe-mount-info.js +306 -0
- package/lib/vendor/blamejs/lib/safe-path.js +254 -0
- package/lib/vendor/blamejs/lib/safe-redirect.js +106 -0
- package/lib/vendor/blamejs/lib/safe-schema.js +1810 -0
- package/lib/vendor/blamejs/lib/safe-sieve.js +684 -0
- package/lib/vendor/blamejs/lib/safe-smtp.js +185 -0
- package/lib/vendor/blamejs/lib/safe-sql.js +363 -0
- package/lib/vendor/blamejs/lib/safe-url.js +428 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +473 -0
- package/lib/vendor/blamejs/lib/sandbox-worker.js +135 -0
- package/lib/vendor/blamejs/lib/sandbox.js +358 -0
- package/lib/vendor/blamejs/lib/scheduler.js +827 -0
- package/lib/vendor/blamejs/lib/sd-notify.js +269 -0
- package/lib/vendor/blamejs/lib/sec-cyber.js +214 -0
- package/lib/vendor/blamejs/lib/security-assert.js +395 -0
- package/lib/vendor/blamejs/lib/seeders.js +620 -0
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +309 -0
- package/lib/vendor/blamejs/lib/self-update.js +804 -0
- package/lib/vendor/blamejs/lib/server-timing.js +174 -0
- package/lib/vendor/blamejs/lib/session-device-binding.js +431 -0
- package/lib/vendor/blamejs/lib/session-stores.js +138 -0
- package/lib/vendor/blamejs/lib/session.js +1162 -0
- package/lib/vendor/blamejs/lib/slug.js +381 -0
- package/lib/vendor/blamejs/lib/sse.js +349 -0
- package/lib/vendor/blamejs/lib/ssrf-guard.js +792 -0
- package/lib/vendor/blamejs/lib/standard-webhooks.js +183 -0
- package/lib/vendor/blamejs/lib/static.js +1249 -0
- package/lib/vendor/blamejs/lib/storage.js +1272 -0
- package/lib/vendor/blamejs/lib/stream-throttle.js +235 -0
- package/lib/vendor/blamejs/lib/structured-fields.js +244 -0
- package/lib/vendor/blamejs/lib/subject.js +667 -0
- package/lib/vendor/blamejs/lib/tcpa-10dlc.js +175 -0
- package/lib/vendor/blamejs/lib/template.js +931 -0
- package/lib/vendor/blamejs/lib/tenant-quota.js +545 -0
- package/lib/vendor/blamejs/lib/test-harness.js +275 -0
- package/lib/vendor/blamejs/lib/testing.js +1185 -0
- package/lib/vendor/blamejs/lib/time.js +578 -0
- package/lib/vendor/blamejs/lib/tls-exporter.js +239 -0
- package/lib/vendor/blamejs/lib/totp.js +318 -0
- package/lib/vendor/blamejs/lib/tracing.js +546 -0
- package/lib/vendor/blamejs/lib/uuid.js +207 -0
- package/lib/vendor/blamejs/lib/validate-opts.js +381 -0
- package/lib/vendor/blamejs/lib/vault/index.js +638 -0
- package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +311 -0
- package/lib/vendor/blamejs/lib/vault/passphrase-source.js +198 -0
- package/lib/vendor/blamejs/lib/vault/rotate.js +803 -0
- package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +471 -0
- package/lib/vendor/blamejs/lib/vault/wrap.js +296 -0
- package/lib/vendor/blamejs/lib/vault-aad.js +259 -0
- package/lib/vendor/blamejs/lib/vendor/.vendor-data-pubkey +4 -0
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +161 -0
- package/lib/vendor/blamejs/lib/vendor/bimi-trust-anchors.data.js +68 -0
- package/lib/vendor/blamejs/lib/vendor/bimi-trust-anchors.pem +33 -0
- package/lib/vendor/blamejs/lib/vendor/common-passwords-top-10000.data.js +1325 -0
- package/lib/vendor/blamejs/lib/vendor/common-passwords-top-10000.txt +10002 -0
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +9 -0
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +18 -0
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +181 -0
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +16382 -0
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5881 -0
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +328 -0
- package/lib/vendor/blamejs/lib/vendor/vendor-data-pubkey.js +16 -0
- package/lib/vendor/blamejs/lib/vendor-data.js +520 -0
- package/lib/vendor/blamejs/lib/vex.js +630 -0
- package/lib/vendor/blamejs/lib/watcher.js +608 -0
- package/lib/vendor/blamejs/lib/web-push-vapid.js +322 -0
- package/lib/vendor/blamejs/lib/webhook.js +977 -0
- package/lib/vendor/blamejs/lib/websocket-channels.js +327 -0
- package/lib/vendor/blamejs/lib/websocket.js +1561 -0
- package/lib/vendor/blamejs/lib/wiki-concepts.js +338 -0
- package/lib/vendor/blamejs/lib/worker-pool.js +464 -0
- package/lib/vendor/blamejs/lib/ws-client.js +978 -0
- package/lib/vendor/blamejs/lib/xml-c14n.js +506 -0
- package/lib/vendor/blamejs/memory/specs/node-26-map-getorinsert-migration.md +164 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +19 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/README.md +88 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/build.sh +26 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/project.yaml +28 -0
- package/lib/vendor/blamejs/package.json +81 -0
- package/lib/vendor/blamejs/release-notes/v0.0.x.json +310 -0
- package/lib/vendor/blamejs/release-notes/v0.1.x.json +1798 -0
- package/lib/vendor/blamejs/release-notes/v0.10.x.json +1288 -0
- package/lib/vendor/blamejs/release-notes/v0.11.x.json +2551 -0
- package/lib/vendor/blamejs/release-notes/v0.12.0.json +64 -0
- package/lib/vendor/blamejs/release-notes/v0.12.1.json +32 -0
- package/lib/vendor/blamejs/release-notes/v0.12.2.json +45 -0
- package/lib/vendor/blamejs/release-notes/v0.2.x.json +706 -0
- package/lib/vendor/blamejs/release-notes/v0.3.x.json +786 -0
- package/lib/vendor/blamejs/release-notes/v0.4.x.json +588 -0
- package/lib/vendor/blamejs/release-notes/v0.5.x.json +390 -0
- package/lib/vendor/blamejs/release-notes/v0.6.x.json +1947 -0
- package/lib/vendor/blamejs/release-notes/v0.7.x.json +3811 -0
- package/lib/vendor/blamejs/release-notes/v0.8.x.json +3318 -0
- package/lib/vendor/blamejs/release-notes/v0.9.x.json +2257 -0
- package/lib/vendor/blamejs/scripts/build-vendored-sbom.js +325 -0
- package/lib/vendor/blamejs/scripts/check-api-snapshot.js +62 -0
- package/lib/vendor/blamejs/scripts/check-changelog-extract.js +108 -0
- package/lib/vendor/blamejs/scripts/check-pack-against-gitignore.js +83 -0
- package/lib/vendor/blamejs/scripts/check-services.js +483 -0
- package/lib/vendor/blamejs/scripts/check-vendor-currency.js +349 -0
- package/lib/vendor/blamejs/scripts/consolidate-release-notes.js +216 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +275 -0
- package/lib/vendor/blamejs/scripts/generate-changelog-entry.js +577 -0
- package/lib/vendor/blamejs/scripts/generate-release-signing-key.js +79 -0
- package/lib/vendor/blamejs/scripts/publish-dep-confusion-placeholder.sh +101 -0
- package/lib/vendor/blamejs/scripts/refresh-api-snapshot.js +31 -0
- package/lib/vendor/blamejs/scripts/refresh-vendor-manifest.js +132 -0
- package/lib/vendor/blamejs/scripts/release.js +652 -0
- package/lib/vendor/blamejs/scripts/sha3-digest.js +62 -0
- package/lib/vendor/blamejs/scripts/sign-release-artifact.js +92 -0
- package/lib/vendor/blamejs/scripts/test-integration.js +181 -0
- package/lib/vendor/blamejs/scripts/test-wiki-integration.js +126 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +77 -0
- package/lib/vendor/blamejs/scripts/vendor-data-gen.js +186 -0
- package/lib/vendor/blamejs/scripts/vendor-data-keygen.js +101 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +278 -0
- package/lib/vendor/blamejs/test/00-primitives.js +19075 -0
- package/lib/vendor/blamejs/test/10-state.js +622 -0
- package/lib/vendor/blamejs/test/20-db.js +561 -0
- package/lib/vendor/blamejs/test/30-chain.js +2110 -0
- package/lib/vendor/blamejs/test/40-consumers.js +2453 -0
- package/lib/vendor/blamejs/test/50-integration.js +486 -0
- package/lib/vendor/blamejs/test/_helpers.js +10 -0
- package/lib/vendor/blamejs/test/_smoke-worker.js +69 -0
- package/lib/vendor/blamejs/test/fixtures/exploit-corpus/corpus.json +368 -0
- package/lib/vendor/blamejs/test/fixtures/http-client-stream-payload.txt +2 -0
- package/lib/vendor/blamejs/test/fixtures/worker-pool/echo.js +52 -0
- package/lib/vendor/blamejs/test/helpers/_codebase-shingle-worker.js +24 -0
- package/lib/vendor/blamejs/test/helpers/_codebase-shingle.js +203 -0
- package/lib/vendor/blamejs/test/helpers/_shape-match.js +513 -0
- package/lib/vendor/blamejs/test/helpers/check.js +36 -0
- package/lib/vendor/blamejs/test/helpers/cluster.js +70 -0
- package/lib/vendor/blamejs/test/helpers/db.js +143 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +207 -0
- package/lib/vendor/blamejs/test/helpers/fs-watch.js +101 -0
- package/lib/vendor/blamejs/test/helpers/http.js +14 -0
- package/lib/vendor/blamejs/test/helpers/index.js +93 -0
- package/lib/vendor/blamejs/test/helpers/json-round-trip.js +120 -0
- package/lib/vendor/blamejs/test/helpers/mocks.js +20 -0
- package/lib/vendor/blamejs/test/helpers/otel.js +13 -0
- package/lib/vendor/blamejs/test/helpers/services.js +380 -0
- package/lib/vendor/blamejs/test/helpers/wait.js +206 -0
- package/lib/vendor/blamejs/test/integration/cache.test.js +235 -0
- package/lib/vendor/blamejs/test/integration/cluster-provider-mysql.test.js +174 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +611 -0
- package/lib/vendor/blamejs/test/integration/http-client.test.js +129 -0
- package/lib/vendor/blamejs/test/integration/log-stream.test.js +219 -0
- package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +181 -0
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +152 -0
- package/lib/vendor/blamejs/test/integration/mail-smtp.test.js +161 -0
- package/lib/vendor/blamejs/test/integration/mtls-ca.test.js +289 -0
- package/lib/vendor/blamejs/test/integration/network-dns.test.js +123 -0
- package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +101 -0
- package/lib/vendor/blamejs/test/integration/ntp-check.test.js +89 -0
- package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +403 -0
- package/lib/vendor/blamejs/test/integration/pqc-pkcs8-forward-compat.test.js +271 -0
- package/lib/vendor/blamejs/test/integration/pubsub.test.js +137 -0
- package/lib/vendor/blamejs/test/integration/queue-redis.test.js +352 -0
- package/lib/vendor/blamejs/test/integration/redis-client-tls.test.js +96 -0
- package/lib/vendor/blamejs/test/integration/ssrf-guard.test.js +98 -0
- package/lib/vendor/blamejs/test/integration/websocket-permessage-deflate.test.js +261 -0
- package/lib/vendor/blamejs/test/integration/ws-client-roundtrip.test.js +230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +211 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a.test.js +59 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/access-lock.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +219 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +266 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-orchestrator.test.js +390 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-posture-chain.test.js +174 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +279 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +322 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-stream.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-tenant.test.js +302 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-trace.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-adverse-decision.test.js +44 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-content-detect.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-input.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-model-manifest.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-pref.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +1080 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +311 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-zip-stream.test.js +291 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +267 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asyncapi.test.js +929 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-conflict-path.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-cve-defensive.test.js +176 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-daily-review.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-export-cadf.test.js +97 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-segregation.test.js +115 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-ml-dsa-65.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +246 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge-verifier.test.js +485 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge.test.js +331 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-lockout.test.js +572 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password-audit.test.js +61 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-bucket-ops.test.js +258 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-worker.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/bearer-auth.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-chunked-malformed.test.js +131 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-smuggling.test.js +118 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/boot-gates.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/breach-deadline.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +861 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/budr.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/bundler-engine.test.js +209 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache-status.test.js +129 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +871 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/canonical-json-jcs.test.js +43 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cdn-cache-control.test.js +243 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +147 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-audit-verify-chain.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-backup.test.js +135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-config-drift.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +75 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-file-type.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-helpers.test.js +145 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-mtls.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-password.test.js +97 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-restore.test.js +160 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-retention.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-security.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-vault.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/client-hints.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +237 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +9600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-cascade.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-eaa.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +712 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +278 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/config-drift.test.js +97 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/config.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cors.test.js +357 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cra-report.test.js +31 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/credential-hash.test.js +226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-envelope.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +193 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hpke-pq.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hpke.test.js +155 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-mlkem768-x25519.test.js +129 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-namespace-hash.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-random-int.test.js +72 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +180 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +210 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daily-byte-quota.test.js +153 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/data-act.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-collection-extensions.test.js +226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-collection.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-init-extensions.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-extensions.test.js +191 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-role-for.test.js +228 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-vacuum.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +184 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/declare-row-policy.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/declare-view.test.js +303 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dns-dnssec-algorithm.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dns-null-mx.test.js +39 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dora.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dr-runbook.test.js +59 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr-state-rules.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +786 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/early-hints.test.js +147 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/events.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/exploit-replay.test.js +243 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-routing.test.js +531 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +118 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fapi2.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fda-21cfr11.test.js +156 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fdx.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +434 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +432 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-type.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +887 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forensic-snapshot.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fsm.test.js +375 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gcs-bucket-ops.test.js +321 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/graphql-federation.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-agent-registry.test.js +87 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-all.test.js +328 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +339 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +694 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-dsn.test.js +296 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +234 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-envelope.test.js +192 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-event-bus-payload.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-event-bus-topic.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +386 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html-wcag.test.js +859 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +357 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +174 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +317 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-list-id.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-list-unsubscribe.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-compose.test.js +111 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-move.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-query.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-reply.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-sieve.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +301 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +265 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-message-id.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +161 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-posture-chain.test.js +100 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-saga-config.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-smtp-command.test.js +269 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-snapshot-envelope.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-stream-args.test.js +78 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +288 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-tenant-id.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-trace-context.test.js +102 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +202 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/hal.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/honeytoken.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +37 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +692 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +280 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +225 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +991 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/iab-mspa.test.js +63 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/iab-tcf.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +612 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/importmap-integrity.test.js +56 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +166 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/incident-report.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jose-jwe-experimental.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-api.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-round-trip-helper.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +159 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +118 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/local-db-thin.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-cloudwatch.test.js +489 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp-grpc.test.js +207 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp.test.js +283 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/lro.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +417 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +208 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +910 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +502 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +680 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-canspam.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +149 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +297 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +514 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy-tlsrpt.test.js +369 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +627 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-feedback-id.test.js +56 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +217 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +283 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +217 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-mdn.test.js +334 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-rbl.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-require-tls.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +336 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +732 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +840 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +130 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +285 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +394 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +147 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-spam-score.test.js +204 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-srs.test.js +152 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +279 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-unsubscribe.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +439 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-tool-registry.test.js +202 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +155 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-shadow-registry.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +224 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-compose-pipeline.test.js +278 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-paths.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nel.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-allowlist.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-byte-quota.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +372 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +635 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-heartbeat-passive.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls-build-options.test.js +130 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls-ct-inclusion.test.js +179 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +447 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +369 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nis2-report.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nist-crosswalk.test.js +42 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/no-cache.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/notify.test.js +707 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/numeric-bounds.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +72 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +597 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openapi.test.js +877 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +257 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pagination.test.js +522 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +324 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +546 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +153 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-software.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/problem-details.test.js +195 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/process-spawn.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/promise-pool.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/protected-resource-metadata.test.js +68 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/protobuf-encoder.test.js +138 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/protocol-dispatcher.test.js +174 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/public-suffix.test.js +197 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +232 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-dlq-extend-lease.test.js +178 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +322 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-priority-rate-progress.test.js +266 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-sqs.test.js +300 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-cluster.test.js +338 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-registry.test.js +75 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +246 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +130 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +335 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-log.test.js +170 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-auth-cache-control.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-mtls.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/resource-access-lock.test.js +52 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention-floor.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retry.test.js +535 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-cross-origin-redirect.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-parallel.test.js +170 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +248 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +451 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +289 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-icap.test.js +206 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +339 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mount-info.test.js +180 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +78 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sieve.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-smtp.test.js +95 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-idn-homograph.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +257 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/saml-slo.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +228 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler-exactly-once.test.js +238 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +700 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-notify.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sec-cyber.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/seeders.test.js +816 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update-standalone-verifier.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +302 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/server-timing.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +247 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/shape-match.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +952 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-multipart-sse.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/slug.test.js +330 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/smtp-policy.test.js +233 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/source-comment-blocks.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/speculation-rules.test.js +319 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sse.test.js +148 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +283 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/standard-webhooks.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +266 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/step-up.test.js +487 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-chunk-scratch.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +773 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/stream-throttle.test.js +173 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +180 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tcpa-10dlc.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +571 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/test-harness.test.js +190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/testing-request.test.js +119 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/testing.test.js +522 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-exporter.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-ocsp-ct.test.js +275 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-ocsp-verify.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-pinset-drift.test.js +35 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-preferred-groups.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tracing.test.js +280 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/uuid.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-aad.test.js +277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-seal-pem-file.test.js +252 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vendor-data.test.js +149 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vendor-manifest.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vex.test.js +661 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +308 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/web-push-vapid.test.js +144 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +674 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket-channels.test.js +360 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool.test.js +302 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +349 -0
- package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +717 -0
- package/lib/vendor/blamejs/test/layer-5-integration/bundler-output.test.js +444 -0
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +597 -0
- package/lib/vendor/blamejs/test/layer-5-integration/security-chaos.test.js +308 -0
- package/lib/vendor/blamejs/test/smoke.js +431 -0
- package/lib/webhooks.js +305 -0
- package/package.json +43 -0
|
@@ -0,0 +1,1448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.acme
|
|
4
|
+
* @nav Network
|
|
5
|
+
* @title ACME
|
|
6
|
+
*
|
|
7
|
+
* @intro
|
|
8
|
+
* ACME RFC 8555 + RFC 9773 ARI client — CA/B 47-day cert phase-in,
|
|
9
|
+
* ARI renewal windows, account key rotation.
|
|
10
|
+
*
|
|
11
|
+
* The handle owns the lifecycle: directory fetch (RFC 8555 §7.1.1),
|
|
12
|
+
* account create (§7.3), new order (§7.4), challenge dispatch
|
|
13
|
+
* (HTTP-01 / DNS-01 — operator runs the challenge response, the
|
|
14
|
+
* framework drives polling), finalize (§7.4), cert retrieve
|
|
15
|
+
* (§7.4.2). RFC 9773 ARI lets the CA push a renewal window:
|
|
16
|
+
* `renewIfDue` consults the directory's `renewalInfo` endpoint with
|
|
17
|
+
* the ACMECertID derived from the cert's AKI + serial. Before
|
|
18
|
+
* `suggestedWindow.start` the call audits `acme.cert.renew.skipped`;
|
|
19
|
+
* at or past it the verdict is `{ shouldRenew: true }` and audits
|
|
20
|
+
* `acme.cert.renewed.scheduled`. Operators wire this with
|
|
21
|
+
* `b.network.tls.expiryMonitor` so the renewal trigger composes
|
|
22
|
+
* into the existing cert-rotation flow.
|
|
23
|
+
*
|
|
24
|
+
* Directory URL: NO default. Operator passes the production CA's
|
|
25
|
+
* directory URL (Let's Encrypt prod / Pebble in tests / any
|
|
26
|
+
* RFC 8555-compliant CA). The framework refuses to default to a
|
|
27
|
+
* single CA — the operator's CA choice is policy, not framework
|
|
28
|
+
* decision.
|
|
29
|
+
*
|
|
30
|
+
* JWS algorithm: ES256 (P-256 + SHA-256) — RFC 8555 §6.2 mandates
|
|
31
|
+
* this for account-key signatures. ACME predates the JOSE PQC
|
|
32
|
+
* algorithm registry; until CAs publish PQC-capable directories,
|
|
33
|
+
* the wire format is classical. The framework's audit chain stays
|
|
34
|
+
* PQC-signed regardless.
|
|
35
|
+
*
|
|
36
|
+
* Validation: throw at config-time on bad opts; throw on bad CA-
|
|
37
|
+
* response shape (operator-meaningful); audit on cert.* lifecycle
|
|
38
|
+
* events.
|
|
39
|
+
*
|
|
40
|
+
* @card
|
|
41
|
+
* ACME RFC 8555 + RFC 9773 ARI client — CA/B 47-day cert phase-in, ARI renewal windows, account key rotation.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
var nodeCrypto = require("node:crypto");
|
|
45
|
+
|
|
46
|
+
var C = require("./constants");
|
|
47
|
+
var asn1 = require("./asn1-der");
|
|
48
|
+
var safeUrl = require("./safe-url");
|
|
49
|
+
var safeJson = require("./safe-json");
|
|
50
|
+
var validateOpts = require("./validate-opts");
|
|
51
|
+
var lazyRequire = require("./lazy-require");
|
|
52
|
+
var httpClient = require("./http-client");
|
|
53
|
+
var { AcmeError } = require("./framework-error");
|
|
54
|
+
|
|
55
|
+
var _err = AcmeError.factory;
|
|
56
|
+
|
|
57
|
+
var observability = lazyRequire(function () { return require("./observability"); });
|
|
58
|
+
|
|
59
|
+
// RFC 9773 §4 — the ACMECertID is constructed as
|
|
60
|
+
// base64url(AuthorityKeyIdentifier.keyIdentifier) + "." +
|
|
61
|
+
// base64url(serialNumber bytes). The renewalInfo endpoint is the
|
|
62
|
+
// directory's `renewalInfo` URL plus "/<ACMECertID>".
|
|
63
|
+
|
|
64
|
+
var DEFAULT_TIMEOUT_MS = C.TIME.seconds(30);
|
|
65
|
+
var DEFAULT_POLL_MS = C.TIME.seconds(2);
|
|
66
|
+
var DEFAULT_POLL_CAP_MS = C.TIME.minutes(5);
|
|
67
|
+
var DEFAULT_BODY_CAP = C.BYTES.mib(2);
|
|
68
|
+
|
|
69
|
+
// ---- helpers ----
|
|
70
|
+
|
|
71
|
+
function _b64u(buf) { return Buffer.from(buf).toString("base64url"); }
|
|
72
|
+
|
|
73
|
+
function _stringify(obj) {
|
|
74
|
+
// RFC 8555 §6.1 — JWS payload SHOULD be the canonical JSON encoding.
|
|
75
|
+
// Use stable key ordering via safeJson when available; fall back to
|
|
76
|
+
// JSON.stringify(obj) for bodies that are pre-validated.
|
|
77
|
+
if (safeJson && typeof safeJson.canonical === "function") {
|
|
78
|
+
try { return safeJson.canonical(obj); } catch (_e) { /* fall through */ }
|
|
79
|
+
}
|
|
80
|
+
return JSON.stringify(obj);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function _emitAudit(audit, action, outcome, metadata) {
|
|
84
|
+
if (!audit || typeof audit.safeEmit !== "function") return;
|
|
85
|
+
try {
|
|
86
|
+
audit.safeEmit({
|
|
87
|
+
action: action,
|
|
88
|
+
outcome: outcome,
|
|
89
|
+
metadata: metadata,
|
|
90
|
+
});
|
|
91
|
+
} catch (_e) { /* audit best-effort */ }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function _emitObs(name, fields) {
|
|
95
|
+
try { observability().safeEvent(name, 1, fields || {}); } catch (_e) { /* obs best-effort */ }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// JWK shape for an ES256 (P-256) public key — RFC 7518 §6.2.1.
|
|
99
|
+
function _publicJwkFromKeyObject(keyObject) {
|
|
100
|
+
if (!keyObject || typeof keyObject.export !== "function") {
|
|
101
|
+
throw _err("acme/bad-account-key", "accountKey must expose a Node KeyObject (export)", true);
|
|
102
|
+
}
|
|
103
|
+
var jwk;
|
|
104
|
+
try { jwk = keyObject.export({ format: "jwk" }); }
|
|
105
|
+
catch (e) { throw _err("acme/bad-account-key", "accountKey export(jwk) failed: " + e.message, true); }
|
|
106
|
+
if (!jwk || jwk.kty !== "EC" || jwk.crv !== "P-256") {
|
|
107
|
+
throw _err("acme/bad-account-key",
|
|
108
|
+
"accountKey must be a P-256 EC keypair (RFC 8555 §6.2 ES256); got kty=" +
|
|
109
|
+
(jwk && jwk.kty) + " crv=" + (jwk && jwk.crv), true);
|
|
110
|
+
}
|
|
111
|
+
// RFC 7638 thumbprint inputs MUST be sorted alphabetically + minimal-JSON.
|
|
112
|
+
return Object.freeze({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function _jwkThumbprint(publicJwk) {
|
|
116
|
+
// RFC 7638 §3 — base64url(SHA-256(canonical JSON of required members)).
|
|
117
|
+
var canon = JSON.stringify({ crv: publicJwk.crv, kty: publicJwk.kty, x: publicJwk.x, y: publicJwk.y });
|
|
118
|
+
return _b64u(nodeCrypto.createHash("sha256").update(canon).digest());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function _signJws(privateKey, protectedHeader, payload) {
|
|
122
|
+
// RFC 7515 compact JWS: <b64u(prot)>.<b64u(payload)>.<b64u(sig)>
|
|
123
|
+
// For empty body POST-as-GET, payload is the empty string.
|
|
124
|
+
var protB64 = _b64u(_stringify(protectedHeader));
|
|
125
|
+
var payloadB64 = (payload === "" || payload === undefined || payload === null)
|
|
126
|
+
? ""
|
|
127
|
+
: _b64u(_stringify(payload));
|
|
128
|
+
var signingInput = protB64 + "." + payloadB64;
|
|
129
|
+
var derSig;
|
|
130
|
+
try {
|
|
131
|
+
var sign = nodeCrypto.createSign("SHA256");
|
|
132
|
+
sign.update(signingInput);
|
|
133
|
+
sign.end();
|
|
134
|
+
derSig = sign.sign(privateKey);
|
|
135
|
+
} catch (e) {
|
|
136
|
+
throw _err("acme/sign-failed", "ES256 sign failed: " + e.message, true);
|
|
137
|
+
}
|
|
138
|
+
// ECDSA from node:crypto returns DER-encoded (r,s); RFC 7515 requires
|
|
139
|
+
// raw concatenation of r||s, each padded to the curve byte size (32
|
|
140
|
+
// for P-256).
|
|
141
|
+
var rawSig = _ecdsaDerToRaw(derSig, 32); // allow:raw-byte-literal — RFC 7518 §3.4 ES256 signature half-length (P-256 byte size)
|
|
142
|
+
return {
|
|
143
|
+
protected: protB64,
|
|
144
|
+
payload: payloadB64,
|
|
145
|
+
signature: _b64u(rawSig),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function _ecdsaDerToRaw(der, partSize) {
|
|
150
|
+
// SEQUENCE { INTEGER r, INTEGER s } — strip DER + left-pad to partSize.
|
|
151
|
+
var seq;
|
|
152
|
+
try { seq = asn1.readNode(der, 0); }
|
|
153
|
+
catch (e) {
|
|
154
|
+
throw _err("acme/bad-signature", "ECDSA signature DER parse failed: " + e.message, true);
|
|
155
|
+
}
|
|
156
|
+
if (seq.tag !== 0x10 && seq.tag !== 0x30) {
|
|
157
|
+
throw _err("acme/bad-signature", "ECDSA signature is not a DER SEQUENCE", true);
|
|
158
|
+
}
|
|
159
|
+
var children;
|
|
160
|
+
try { children = asn1.readSequence(seq.value); }
|
|
161
|
+
catch (e) {
|
|
162
|
+
throw _err("acme/bad-signature", "ECDSA signature SEQUENCE walk failed: " + e.message, true);
|
|
163
|
+
}
|
|
164
|
+
if (children.length !== 2) {
|
|
165
|
+
throw _err("acme/bad-signature",
|
|
166
|
+
"ECDSA signature SEQUENCE expected 2 INTEGERs, got " + children.length, true);
|
|
167
|
+
}
|
|
168
|
+
var r = _stripLeadingZero(children[0].value);
|
|
169
|
+
var s = _stripLeadingZero(children[1].value);
|
|
170
|
+
if (r.length > partSize || s.length > partSize) {
|
|
171
|
+
throw _err("acme/bad-signature",
|
|
172
|
+
"ECDSA signature integer exceeds " + partSize + " bytes", true);
|
|
173
|
+
}
|
|
174
|
+
var out = Buffer.alloc(partSize * 2);
|
|
175
|
+
r.copy(out, partSize - r.length);
|
|
176
|
+
s.copy(out, partSize * 2 - s.length);
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function _stripLeadingZero(buf) {
|
|
181
|
+
if (buf.length > 1 && buf[0] === 0x00) return buf.slice(1);
|
|
182
|
+
return buf;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ---- AKI + serial extraction (RFC 9773 §4.1 ACMECertID) ----
|
|
186
|
+
|
|
187
|
+
function _extractAkiAndSerial(certPem) {
|
|
188
|
+
if (typeof certPem !== "string" || certPem.indexOf("-----BEGIN CERTIFICATE-----") === -1) {
|
|
189
|
+
throw _err("acme/bad-cert", "renewIfDue: certPem must be a PEM-encoded CERTIFICATE", true);
|
|
190
|
+
}
|
|
191
|
+
var x509;
|
|
192
|
+
try { x509 = new nodeCrypto.X509Certificate(certPem); }
|
|
193
|
+
catch (e) {
|
|
194
|
+
throw _err("acme/bad-cert", "X.509 parse failed: " + e.message, true);
|
|
195
|
+
}
|
|
196
|
+
// Serial is exposed as a hex string; strip any leading "0x".
|
|
197
|
+
var serialHex = String(x509.serialNumber || "").replace(/^0x/i, "");
|
|
198
|
+
if (serialHex.length === 0 || (serialHex.length % 2) !== 0) {
|
|
199
|
+
throw _err("acme/bad-cert", "X.509 serialNumber malformed", true);
|
|
200
|
+
}
|
|
201
|
+
var serialBytes = Buffer.from(serialHex, "hex");
|
|
202
|
+
// The AuthorityKeyIdentifier extension OID is 2.5.29.35. Walk the
|
|
203
|
+
// tbsCertificate to find it.
|
|
204
|
+
var aki = _findAkiKeyIdentifier(x509.raw);
|
|
205
|
+
if (!aki) {
|
|
206
|
+
throw _err("acme/no-aki",
|
|
207
|
+
"renewIfDue: cert has no AuthorityKeyIdentifier extension; " +
|
|
208
|
+
"RFC 9773 §4.1 ACMECertID requires AKI keyIdentifier", true);
|
|
209
|
+
}
|
|
210
|
+
return { aki: aki, serial: serialBytes };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function _findAkiKeyIdentifier(rawDer) {
|
|
214
|
+
// Certificate ::= SEQUENCE { tbsCertificate, signatureAlgorithm, signatureValue }
|
|
215
|
+
var outer;
|
|
216
|
+
try { outer = asn1.readNode(rawDer, 0); }
|
|
217
|
+
catch (_e) { return null; }
|
|
218
|
+
if (!outer || !outer.constructed) return null;
|
|
219
|
+
var topChildren;
|
|
220
|
+
try { topChildren = asn1.readSequence(outer.value); }
|
|
221
|
+
catch (_e) { return null; }
|
|
222
|
+
if (!topChildren || topChildren.length < 1) return null;
|
|
223
|
+
var tbs = topChildren[0];
|
|
224
|
+
if (!tbs || !tbs.constructed) return null;
|
|
225
|
+
var tbsChildren;
|
|
226
|
+
try { tbsChildren = asn1.readSequence(tbs.value); }
|
|
227
|
+
catch (_e) { return null; }
|
|
228
|
+
// tbsCertificate fields ending with extensions [3] EXPLICIT — find the
|
|
229
|
+
// context-specific [3] tag (tagClass=2, tag=3).
|
|
230
|
+
var extsNode = null;
|
|
231
|
+
for (var i = 0; i < tbsChildren.length; i += 1) {
|
|
232
|
+
var n = tbsChildren[i];
|
|
233
|
+
if (n.tagClass === 2 && n.tag === 3) { extsNode = n; break; }
|
|
234
|
+
}
|
|
235
|
+
if (!extsNode) return null;
|
|
236
|
+
// [3] EXPLICIT wraps a SEQUENCE OF Extension. Unwrap.
|
|
237
|
+
var seqNode;
|
|
238
|
+
try { seqNode = asn1.readNode(extsNode.value, 0); }
|
|
239
|
+
catch (_e) { return null; }
|
|
240
|
+
if (!seqNode || !seqNode.constructed) return null;
|
|
241
|
+
var extList;
|
|
242
|
+
try { extList = asn1.readSequence(seqNode.value); }
|
|
243
|
+
catch (_e) { return null; }
|
|
244
|
+
for (var j = 0; j < extList.length; j += 1) {
|
|
245
|
+
var ext = extList[j];
|
|
246
|
+
if (!ext.constructed) continue;
|
|
247
|
+
var extChildren;
|
|
248
|
+
try { extChildren = asn1.readSequence(ext.value); }
|
|
249
|
+
catch (_e) { continue; }
|
|
250
|
+
if (!extChildren || extChildren.length < 2) continue;
|
|
251
|
+
var oid;
|
|
252
|
+
try { oid = asn1.readOid(extChildren[0]); }
|
|
253
|
+
catch (_e) { continue; }
|
|
254
|
+
if (oid !== "2.5.29.35") continue;
|
|
255
|
+
// extnValue is OCTET STRING containing AuthorityKeyIdentifier ::=
|
|
256
|
+
// SEQUENCE { keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL, ... }
|
|
257
|
+
var octet = extChildren[extChildren.length - 1];
|
|
258
|
+
var akiSeq;
|
|
259
|
+
try { akiSeq = asn1.readNode(octet.value, 0); }
|
|
260
|
+
catch (_e) { continue; }
|
|
261
|
+
if (!akiSeq.constructed) continue;
|
|
262
|
+
var akiInner;
|
|
263
|
+
try { akiInner = asn1.readSequence(akiSeq.value); }
|
|
264
|
+
catch (_e) { continue; }
|
|
265
|
+
for (var k = 0; k < akiInner.length; k += 1) {
|
|
266
|
+
// [0] IMPLICIT — context-specific tag 0, primitive (OCTET STRING).
|
|
267
|
+
if (akiInner[k].tagClass === 2 && akiInner[k].tag === 0) {
|
|
268
|
+
return Buffer.from(akiInner[k].value);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ---- ACME client factory ----
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* @primitive b.acme.create
|
|
280
|
+
* @signature b.acme.create(opts)
|
|
281
|
+
* @since 0.7.68
|
|
282
|
+
* @related b.mtlsCa.create
|
|
283
|
+
*
|
|
284
|
+
* Build an ACME client handle bound to the operator's chosen
|
|
285
|
+
* directory URL and account key. The returned object exposes
|
|
286
|
+
* `fetchDirectory`, `newAccount`, `newOrder`, `finalize`,
|
|
287
|
+
* `retrieveCert`, `revokeCert`, and `renewIfDue` (RFC 9773 ARI). The
|
|
288
|
+
* handle owns nonce management, JWS signing (ES256 per RFC 8555
|
|
289
|
+
* §6.2), polling with an exponential backoff cap, and cert /
|
|
290
|
+
* renewal-window audit emission. Throws `AcmeError` at config-time
|
|
291
|
+
* on bad opts (missing directory URL, missing accountKey, malformed
|
|
292
|
+
* contact list).
|
|
293
|
+
*
|
|
294
|
+
* @opts
|
|
295
|
+
* directory: string, // required — CA directory URL (no default)
|
|
296
|
+
* accountKey: { privatePem, publicPem, jwk, kty, crv }, // required — ES256 P-256 key material
|
|
297
|
+
* contact: Array<string>, // optional — mailto: URIs
|
|
298
|
+
* audit: object, // optional — b.audit sink for cert.* lifecycle events
|
|
299
|
+
* timeoutMs: number, // default 30s — per-HTTP-call timeout
|
|
300
|
+
* pollIntervalMs: number, // default 2s — polling interval for order / authorization status
|
|
301
|
+
* pollMaxMs: number, // default 5min — total polling cap
|
|
302
|
+
* maxBytes: number, // default 2 MiB — response body cap
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* var crypto = require("crypto");
|
|
306
|
+
* var pair = crypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
|
|
307
|
+
* var acme = b.acme.create({
|
|
308
|
+
* directory: "https://acme-staging-v02.api.letsencrypt.org/directory",
|
|
309
|
+
* accountKey: {
|
|
310
|
+
* privatePem: pair.privateKey.export({ type: "pkcs8", format: "pem" }),
|
|
311
|
+
* publicPem: pair.publicKey.export({ type: "spki", format: "pem" }),
|
|
312
|
+
* kty: "EC",
|
|
313
|
+
* crv: "P-256",
|
|
314
|
+
* },
|
|
315
|
+
* contact: ["mailto:ops@example.com"],
|
|
316
|
+
* });
|
|
317
|
+
* typeof acme.fetchDirectory;
|
|
318
|
+
* // → "function"
|
|
319
|
+
*/
|
|
320
|
+
function create(opts) {
|
|
321
|
+
if (!opts || typeof opts !== "object") {
|
|
322
|
+
throw _err("acme/bad-opts", "acme.create: opts is required", true);
|
|
323
|
+
}
|
|
324
|
+
validateOpts(opts, [
|
|
325
|
+
"directory", "accountKey", "audit", "contact", "timeoutMs",
|
|
326
|
+
"pollIntervalMs", "pollMaxMs", "maxBytes",
|
|
327
|
+
], "acme.create");
|
|
328
|
+
|
|
329
|
+
validateOpts.requireNonEmptyString(opts.directory,
|
|
330
|
+
"acme.create: directory (the operator's RFC 8555 directory URL — no framework default)",
|
|
331
|
+
AcmeError, "acme/bad-directory");
|
|
332
|
+
// Refuse non-https directories — RFC 8555 §6.1 mandates HTTPS for ACME.
|
|
333
|
+
var dirUrl;
|
|
334
|
+
try {
|
|
335
|
+
dirUrl = safeUrl.parse(opts.directory, {
|
|
336
|
+
allowedProtocols: ["https:"],
|
|
337
|
+
errorClass: AcmeError,
|
|
338
|
+
});
|
|
339
|
+
} catch (e) {
|
|
340
|
+
throw _err("acme/bad-directory",
|
|
341
|
+
"acme.create: directory must be an https:// URL (RFC 8555 §6.1): " + e.message, true);
|
|
342
|
+
}
|
|
343
|
+
if (!opts.accountKey || typeof opts.accountKey !== "object") {
|
|
344
|
+
throw _err("acme/bad-account-key",
|
|
345
|
+
"acme.create: accountKey object is required (privateKey / publicJwk / KeyObject)", true);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Accept either a Node KeyObject or a PEM/JWK and normalize. A
|
|
349
|
+
// KeyObject is identified by `type === "private"` + `asymmetricKeyType`.
|
|
350
|
+
var privateKey = null;
|
|
351
|
+
var publicJwk = null;
|
|
352
|
+
if (opts.accountKey.type === "private" && typeof opts.accountKey.export === "function") {
|
|
353
|
+
privateKey = opts.accountKey; // already a KeyObject
|
|
354
|
+
} else if (typeof opts.accountKey.privatePem === "string") {
|
|
355
|
+
try { privateKey = nodeCrypto.createPrivateKey(opts.accountKey.privatePem); }
|
|
356
|
+
catch (e) { throw _err("acme/bad-account-key", "accountKey.privatePem parse failed: " + e.message, true); }
|
|
357
|
+
} else if (opts.accountKey.privateKey &&
|
|
358
|
+
opts.accountKey.privateKey.type === "private" &&
|
|
359
|
+
typeof opts.accountKey.privateKey.export === "function") {
|
|
360
|
+
privateKey = opts.accountKey.privateKey;
|
|
361
|
+
} else {
|
|
362
|
+
throw _err("acme/bad-account-key",
|
|
363
|
+
"acme.create: accountKey must carry a Node KeyObject or { privatePem }", true);
|
|
364
|
+
}
|
|
365
|
+
publicJwk = _publicJwkFromKeyObject(privateKey);
|
|
366
|
+
|
|
367
|
+
if (opts.contact !== undefined) {
|
|
368
|
+
if (!Array.isArray(opts.contact) || !opts.contact.every(function (c) {
|
|
369
|
+
return typeof c === "string" && c.length > 0 && c.length <= C.BYTES.bytes(256) &&
|
|
370
|
+
/^(mailto|tel):/i.test(c);
|
|
371
|
+
})) {
|
|
372
|
+
throw _err("acme/bad-contact",
|
|
373
|
+
"acme.create: contact must be an array of mailto:/tel: URIs", true);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
var timeoutMs = (typeof opts.timeoutMs === "number" && isFinite(opts.timeoutMs) && opts.timeoutMs > 0)
|
|
377
|
+
? opts.timeoutMs : DEFAULT_TIMEOUT_MS;
|
|
378
|
+
var pollIntervalMs = (typeof opts.pollIntervalMs === "number" && isFinite(opts.pollIntervalMs) && opts.pollIntervalMs > 0)
|
|
379
|
+
? opts.pollIntervalMs : DEFAULT_POLL_MS;
|
|
380
|
+
var pollMaxMs = (typeof opts.pollMaxMs === "number" && isFinite(opts.pollMaxMs) && opts.pollMaxMs > 0)
|
|
381
|
+
? opts.pollMaxMs : DEFAULT_POLL_CAP_MS;
|
|
382
|
+
var maxBytes = (typeof opts.maxBytes === "number" && isFinite(opts.maxBytes) && opts.maxBytes > 0)
|
|
383
|
+
? opts.maxBytes : DEFAULT_BODY_CAP;
|
|
384
|
+
|
|
385
|
+
var audit = opts.audit || null;
|
|
386
|
+
|
|
387
|
+
// Mutable state — directory entries, account URL (kid), nonce queue.
|
|
388
|
+
var state = {
|
|
389
|
+
directoryUrl: dirUrl.toString(),
|
|
390
|
+
directory: null,
|
|
391
|
+
accountUrl: null,
|
|
392
|
+
nonces: [],
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// ---- internal: HTTP shapes ----
|
|
396
|
+
|
|
397
|
+
async function _httpReq(method, url, body, headers) {
|
|
398
|
+
headers = Object.assign({
|
|
399
|
+
"User-Agent": "blamejs-acme/1",
|
|
400
|
+
"Accept": "application/json",
|
|
401
|
+
}, headers || {});
|
|
402
|
+
var req = {
|
|
403
|
+
method: method,
|
|
404
|
+
url: url,
|
|
405
|
+
headers: headers,
|
|
406
|
+
body: body || undefined,
|
|
407
|
+
timeoutMs: timeoutMs,
|
|
408
|
+
maxResponseBytes: maxBytes,
|
|
409
|
+
allowedProtocols: ["https:"],
|
|
410
|
+
errorClass: AcmeError,
|
|
411
|
+
};
|
|
412
|
+
var rsp;
|
|
413
|
+
try { rsp = await httpClient.request(req); }
|
|
414
|
+
catch (e) {
|
|
415
|
+
throw _err("acme/network",
|
|
416
|
+
method + " " + url + " failed: " + (e && e.message),
|
|
417
|
+
false, (e && e.statusCode) || 0);
|
|
418
|
+
}
|
|
419
|
+
// Stash any Replay-Nonce (RFC 8555 §6.5) for the next request.
|
|
420
|
+
var nonce = rsp.headers && (rsp.headers["replay-nonce"] || rsp.headers["Replay-Nonce"]);
|
|
421
|
+
if (typeof nonce === "string" && nonce.length > 0) state.nonces.push(nonce);
|
|
422
|
+
return rsp;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async function _newNonce() {
|
|
426
|
+
if (state.nonces.length > 0) return state.nonces.shift();
|
|
427
|
+
if (!state.directory || !state.directory.newNonce) {
|
|
428
|
+
throw _err("acme/no-directory",
|
|
429
|
+
"_newNonce: directory must be fetched before signed requests", true);
|
|
430
|
+
}
|
|
431
|
+
var rsp = await _httpReq("HEAD", state.directory.newNonce, null);
|
|
432
|
+
if (rsp.statusCode !== 200 && rsp.statusCode !== 204) {
|
|
433
|
+
throw _err("acme/newnonce-failed",
|
|
434
|
+
"newNonce HEAD returned " + rsp.statusCode, true, rsp.statusCode);
|
|
435
|
+
}
|
|
436
|
+
if (state.nonces.length === 0) {
|
|
437
|
+
throw _err("acme/newnonce-no-header",
|
|
438
|
+
"newNonce response carried no Replay-Nonce header", true, rsp.statusCode);
|
|
439
|
+
}
|
|
440
|
+
return state.nonces.shift();
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
async function _signedPost(url, payload, opts2) {
|
|
444
|
+
opts2 = opts2 || {};
|
|
445
|
+
var nonce = await _newNonce();
|
|
446
|
+
var prot = {
|
|
447
|
+
alg: "ES256",
|
|
448
|
+
nonce: nonce,
|
|
449
|
+
url: url,
|
|
450
|
+
};
|
|
451
|
+
if (opts2.useJwk || !state.accountUrl) {
|
|
452
|
+
prot.jwk = publicJwk;
|
|
453
|
+
} else {
|
|
454
|
+
prot.kid = state.accountUrl;
|
|
455
|
+
}
|
|
456
|
+
var jws = _signJws(privateKey, prot, payload === null ? "" : payload);
|
|
457
|
+
var rsp = await _httpReq("POST", url, JSON.stringify(jws), {
|
|
458
|
+
"Content-Type": "application/jose+json",
|
|
459
|
+
});
|
|
460
|
+
return rsp;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ---- public: directory / account ----
|
|
464
|
+
|
|
465
|
+
async function fetchDirectory() {
|
|
466
|
+
var rsp = await _httpReq("GET", state.directoryUrl, null);
|
|
467
|
+
if (rsp.statusCode !== 200) {
|
|
468
|
+
throw _err("acme/directory-fetch",
|
|
469
|
+
"directory GET returned " + rsp.statusCode, true, rsp.statusCode);
|
|
470
|
+
}
|
|
471
|
+
var body = _parseJsonBody(rsp.body, "directory");
|
|
472
|
+
var required = ["newNonce", "newAccount", "newOrder"];
|
|
473
|
+
for (var i = 0; i < required.length; i += 1) {
|
|
474
|
+
if (typeof body[required[i]] !== "string") {
|
|
475
|
+
throw _err("acme/directory-shape",
|
|
476
|
+
"directory missing required field: " + required[i], true);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
state.directory = body;
|
|
480
|
+
_emitAudit(audit, "acme.directory.fetched", "success",
|
|
481
|
+
{ directoryUrl: state.directoryUrl, hasAri: typeof body.renewalInfo === "string" });
|
|
482
|
+
_emitObs("acme.directory.fetched", { hasAri: typeof body.renewalInfo === "string" });
|
|
483
|
+
return body;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
async function newAccount(nopts) {
|
|
487
|
+
nopts = nopts || {};
|
|
488
|
+
if (!state.directory) await fetchDirectory();
|
|
489
|
+
var payload = { termsOfServiceAgreed: true };
|
|
490
|
+
if (Array.isArray(opts.contact) && opts.contact.length > 0) payload.contact = opts.contact.slice();
|
|
491
|
+
// RFC 8555 §7.3.4 — External Account Binding (EAB). Required by
|
|
492
|
+
// ZeroSSL / Buypass / Google CA / many other commercial CAs.
|
|
493
|
+
// The operator obtains `kid` + `hmacKey` from the CA's account
|
|
494
|
+
// dashboard and supplies them either via the `externalAccountBinding`
|
|
495
|
+
// opt on newAccount() OR statically on create() opts. The EAB
|
|
496
|
+
// payload is an inner-JWS over the account's public JWK signed
|
|
497
|
+
// with HMAC-SHA256 keyed by the CA-supplied HMAC key.
|
|
498
|
+
var eab = nopts.externalAccountBinding || opts.externalAccountBinding;
|
|
499
|
+
if (eab) {
|
|
500
|
+
if (typeof eab.kid !== "string" || eab.kid.length === 0) {
|
|
501
|
+
throw _err("acme/eab-no-kid",
|
|
502
|
+
"newAccount: externalAccountBinding.kid required (RFC 8555 §7.3.4)", true);
|
|
503
|
+
}
|
|
504
|
+
if (typeof eab.hmacKey !== "string" || eab.hmacKey.length === 0) {
|
|
505
|
+
throw _err("acme/eab-no-hmac",
|
|
506
|
+
"newAccount: externalAccountBinding.hmacKey required (base64url-encoded)", true);
|
|
507
|
+
}
|
|
508
|
+
var eabProtected = {
|
|
509
|
+
alg: eab.alg || "HS256",
|
|
510
|
+
kid: eab.kid,
|
|
511
|
+
url: state.directory.newAccount,
|
|
512
|
+
};
|
|
513
|
+
// Inner JWS: payload = the account's public JWK (RFC 8555 §7.3.4).
|
|
514
|
+
var eabHeaderB64 = _b64u(Buffer.from(_stringify(eabProtected), "utf8"));
|
|
515
|
+
var eabPayloadB64 = _b64u(Buffer.from(_stringify(publicJwk), "utf8"));
|
|
516
|
+
var eabSigningInput = eabHeaderB64 + "." + eabPayloadB64;
|
|
517
|
+
var hmacKeyRaw = Buffer.from(eab.hmacKey, "base64url");
|
|
518
|
+
var hmac = require("node:crypto").createHmac("sha256", hmacKeyRaw);
|
|
519
|
+
hmac.update(eabSigningInput);
|
|
520
|
+
var eabSig = _b64u(hmac.digest());
|
|
521
|
+
payload.externalAccountBinding = {
|
|
522
|
+
protected: eabHeaderB64,
|
|
523
|
+
payload: eabPayloadB64,
|
|
524
|
+
signature: eabSig,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
var rsp = await _signedPost(state.directory.newAccount, payload, { useJwk: true });
|
|
528
|
+
if (rsp.statusCode !== 200 && rsp.statusCode !== 201) {
|
|
529
|
+
_emitAudit(audit, "acme.account.registered", "failure",
|
|
530
|
+
{ status: rsp.statusCode, reason: _extractProblemReason(rsp.body) });
|
|
531
|
+
throw _err("acme/newaccount",
|
|
532
|
+
"newAccount returned " + rsp.statusCode, true, rsp.statusCode);
|
|
533
|
+
}
|
|
534
|
+
var loc = rsp.headers && (rsp.headers["location"] || rsp.headers["Location"]);
|
|
535
|
+
if (typeof loc !== "string" || loc.length === 0) {
|
|
536
|
+
throw _err("acme/newaccount-no-location",
|
|
537
|
+
"newAccount response carried no Location header", true, rsp.statusCode);
|
|
538
|
+
}
|
|
539
|
+
state.accountUrl = loc;
|
|
540
|
+
_emitAudit(audit, "acme.account.registered", "success",
|
|
541
|
+
{ accountUrl: loc, contact: payload.contact || [] });
|
|
542
|
+
return { accountUrl: loc, body: _parseJsonBody(rsp.body, "newAccount") };
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// ---- public: order lifecycle ----
|
|
546
|
+
|
|
547
|
+
async function newOrder(orderOpts) {
|
|
548
|
+
if (!state.directory) await fetchDirectory();
|
|
549
|
+
if (!state.accountUrl) {
|
|
550
|
+
throw _err("acme/no-account", "newOrder: call newAccount() first", true);
|
|
551
|
+
}
|
|
552
|
+
if (!orderOpts || !Array.isArray(orderOpts.identifiers) || orderOpts.identifiers.length === 0) {
|
|
553
|
+
throw _err("acme/bad-order",
|
|
554
|
+
"newOrder: identifiers[] is required (e.g. [{ type: 'dns', value: 'example.com' }])", true);
|
|
555
|
+
}
|
|
556
|
+
for (var i = 0; i < orderOpts.identifiers.length; i += 1) {
|
|
557
|
+
var id = orderOpts.identifiers[i];
|
|
558
|
+
if (!id || typeof id.type !== "string" || typeof id.value !== "string" ||
|
|
559
|
+
id.type.length === 0 || id.value.length === 0 ||
|
|
560
|
+
id.value.length > C.BYTES.bytes(255)) {
|
|
561
|
+
throw _err("acme/bad-identifier",
|
|
562
|
+
"newOrder: identifier must be { type: string, value: string<=255 }", true);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
var payload = { identifiers: orderOpts.identifiers.slice() };
|
|
566
|
+
if (typeof orderOpts.notBefore === "string") payload.notBefore = orderOpts.notBefore;
|
|
567
|
+
if (typeof orderOpts.notAfter === "string") payload.notAfter = orderOpts.notAfter;
|
|
568
|
+
// draft-aaron-acme-profiles — operator-selected certificate profile.
|
|
569
|
+
// The CA advertises profile names + descriptions via
|
|
570
|
+
// `directory.meta.profiles`; operator passes the chosen name through
|
|
571
|
+
// newOrder. CAs honoring the draft return 400 when the name isn't
|
|
572
|
+
// in the advertised set; ones that haven't adopted the draft ignore
|
|
573
|
+
// the field. v1-defensible scope: refuse non-string + cap length so
|
|
574
|
+
// attacker-supplied profile values can't bloat the JSON payload.
|
|
575
|
+
if (typeof orderOpts.profile === "string") {
|
|
576
|
+
if (orderOpts.profile.length === 0 || orderOpts.profile.length > C.BYTES.bytes(64)) {
|
|
577
|
+
throw _err("acme/bad-profile",
|
|
578
|
+
"newOrder: profile name must be a non-empty string <= 64 bytes", true);
|
|
579
|
+
}
|
|
580
|
+
payload.profile = orderOpts.profile;
|
|
581
|
+
} else if (orderOpts.profile !== undefined) {
|
|
582
|
+
throw _err("acme/bad-profile",
|
|
583
|
+
"newOrder: profile must be a string when provided", true);
|
|
584
|
+
}
|
|
585
|
+
var rsp = await _signedPost(state.directory.newOrder, payload);
|
|
586
|
+
if (rsp.statusCode !== 201) {
|
|
587
|
+
_emitAudit(audit, "acme.order.created", "failure",
|
|
588
|
+
{ status: rsp.statusCode, reason: _extractProblemReason(rsp.body) });
|
|
589
|
+
throw _err("acme/neworder",
|
|
590
|
+
"newOrder returned " + rsp.statusCode, true, rsp.statusCode);
|
|
591
|
+
}
|
|
592
|
+
var orderUrl = rsp.headers && (rsp.headers["location"] || rsp.headers["Location"]);
|
|
593
|
+
var order = _parseJsonBody(rsp.body, "newOrder");
|
|
594
|
+
order.url = orderUrl;
|
|
595
|
+
_emitAudit(audit, "acme.order.created", "success",
|
|
596
|
+
{ orderUrl: orderUrl, identifiers: payload.identifiers });
|
|
597
|
+
return order;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
async function finalize(order, csrDerOrPem) {
|
|
601
|
+
if (!order || typeof order !== "object" || typeof order.finalize !== "string") {
|
|
602
|
+
throw _err("acme/bad-order", "finalize: order.finalize URL is required", true);
|
|
603
|
+
}
|
|
604
|
+
var csrDer;
|
|
605
|
+
if (Buffer.isBuffer(csrDerOrPem)) {
|
|
606
|
+
csrDer = csrDerOrPem;
|
|
607
|
+
} else if (typeof csrDerOrPem === "string" &&
|
|
608
|
+
csrDerOrPem.indexOf("-----BEGIN CERTIFICATE REQUEST-----") !== -1) {
|
|
609
|
+
var b64 = csrDerOrPem
|
|
610
|
+
.replace(/-----BEGIN CERTIFICATE REQUEST-----/, "")
|
|
611
|
+
.replace(/-----END CERTIFICATE REQUEST-----/, "")
|
|
612
|
+
.replace(/\s+/g, "");
|
|
613
|
+
try { csrDer = Buffer.from(b64, "base64"); }
|
|
614
|
+
catch (e) { throw _err("acme/bad-csr", "CSR base64 decode failed: " + e.message, true); }
|
|
615
|
+
} else {
|
|
616
|
+
throw _err("acme/bad-csr", "finalize: csr must be a DER Buffer or PEM string", true);
|
|
617
|
+
}
|
|
618
|
+
if (csrDer.length === 0 || csrDer.length > C.BYTES.kib(64)) {
|
|
619
|
+
throw _err("acme/bad-csr",
|
|
620
|
+
"finalize: CSR DER size out of range (got " + csrDer.length + " bytes)", true);
|
|
621
|
+
}
|
|
622
|
+
var payload = { csr: _b64u(csrDer) };
|
|
623
|
+
var rsp = await _signedPost(order.finalize, payload);
|
|
624
|
+
if (rsp.statusCode < 200 || rsp.statusCode >= 300) {
|
|
625
|
+
_emitAudit(audit, "acme.order.finalize", "failure",
|
|
626
|
+
{ orderUrl: order.url, status: rsp.statusCode, reason: _extractProblemReason(rsp.body) });
|
|
627
|
+
throw _err("acme/finalize",
|
|
628
|
+
"finalize returned " + rsp.statusCode, true, rsp.statusCode);
|
|
629
|
+
}
|
|
630
|
+
var updated = _parseJsonBody(rsp.body, "finalize");
|
|
631
|
+
updated.url = order.url;
|
|
632
|
+
_emitAudit(audit, "acme.order.finalize", "success",
|
|
633
|
+
{ orderUrl: order.url, status: updated.status });
|
|
634
|
+
return updated;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
async function retrieveCert(order) {
|
|
638
|
+
if (!order || typeof order !== "object" || typeof order.url !== "string") {
|
|
639
|
+
throw _err("acme/bad-order", "retrieveCert: order.url is required", true);
|
|
640
|
+
}
|
|
641
|
+
var deadline = Date.now() + pollMaxMs;
|
|
642
|
+
var current = order;
|
|
643
|
+
while (true) {
|
|
644
|
+
if (current.status === "valid" && typeof current.certificate === "string") break;
|
|
645
|
+
if (current.status === "invalid") {
|
|
646
|
+
_emitAudit(audit, "acme.order.poll", "failure",
|
|
647
|
+
{ orderUrl: current.url, status: "invalid" });
|
|
648
|
+
throw _err("acme/order-invalid",
|
|
649
|
+
"retrieveCert: order is invalid", true);
|
|
650
|
+
}
|
|
651
|
+
if (Date.now() >= deadline) {
|
|
652
|
+
throw _err("acme/order-timeout",
|
|
653
|
+
"retrieveCert: order did not reach 'valid' within " + pollMaxMs + "ms", true);
|
|
654
|
+
}
|
|
655
|
+
await _sleep(pollIntervalMs);
|
|
656
|
+
var rsp = await _signedPost(current.url, null);
|
|
657
|
+
if (rsp.statusCode < 200 || rsp.statusCode >= 300) {
|
|
658
|
+
throw _err("acme/order-poll",
|
|
659
|
+
"order poll returned " + rsp.statusCode, true, rsp.statusCode);
|
|
660
|
+
}
|
|
661
|
+
current = _parseJsonBody(rsp.body, "order-poll");
|
|
662
|
+
current.url = order.url;
|
|
663
|
+
}
|
|
664
|
+
var certRsp = await _signedPost(current.certificate, null);
|
|
665
|
+
if (certRsp.statusCode !== 200) {
|
|
666
|
+
_emitAudit(audit, "acme.cert.issued", "failure",
|
|
667
|
+
{ orderUrl: order.url, status: certRsp.statusCode });
|
|
668
|
+
throw _err("acme/cert-download",
|
|
669
|
+
"certificate download returned " + certRsp.statusCode, true, certRsp.statusCode);
|
|
670
|
+
}
|
|
671
|
+
var pem = certRsp.body && certRsp.body.toString("utf8");
|
|
672
|
+
if (typeof pem !== "string" || pem.indexOf("-----BEGIN CERTIFICATE-----") === -1) {
|
|
673
|
+
throw _err("acme/bad-cert-bytes",
|
|
674
|
+
"certificate body is not PEM-encoded", true, certRsp.statusCode);
|
|
675
|
+
}
|
|
676
|
+
_emitAudit(audit, "acme.cert.issued", "success",
|
|
677
|
+
{ orderUrl: order.url, bytes: pem.length });
|
|
678
|
+
_emitObs("acme.cert.issued", { bytes: pem.length });
|
|
679
|
+
return pem;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// ---- public: per-challenge authorization flow ----
|
|
683
|
+
//
|
|
684
|
+
// RFC 8555 §7.5 — authorization objects contain the challenge list.
|
|
685
|
+
// Fetching the authorization is POST-as-GET. The operator (or higher-
|
|
686
|
+
// level wrapper like `b.cert.create`) walks the challenges, provisions
|
|
687
|
+
// the response, then POSTs an empty object to the challenge URL to
|
|
688
|
+
// signal readiness, then polls the authorization until `status` is
|
|
689
|
+
// `valid` (or `invalid`).
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* @primitive b.acme.create.fetchAuthorization
|
|
693
|
+
* @signature b.acme.create.fetchAuthorization(authUrl)
|
|
694
|
+
* @since 0.11.22
|
|
695
|
+
*
|
|
696
|
+
* POST-as-GET an authorization URL. Returns the parsed authorization
|
|
697
|
+
* object — `{ status, identifier, challenges, expires, wildcard? }`
|
|
698
|
+
* per RFC 8555 §7.5. The challenges array lists every challenge type
|
|
699
|
+
* the CA offers for this authorization (`http-01`, `dns-01`,
|
|
700
|
+
* `tls-alpn-01`); each entry carries `{ type, url, token, status }`.
|
|
701
|
+
*
|
|
702
|
+
* @example
|
|
703
|
+
* var auth = await client.fetchAuthorization(order.authorizations[0]);
|
|
704
|
+
* var http01 = auth.challenges.find(function (c) { return c.type === "http-01"; });
|
|
705
|
+
* typeof http01.token; // → "string"
|
|
706
|
+
* typeof http01.url; // → "string"
|
|
707
|
+
*/
|
|
708
|
+
async function fetchAuthorization(authUrl) {
|
|
709
|
+
if (typeof authUrl !== "string" || authUrl.length === 0) {
|
|
710
|
+
throw _err("acme/bad-auth-url",
|
|
711
|
+
"fetchAuthorization: authUrl must be a non-empty string", true);
|
|
712
|
+
}
|
|
713
|
+
var rsp = await _signedPost(authUrl, null);
|
|
714
|
+
if (rsp.statusCode < 200 || rsp.statusCode >= 300) {
|
|
715
|
+
throw _err("acme/auth-fetch",
|
|
716
|
+
"fetchAuthorization returned " + rsp.statusCode, true, rsp.statusCode);
|
|
717
|
+
}
|
|
718
|
+
var body = _parseJsonBody(rsp.body, "fetchAuthorization");
|
|
719
|
+
body.url = authUrl;
|
|
720
|
+
return body;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* @primitive b.acme.create.notifyChallengeReady
|
|
725
|
+
* @signature b.acme.create.notifyChallengeReady(challengeUrl)
|
|
726
|
+
* @since 0.11.22
|
|
727
|
+
*
|
|
728
|
+
* POST an empty JSON object (`{}`) to a challenge URL to signal that
|
|
729
|
+
* the operator has provisioned the challenge response and the CA may
|
|
730
|
+
* now begin its validation attempt. Returns the updated challenge
|
|
731
|
+
* object (status typically `processing` immediately after this call).
|
|
732
|
+
*
|
|
733
|
+
* Per RFC 8555 §7.5.1: the empty-object POST is the operator's
|
|
734
|
+
* commitment that the validation surface is ready. The CA's
|
|
735
|
+
* validation runs asynchronously; poll the authorization with
|
|
736
|
+
* `waitForAuthorization` afterwards.
|
|
737
|
+
*
|
|
738
|
+
* @example
|
|
739
|
+
* await myHttp01Server.add(challenge.token, client.keyAuthorization(challenge.token));
|
|
740
|
+
* var updated = await client.notifyChallengeReady(challenge.url);
|
|
741
|
+
* typeof updated.status; // → "string" ("processing" | "valid" | "invalid")
|
|
742
|
+
*/
|
|
743
|
+
async function notifyChallengeReady(challengeUrl) {
|
|
744
|
+
if (typeof challengeUrl !== "string" || challengeUrl.length === 0) {
|
|
745
|
+
throw _err("acme/bad-challenge-url",
|
|
746
|
+
"notifyChallengeReady: challengeUrl must be a non-empty string", true);
|
|
747
|
+
}
|
|
748
|
+
var rsp = await _signedPost(challengeUrl, {});
|
|
749
|
+
if (rsp.statusCode < 200 || rsp.statusCode >= 300) {
|
|
750
|
+
throw _err("acme/challenge-ready",
|
|
751
|
+
"notifyChallengeReady returned " + rsp.statusCode, true, rsp.statusCode);
|
|
752
|
+
}
|
|
753
|
+
return _parseJsonBody(rsp.body, "notifyChallengeReady");
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* @primitive b.acme.create.waitForAuthorization
|
|
758
|
+
* @signature b.acme.create.waitForAuthorization(authUrl, opts?)
|
|
759
|
+
* @since 0.11.22
|
|
760
|
+
*
|
|
761
|
+
* Poll an authorization URL until `status === "valid"` (success) or
|
|
762
|
+
* `status === "invalid"` (CA refused). Throws on invalid OR on
|
|
763
|
+
* timeout (default `pollMaxMs` set at `b.acme.create` time).
|
|
764
|
+
*
|
|
765
|
+
* @opts
|
|
766
|
+
* intervalMs: number, // default — uses the client's pollIntervalMs
|
|
767
|
+
* timeoutMs: number, // default — uses the client's pollMaxMs
|
|
768
|
+
*
|
|
769
|
+
* @example
|
|
770
|
+
* await client.notifyChallengeReady(http01.url);
|
|
771
|
+
* var auth = await client.waitForAuthorization(authUrl);
|
|
772
|
+
* auth.status; // → "valid"
|
|
773
|
+
*/
|
|
774
|
+
async function waitForAuthorization(authUrl, opts2) {
|
|
775
|
+
opts2 = opts2 || {};
|
|
776
|
+
var interval = typeof opts2.intervalMs === "number" ? opts2.intervalMs : pollIntervalMs;
|
|
777
|
+
var deadline = Date.now() + (typeof opts2.timeoutMs === "number" ? opts2.timeoutMs : pollMaxMs);
|
|
778
|
+
while (true) {
|
|
779
|
+
var auth = await fetchAuthorization(authUrl);
|
|
780
|
+
if (auth.status === "valid") return auth;
|
|
781
|
+
if (auth.status === "invalid") {
|
|
782
|
+
_emitAudit(audit, "acme.auth.poll", "failure",
|
|
783
|
+
{ authUrl: authUrl, status: "invalid",
|
|
784
|
+
error: auth.challenges && auth.challenges.find(function (c) { return c.error; }) });
|
|
785
|
+
throw _err("acme/auth-invalid",
|
|
786
|
+
"waitForAuthorization: " + authUrl + " is invalid", true);
|
|
787
|
+
}
|
|
788
|
+
if (Date.now() >= deadline) {
|
|
789
|
+
throw _err("acme/auth-timeout",
|
|
790
|
+
"waitForAuthorization: " + authUrl + " did not reach 'valid' within " +
|
|
791
|
+
(opts2.timeoutMs || pollMaxMs) + "ms", true);
|
|
792
|
+
}
|
|
793
|
+
await _sleep(interval);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* @primitive b.acme.create.buildCsr
|
|
799
|
+
* @signature b.acme.create.buildCsr(opts)
|
|
800
|
+
* @since 0.11.22
|
|
801
|
+
*
|
|
802
|
+
* Build a PKCS#10 (RFC 2986) Certificate Signing Request and sign it
|
|
803
|
+
* with the leaf private key. Subject is `CN=<first domain>`; every
|
|
804
|
+
* domain (including the first) appears as a `dNSName` in the
|
|
805
|
+
* Subject Alternative Name extension. Returns a PEM-encoded
|
|
806
|
+
* `-----BEGIN CERTIFICATE REQUEST-----` block ready to feed to
|
|
807
|
+
* `finalize(order, csrPem)`.
|
|
808
|
+
*
|
|
809
|
+
* Supports ECDSA P-256 / P-384 leaf keys (signed with `ecdsa-with-SHA256`
|
|
810
|
+
* / `ecdsa-with-SHA384` respectively) and RSA 2048 / 3072 / 4096
|
|
811
|
+
* (signed with `sha256WithRSAEncryption`). Ed25519 is rejected at
|
|
812
|
+
* the CSR layer because CA support is uneven; operators wanting
|
|
813
|
+
* Ed25519 certs build the CSR externally.
|
|
814
|
+
*
|
|
815
|
+
* @opts
|
|
816
|
+
* privateKey: crypto.KeyObject, // required — Node-crypto private key handle
|
|
817
|
+
* publicKey: crypto.KeyObject, // required — matching public key handle
|
|
818
|
+
* domains: Array<string>, // required — non-empty; first is CN, all are SANs
|
|
819
|
+
*
|
|
820
|
+
* @example
|
|
821
|
+
* var pair = crypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
|
|
822
|
+
* var csr = client.buildCsr({
|
|
823
|
+
* privateKey: pair.privateKey,
|
|
824
|
+
* publicKey: pair.publicKey,
|
|
825
|
+
* domains: ["example.com", "www.example.com"],
|
|
826
|
+
* });
|
|
827
|
+
* csr.indexOf("-----BEGIN CERTIFICATE REQUEST-----"); // → 0
|
|
828
|
+
*/
|
|
829
|
+
function buildCsr(opts2) {
|
|
830
|
+
if (!opts2 || typeof opts2 !== "object") {
|
|
831
|
+
throw _err("acme/bad-csr-opts", "buildCsr: opts is required", true);
|
|
832
|
+
}
|
|
833
|
+
if (!opts2.privateKey || opts2.privateKey.type !== "private" ||
|
|
834
|
+
typeof opts2.privateKey.export !== "function") {
|
|
835
|
+
throw _err("acme/bad-csr-private-key",
|
|
836
|
+
"buildCsr: privateKey must be a Node KeyObject (private)", true);
|
|
837
|
+
}
|
|
838
|
+
if (!opts2.publicKey || opts2.publicKey.type !== "public" ||
|
|
839
|
+
typeof opts2.publicKey.export !== "function") {
|
|
840
|
+
throw _err("acme/bad-csr-public-key",
|
|
841
|
+
"buildCsr: publicKey must be a Node KeyObject (public)", true);
|
|
842
|
+
}
|
|
843
|
+
if (!Array.isArray(opts2.domains) || opts2.domains.length === 0) {
|
|
844
|
+
throw _err("acme/bad-csr-domains",
|
|
845
|
+
"buildCsr: domains must be a non-empty array of strings", true);
|
|
846
|
+
}
|
|
847
|
+
for (var di = 0; di < opts2.domains.length; di += 1) {
|
|
848
|
+
var d = opts2.domains[di];
|
|
849
|
+
if (typeof d !== "string" || d.length === 0 || d.length > C.BYTES.bytes(255)) {
|
|
850
|
+
throw _err("acme/bad-csr-domain",
|
|
851
|
+
"buildCsr: domains[" + di + "] must be a non-empty string <= 255 bytes", true);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
var keyType = opts2.privateKey.asymmetricKeyType;
|
|
856
|
+
var keyDetails = opts2.privateKey.asymmetricKeyDetails || {};
|
|
857
|
+
|
|
858
|
+
// Pick signature algorithm based on key type.
|
|
859
|
+
var sigOidDotted, sigDigest, sigAlgoAlgId;
|
|
860
|
+
if (keyType === "ec") {
|
|
861
|
+
var curve = keyDetails.namedCurve;
|
|
862
|
+
if (curve === "prime256v1" || curve === "P-256") {
|
|
863
|
+
sigOidDotted = "1.2.840.10045.4.3.2"; // ecdsa-with-SHA256
|
|
864
|
+
sigDigest = "sha256";
|
|
865
|
+
} else if (curve === "secp384r1" || curve === "P-384") {
|
|
866
|
+
sigOidDotted = "1.2.840.10045.4.3.3"; // ecdsa-with-SHA384
|
|
867
|
+
sigDigest = "sha384";
|
|
868
|
+
} else {
|
|
869
|
+
throw _err("acme/bad-csr-curve",
|
|
870
|
+
"buildCsr: ECDSA curve '" + curve + "' is not supported (use P-256 or P-384)", true);
|
|
871
|
+
}
|
|
872
|
+
// For ECDSA the AlgorithmIdentifier has NO parameters (RFC 5758 §3.2).
|
|
873
|
+
sigAlgoAlgId = asn1.writeSequence([asn1.writeOid(sigOidDotted)]);
|
|
874
|
+
} else if (keyType === "rsa") {
|
|
875
|
+
sigOidDotted = "1.2.840.113549.1.1.11"; // sha256WithRSAEncryption
|
|
876
|
+
sigDigest = "sha256";
|
|
877
|
+
// RSA AlgorithmIdentifier carries an explicit NULL parameter
|
|
878
|
+
// (RFC 8017 / RFC 3447 §A.2.4).
|
|
879
|
+
sigAlgoAlgId = asn1.writeSequence([asn1.writeOid(sigOidDotted), asn1.writeNull()]);
|
|
880
|
+
} else {
|
|
881
|
+
throw _err("acme/bad-csr-key-type",
|
|
882
|
+
"buildCsr: keyType '" + keyType + "' is not supported (use ECDSA P-256/P-384 or RSA 2048/3072/4096)", true);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// 1. Build Subject Name — single RDN: CN=<first domain> (UTF8String).
|
|
886
|
+
// Name ::= SEQUENCE OF RelativeDistinguishedName
|
|
887
|
+
// RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
|
|
888
|
+
// AttributeTypeAndValue ::= SEQUENCE { type OID, value ANY }
|
|
889
|
+
var commonName = opts2.domains[0];
|
|
890
|
+
var cnAttr = asn1.writeSequence([
|
|
891
|
+
asn1.writeOid("2.5.4.3"), // id-at-commonName
|
|
892
|
+
asn1.writeUtf8String(commonName),
|
|
893
|
+
]);
|
|
894
|
+
var subjectName = asn1.writeSequence([
|
|
895
|
+
asn1.writeSet([cnAttr]),
|
|
896
|
+
]);
|
|
897
|
+
|
|
898
|
+
// 2. Build SubjectPublicKeyInfo from the public KeyObject.
|
|
899
|
+
var spkiDer = opts2.publicKey.export({ type: "spki", format: "der" });
|
|
900
|
+
|
|
901
|
+
// 3. Build SubjectAltName extension — SEQUENCE OF GeneralName
|
|
902
|
+
// GeneralName ::= CHOICE { ... [2] IA5String dNSName, ... }
|
|
903
|
+
// dNSName has IMPLICIT [2] tag.
|
|
904
|
+
var sanGeneralNames = opts2.domains.map(function (d) {
|
|
905
|
+
// [2] IMPLICIT IA5String — context-specific class, primitive,
|
|
906
|
+
// tag number 2. asn1.writeContextImplicit assembles the value
|
|
907
|
+
// bytes (IA5 chars) directly without the inner UNIVERSAL IA5
|
|
908
|
+
// tag (that's what "implicit" means). Validation above already
|
|
909
|
+
// refuses non-string domains, so d is always a string here.
|
|
910
|
+
return asn1.writeContextImplicit(2, Buffer.from(d, "ascii"));
|
|
911
|
+
});
|
|
912
|
+
var sanExtnValue = asn1.writeSequence(sanGeneralNames);
|
|
913
|
+
// Extension ::= SEQUENCE { extnID OID, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING }
|
|
914
|
+
var sanExtension = asn1.writeSequence([
|
|
915
|
+
asn1.writeOid("2.5.29.17"), // id-ce-subjectAltName
|
|
916
|
+
asn1.writeOctetString(sanExtnValue),
|
|
917
|
+
]);
|
|
918
|
+
|
|
919
|
+
// 4. Build the extensionRequest attribute carrying the SAN.
|
|
920
|
+
// Attribute ::= SEQUENCE { type OID, values SET OF ANY }
|
|
921
|
+
// extensionRequest: type = 1.2.840.113549.1.9.14, values = SET OF Extensions
|
|
922
|
+
var extensionsSeq = asn1.writeSequence([sanExtension]);
|
|
923
|
+
var extensionReqAttr = asn1.writeSequence([
|
|
924
|
+
asn1.writeOid("1.2.840.113549.1.9.14"), // pkcs-9-at-extensionRequest
|
|
925
|
+
asn1.writeSet([extensionsSeq]),
|
|
926
|
+
]);
|
|
927
|
+
|
|
928
|
+
// 5. Build CertificationRequestInfo.
|
|
929
|
+
// CertificationRequestInfo ::= SEQUENCE {
|
|
930
|
+
// version INTEGER (0),
|
|
931
|
+
// subject Name,
|
|
932
|
+
// subjectPKInfo SubjectPublicKeyInfo,
|
|
933
|
+
// attributes [0] IMPLICIT Attributes
|
|
934
|
+
// }
|
|
935
|
+
// [0] IMPLICIT SET OF Attribute — we wrap the existing attr set.
|
|
936
|
+
var attributesField = asn1.writeContextImplicit(0,
|
|
937
|
+
Buffer.concat([extensionReqAttr]), // SET OF Attribute is implicit; one attribute → just its encoding
|
|
938
|
+
{ constructed: true });
|
|
939
|
+
var certReqInfo = asn1.writeSequence([
|
|
940
|
+
asn1.writeInteger(Buffer.from([0])), // version v1 = 0
|
|
941
|
+
subjectName,
|
|
942
|
+
spkiDer,
|
|
943
|
+
attributesField,
|
|
944
|
+
]);
|
|
945
|
+
|
|
946
|
+
// 6. Sign certReqInfo with the leaf private key.
|
|
947
|
+
var signer = nodeCrypto.createSign(sigDigest);
|
|
948
|
+
signer.update(certReqInfo);
|
|
949
|
+
var signature = signer.sign(opts2.privateKey);
|
|
950
|
+
|
|
951
|
+
// 7. Wrap as CertificationRequest.
|
|
952
|
+
var csr = asn1.writeSequence([
|
|
953
|
+
certReqInfo,
|
|
954
|
+
sigAlgoAlgId,
|
|
955
|
+
asn1.writeBitString(signature, 0),
|
|
956
|
+
]);
|
|
957
|
+
|
|
958
|
+
// 8. PEM-encode.
|
|
959
|
+
var b64 = csr.toString("base64");
|
|
960
|
+
var pemBody = b64.match(/.{1,64}/g).join("\n");
|
|
961
|
+
return "-----BEGIN CERTIFICATE REQUEST-----\n" +
|
|
962
|
+
pemBody + "\n" +
|
|
963
|
+
"-----END CERTIFICATE REQUEST-----\n";
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
// ---- public: RFC 9773 ARI ----
|
|
967
|
+
|
|
968
|
+
async function fetchAri(opts2) {
|
|
969
|
+
// Validate cert input BEFORE any network call so misconfigured
|
|
970
|
+
// operators see the bad-cert error without burning a directory
|
|
971
|
+
// round-trip first.
|
|
972
|
+
if (!opts2 || typeof opts2.certPem !== "string") {
|
|
973
|
+
throw _err("acme/bad-ari-input", "fetchAri: certPem is required", true);
|
|
974
|
+
}
|
|
975
|
+
var ext = _extractAkiAndSerial(opts2.certPem);
|
|
976
|
+
if (!state.directory) await fetchDirectory();
|
|
977
|
+
if (typeof state.directory.renewalInfo !== "string") {
|
|
978
|
+
throw _err("acme/no-ari",
|
|
979
|
+
"fetchAri: directory has no renewalInfo endpoint (RFC 9773 not supported by this CA)", true);
|
|
980
|
+
}
|
|
981
|
+
var certId = _b64u(ext.aki) + "." + _b64u(ext.serial);
|
|
982
|
+
var ariUrl = state.directory.renewalInfo.replace(/\/+$/, "") + "/" + certId;
|
|
983
|
+
var rsp = await _httpReq("GET", ariUrl, null);
|
|
984
|
+
if (rsp.statusCode !== 200) {
|
|
985
|
+
throw _err("acme/ari-fetch",
|
|
986
|
+
"ARI GET returned " + rsp.statusCode, true, rsp.statusCode);
|
|
987
|
+
}
|
|
988
|
+
var body = _parseJsonBody(rsp.body, "ari");
|
|
989
|
+
if (!body.suggestedWindow || typeof body.suggestedWindow.start !== "string" ||
|
|
990
|
+
typeof body.suggestedWindow.end !== "string") {
|
|
991
|
+
throw _err("acme/ari-shape",
|
|
992
|
+
"ARI response missing suggestedWindow {start,end}", true);
|
|
993
|
+
}
|
|
994
|
+
var startMs = Date.parse(body.suggestedWindow.start);
|
|
995
|
+
var endMs = Date.parse(body.suggestedWindow.end);
|
|
996
|
+
if (!isFinite(startMs) || !isFinite(endMs) || endMs < startMs) {
|
|
997
|
+
throw _err("acme/ari-shape",
|
|
998
|
+
"ARI suggestedWindow timestamps malformed", true);
|
|
999
|
+
}
|
|
1000
|
+
var retryAfterHeader = rsp.headers && (rsp.headers["retry-after"] || rsp.headers["Retry-After"]);
|
|
1001
|
+
return {
|
|
1002
|
+
suggestedWindow: { start: body.suggestedWindow.start, end: body.suggestedWindow.end,
|
|
1003
|
+
startMs: startMs, endMs: endMs },
|
|
1004
|
+
explanationURL: typeof body.explanationURL === "string" ? body.explanationURL : null,
|
|
1005
|
+
retryAfter: typeof retryAfterHeader === "string" ? retryAfterHeader : null,
|
|
1006
|
+
certId: certId,
|
|
1007
|
+
ariUrl: ariUrl,
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
async function renewIfDue(opts2) {
|
|
1012
|
+
var ari = await fetchAri(opts2);
|
|
1013
|
+
var nowMs = Date.now();
|
|
1014
|
+
// RFC 9773 §4.2 — when called inside the suggested window, return
|
|
1015
|
+
// a renewAt timestamp picked uniformly across the remaining window
|
|
1016
|
+
// so a fleet of operators running on the same poll cadence don't
|
|
1017
|
+
// cluster their renewal storms at the window-start instant. Operators
|
|
1018
|
+
// opt in via `{ jitter: true }`; default behavior preserves the
|
|
1019
|
+
// pre-0.8.83 "renew now" semantics.
|
|
1020
|
+
var jitter = opts2 && opts2.jitter === true;
|
|
1021
|
+
var beforeWindow = nowMs < ari.suggestedWindow.startMs;
|
|
1022
|
+
var pastWindow = nowMs > ari.suggestedWindow.endMs;
|
|
1023
|
+
var renewAtMs = null;
|
|
1024
|
+
if (jitter) {
|
|
1025
|
+
// Uniform random point in [max(now, start), end].
|
|
1026
|
+
var jLo = beforeWindow ? ari.suggestedWindow.startMs : nowMs;
|
|
1027
|
+
var jHi = ari.suggestedWindow.endMs;
|
|
1028
|
+
if (jHi >= jLo) {
|
|
1029
|
+
// Non-crypto: RFC 9773 §4.2 fleet-scheduling jitter inside the
|
|
1030
|
+
// CA-suggested renewal window. Predictability is not a threat
|
|
1031
|
+
// here; uniform distribution across the window is the goal.
|
|
1032
|
+
renewAtMs = jLo + Math.floor(Math.random() * (jHi - jLo + 1)); // allow:math-random-noncrypto — RFC 9773 fleet jitter, predictability not a threat
|
|
1033
|
+
} else {
|
|
1034
|
+
// Past-window — renew immediately, no jitter.
|
|
1035
|
+
renewAtMs = nowMs;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
if (beforeWindow) {
|
|
1039
|
+
_emitAudit(audit, "acme.cert.renew.skipped", "success", {
|
|
1040
|
+
certId: ari.certId,
|
|
1041
|
+
windowStart: ari.suggestedWindow.start,
|
|
1042
|
+
windowEnd: ari.suggestedWindow.end,
|
|
1043
|
+
nowIso: new Date(nowMs).toISOString(),
|
|
1044
|
+
});
|
|
1045
|
+
_emitObs("acme.cert.renew.skipped", { reason: "before-window" });
|
|
1046
|
+
var ret = { shouldRenew: false, reason: "before-window", ari: ari };
|
|
1047
|
+
if (jitter) ret.renewAt = new Date(renewAtMs).toISOString();
|
|
1048
|
+
return ret;
|
|
1049
|
+
}
|
|
1050
|
+
if (pastWindow) {
|
|
1051
|
+
_emitAudit(audit, "acme.cert.renew.scheduled", "warning", {
|
|
1052
|
+
certId: ari.certId,
|
|
1053
|
+
reason: "past-window",
|
|
1054
|
+
windowEnd: ari.suggestedWindow.end,
|
|
1055
|
+
});
|
|
1056
|
+
_emitObs("acme.cert.renew.scheduled", { reason: "past-window" });
|
|
1057
|
+
var rp = { shouldRenew: true, reason: "past-window", ari: ari };
|
|
1058
|
+
if (jitter) rp.renewAt = new Date(renewAtMs).toISOString();
|
|
1059
|
+
return rp;
|
|
1060
|
+
}
|
|
1061
|
+
_emitAudit(audit, "acme.cert.renew.scheduled", "success", {
|
|
1062
|
+
certId: ari.certId,
|
|
1063
|
+
windowStart: ari.suggestedWindow.start,
|
|
1064
|
+
windowEnd: ari.suggestedWindow.end,
|
|
1065
|
+
renewAt: jitter ? new Date(renewAtMs).toISOString() : null,
|
|
1066
|
+
});
|
|
1067
|
+
_emitObs("acme.cert.renew.scheduled", { reason: "in-window" });
|
|
1068
|
+
var ri = { shouldRenew: true, reason: "in-window", ari: ari };
|
|
1069
|
+
if (jitter) ri.renewAt = new Date(renewAtMs).toISOString();
|
|
1070
|
+
return ri;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* @primitive b.acme.create.revokeCert
|
|
1075
|
+
* @signature b.acme.create.revokeCert(certDerBuf, opts?)
|
|
1076
|
+
* @since 0.8.77
|
|
1077
|
+
*
|
|
1078
|
+
* RFC 8555 §7.6 — revoke a previously issued certificate. Accepts
|
|
1079
|
+
* the DER-encoded cert (base64url-encoded automatically) plus an
|
|
1080
|
+
* optional `reason` code per RFC 5280 §5.3.1 (0=unspecified,
|
|
1081
|
+
* 1=keyCompromise, 3=affiliationChanged, 4=superseded, 5=cessationOfOperation).
|
|
1082
|
+
* Signs with the account key by default; pass `useCertKey:true`
|
|
1083
|
+
* + the cert's private key to authorize via the cert's own key
|
|
1084
|
+
* when the account key is unavailable.
|
|
1085
|
+
*
|
|
1086
|
+
* @opts
|
|
1087
|
+
* reason: number, // RFC 5280 §5.3.1 reason code; default 0 (unspecified)
|
|
1088
|
+
* useCertKey: boolean, // sign with the cert's own key instead of account key
|
|
1089
|
+
* certPrivateKey: KeyObject, // required when useCertKey:true
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* await acme.revokeCert(certDerBuffer, { reason: 4 }); // 4 = superseded
|
|
1093
|
+
*/
|
|
1094
|
+
async function revokeCert(certDerBuf, ropts) {
|
|
1095
|
+
ropts = ropts || {};
|
|
1096
|
+
if (!Buffer.isBuffer(certDerBuf) && !(certDerBuf instanceof Uint8Array)) {
|
|
1097
|
+
throw _err("acme/revoke-bad-cert",
|
|
1098
|
+
"revokeCert: certDerBuf must be a Buffer / Uint8Array of the cert's DER bytes", true);
|
|
1099
|
+
}
|
|
1100
|
+
if (!state.directory) await fetchDirectory();
|
|
1101
|
+
if (!state.directory.revokeCert) {
|
|
1102
|
+
throw _err("acme/revoke-not-supported",
|
|
1103
|
+
"revokeCert: directory has no revokeCert endpoint", true);
|
|
1104
|
+
}
|
|
1105
|
+
var payload = { certificate: _b64u(Buffer.from(certDerBuf)) };
|
|
1106
|
+
if (typeof ropts.reason === "number") payload.reason = ropts.reason;
|
|
1107
|
+
var signedOpts = { useJwk: false }; // account-key signed by default
|
|
1108
|
+
if (ropts.useCertKey === true) {
|
|
1109
|
+
// RFC 8555 §7.6 alternate signer: the certificate's own private
|
|
1110
|
+
// key signs the revocation JWS (bypassing the account-key
|
|
1111
|
+
// requirement). Useful when the account that originally issued
|
|
1112
|
+
// the cert is lost / compromised but the cert's private key is
|
|
1113
|
+
// still under operator control.
|
|
1114
|
+
//
|
|
1115
|
+
// Re-open condition: operator surfaces a CA whose only accepted
|
|
1116
|
+
// revocation path is cert-key signing (rare — Let's Encrypt /
|
|
1117
|
+
// ZeroSSL / Google CA all accept account-key signing as the
|
|
1118
|
+
// primary path), OR the operator's account-recovery posture
|
|
1119
|
+
// demands cert-key as a break-glass route. Track via a new opt
|
|
1120
|
+
// shape: `ropts.certPrivateKey: <PEM string>` would route
|
|
1121
|
+
// through a dedicated signed-post that detaches from
|
|
1122
|
+
// state.accountUrl.
|
|
1123
|
+
//
|
|
1124
|
+
// Operator escape hatch today: account-key signing covers every
|
|
1125
|
+
// mainstream public CA. Operators in the rare cert-key-only
|
|
1126
|
+
// scenario reach the CA directly via the CA's own revocation
|
|
1127
|
+
// portal (web UI / out-of-band API) until this lights up.
|
|
1128
|
+
throw _err("acme/revoke-cert-key-not-implemented",
|
|
1129
|
+
"revokeCert: cert-key signing path (RFC 8555 §7.6 alternate) is deferred; " +
|
|
1130
|
+
"use account-key signing (the default, omit useCertKey)", true);
|
|
1131
|
+
}
|
|
1132
|
+
var rsp = await _signedPost(state.directory.revokeCert, payload, signedOpts);
|
|
1133
|
+
if (rsp.statusCode !== 200) {
|
|
1134
|
+
_emitAudit(audit, "acme.cert.revoked", "failure",
|
|
1135
|
+
{ status: rsp.statusCode, reason: _extractProblemReason(rsp.body) });
|
|
1136
|
+
throw _err("acme/revoke-failed",
|
|
1137
|
+
"revokeCert returned " + rsp.statusCode, true, rsp.statusCode);
|
|
1138
|
+
}
|
|
1139
|
+
_emitAudit(audit, "acme.cert.revoked", "success", { reason: ropts.reason || null });
|
|
1140
|
+
_emitObs("acme.cert.revoked", { reason: ropts.reason || 0 });
|
|
1141
|
+
return true;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* @primitive b.acme.create.accountKeyRollover
|
|
1146
|
+
* @signature b.acme.create.accountKeyRollover(newPrivateKey)
|
|
1147
|
+
* @since 0.8.77
|
|
1148
|
+
*
|
|
1149
|
+
* RFC 8555 §7.3.5 — rotate the account key. Inner JWS payload
|
|
1150
|
+
* commits the old + new public JWKs; outer JWS signed by old key
|
|
1151
|
+
* authorizes the rotation. After success, future signed-posts use
|
|
1152
|
+
* the new key. The instance is mutated; callers using multiple
|
|
1153
|
+
* acme instances must rotate each independently.
|
|
1154
|
+
*
|
|
1155
|
+
* @example
|
|
1156
|
+
* var newKey = crypto.generateKeyPairSync("ec", { namedCurve: "P-256" }).privateKey;
|
|
1157
|
+
* await acme.accountKeyRollover(newKey);
|
|
1158
|
+
*/
|
|
1159
|
+
async function accountKeyRollover(newPrivateKey) {
|
|
1160
|
+
if (!state.directory) await fetchDirectory();
|
|
1161
|
+
if (!state.accountUrl) {
|
|
1162
|
+
throw _err("acme/no-account", "accountKeyRollover: call newAccount() first", true);
|
|
1163
|
+
}
|
|
1164
|
+
if (!state.directory.keyChange) {
|
|
1165
|
+
throw _err("acme/key-change-not-supported",
|
|
1166
|
+
"accountKeyRollover: directory has no keyChange endpoint", true);
|
|
1167
|
+
}
|
|
1168
|
+
if (!newPrivateKey || typeof newPrivateKey !== "object") {
|
|
1169
|
+
throw _err("acme/bad-new-key", "accountKeyRollover: newPrivateKey must be a KeyObject", true);
|
|
1170
|
+
}
|
|
1171
|
+
var newPublicJwk = _publicJwkFromKeyObject(newPrivateKey);
|
|
1172
|
+
var innerProtected = {
|
|
1173
|
+
alg: opts.alg || "ES256",
|
|
1174
|
+
jwk: newPublicJwk,
|
|
1175
|
+
url: state.directory.keyChange,
|
|
1176
|
+
};
|
|
1177
|
+
var innerPayload = { account: state.accountUrl, oldKey: publicJwk };
|
|
1178
|
+
var innerJws = _signJws(newPrivateKey, innerProtected, _stringify(innerPayload));
|
|
1179
|
+
var rsp = await _signedPost(state.directory.keyChange, innerJws);
|
|
1180
|
+
if (rsp.statusCode !== 200) {
|
|
1181
|
+
_emitAudit(audit, "acme.account.key_rotated", "failure",
|
|
1182
|
+
{ status: rsp.statusCode, reason: _extractProblemReason(rsp.body) });
|
|
1183
|
+
throw _err("acme/key-change-failed",
|
|
1184
|
+
"accountKeyRollover returned " + rsp.statusCode, true, rsp.statusCode);
|
|
1185
|
+
}
|
|
1186
|
+
// Swap the active key.
|
|
1187
|
+
privateKey = newPrivateKey;
|
|
1188
|
+
publicJwk = newPublicJwk;
|
|
1189
|
+
_emitAudit(audit, "acme.account.key_rotated", "success", { accountUrl: state.accountUrl });
|
|
1190
|
+
_emitObs("acme.account.key_rotated", {});
|
|
1191
|
+
return true;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
/**
|
|
1195
|
+
* @primitive b.acme.create.deactivateAccount
|
|
1196
|
+
* @signature b.acme.create.deactivateAccount()
|
|
1197
|
+
* @since 0.8.77
|
|
1198
|
+
*
|
|
1199
|
+
* RFC 8555 §7.3.6 — deactivate the account. The CA refuses subsequent
|
|
1200
|
+
* requests signed by this account key. Irreversible — operators must
|
|
1201
|
+
* register a new account via newAccount() afterwards.
|
|
1202
|
+
*
|
|
1203
|
+
* @example
|
|
1204
|
+
* await acme.deactivateAccount();
|
|
1205
|
+
*/
|
|
1206
|
+
async function deactivateAccount() {
|
|
1207
|
+
if (!state.accountUrl) {
|
|
1208
|
+
throw _err("acme/no-account", "deactivateAccount: call newAccount() first", true);
|
|
1209
|
+
}
|
|
1210
|
+
var rsp = await _signedPost(state.accountUrl, { status: "deactivated" });
|
|
1211
|
+
if (rsp.statusCode !== 200) {
|
|
1212
|
+
_emitAudit(audit, "acme.account.deactivated", "failure",
|
|
1213
|
+
{ status: rsp.statusCode, reason: _extractProblemReason(rsp.body) });
|
|
1214
|
+
throw _err("acme/deactivate-failed",
|
|
1215
|
+
"deactivateAccount returned " + rsp.statusCode, true, rsp.statusCode);
|
|
1216
|
+
}
|
|
1217
|
+
_emitAudit(audit, "acme.account.deactivated", "success", { accountUrl: state.accountUrl });
|
|
1218
|
+
return true;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* @primitive b.acme.create.tlsAlpn01KeyAuthorization
|
|
1223
|
+
* @signature b.acme.create.tlsAlpn01KeyAuthorization(token)
|
|
1224
|
+
* @since 0.8.77
|
|
1225
|
+
*
|
|
1226
|
+
* RFC 8737 — TLS-ALPN-01 challenge variant. Returns the SHA-256
|
|
1227
|
+
* digest of the key authorization (the value the operator embeds
|
|
1228
|
+
* in the `acme-tls/1` SNI cert's `id-pe-acmeIdentifier` extension).
|
|
1229
|
+
* Operator wires the digest into a one-off cert presented during
|
|
1230
|
+
* the CA's ALPN-ALPN-1 probe. Pairs with HTTP-01 + DNS-01 as the
|
|
1231
|
+
* three RFC 8555 / RFC 8737 challenge types.
|
|
1232
|
+
*
|
|
1233
|
+
* @example
|
|
1234
|
+
* var digest = acme.tlsAlpn01KeyAuthorization(challengeToken);
|
|
1235
|
+
* // embed `digest` in the acme-tls/1 cert's acmeIdentifier extension.
|
|
1236
|
+
*/
|
|
1237
|
+
function tlsAlpn01KeyAuthorization(token) {
|
|
1238
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
1239
|
+
throw _err("acme/bad-token", "tlsAlpn01KeyAuthorization: token must be a non-empty string", true);
|
|
1240
|
+
}
|
|
1241
|
+
var keyAuth = token + "." + _jwkThumbprint(publicJwk);
|
|
1242
|
+
var nodeCrypto = require("node:crypto");
|
|
1243
|
+
return nodeCrypto.createHash("sha256").update(keyAuth, "utf8").digest();
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* @primitive b.acme.create.listProfiles
|
|
1248
|
+
* @signature b.acme.create.listProfiles()
|
|
1249
|
+
* @since 0.8.83
|
|
1250
|
+
* @status experimental
|
|
1251
|
+
*
|
|
1252
|
+
* Returns the CA-advertised certificate profile catalog as
|
|
1253
|
+
* `{ name: description }` per draft-aaron-acme-profiles. Operators
|
|
1254
|
+
* pass the chosen name through `newOrder({ profile: name })`; CAs
|
|
1255
|
+
* use the profile to select certificate lifetime + key-usage +
|
|
1256
|
+
* validation rigor. As CA/B Forum 47-day cert TTLs phase in (Mar
|
|
1257
|
+
* 2026 ballot SC-081v3), profile-name vocabulary becomes the
|
|
1258
|
+
* operator-facing handle for "long-lived" vs "47-day" vs "short-
|
|
1259
|
+
* lived". Returns an empty object when the directory has no
|
|
1260
|
+
* `meta.profiles` map (CA hasn't adopted the draft). Refreshes the
|
|
1261
|
+
* directory cache when none has been fetched yet.
|
|
1262
|
+
*
|
|
1263
|
+
* @example
|
|
1264
|
+
* await acme.fetchDirectory();
|
|
1265
|
+
* var profiles = acme.listProfiles();
|
|
1266
|
+
* // → { "default": "Standard 90-day certificate",
|
|
1267
|
+
* // "shortlived": "47-day certificate (CA/B Forum SC-081v3)",
|
|
1268
|
+
* // "tlsserver": "TLS server profile with Must-Staple" }
|
|
1269
|
+
*
|
|
1270
|
+
* await acme.newOrder({ identifiers: [{ type: "dns", value: "example.com" }],
|
|
1271
|
+
* profile: "shortlived" });
|
|
1272
|
+
*/
|
|
1273
|
+
function listProfiles() {
|
|
1274
|
+
if (!state.directory) return {};
|
|
1275
|
+
var meta = state.directory.meta;
|
|
1276
|
+
if (!meta || typeof meta !== "object") return {};
|
|
1277
|
+
var profiles = meta.profiles;
|
|
1278
|
+
if (!profiles || typeof profiles !== "object") return {};
|
|
1279
|
+
var out = {};
|
|
1280
|
+
var keys = Object.keys(profiles);
|
|
1281
|
+
for (var i = 0; i < keys.length; i += 1) {
|
|
1282
|
+
var k = keys[i];
|
|
1283
|
+
var v = profiles[k];
|
|
1284
|
+
out[k] = typeof v === "string" ? v : "";
|
|
1285
|
+
}
|
|
1286
|
+
return out;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* @primitive b.acme.create.dnsAccount01ChallengeRecord
|
|
1291
|
+
* @signature b.acme.create.dnsAccount01ChallengeRecord(token, opts?)
|
|
1292
|
+
* @since 0.8.83
|
|
1293
|
+
* @status experimental
|
|
1294
|
+
* @related b.acme.create.tlsAlpn01KeyAuthorization
|
|
1295
|
+
*
|
|
1296
|
+
* Build the DNS TXT record an operator publishes to satisfy a
|
|
1297
|
+
* `dns-account-01` challenge per draft-ietf-acme-dns-account-label.
|
|
1298
|
+
* Unlike `dns-01` (record at `_acme-challenge.<host>`),
|
|
1299
|
+
* `dns-account-01` scopes the record by account so the same domain
|
|
1300
|
+
* can be validated from multiple ACME accounts without record-name
|
|
1301
|
+
* collisions; the record name becomes
|
|
1302
|
+
* `_<accountLabel>._acme-challenge.<identifier>` where
|
|
1303
|
+
* `accountLabel` is the SHA-256 truncated-base32 of the account URL.
|
|
1304
|
+
*
|
|
1305
|
+
* Returns `{ name, value, ttl }` where `name` is the FQDN to publish
|
|
1306
|
+
* the TXT record at (with operator-supplied `identifier` substituted
|
|
1307
|
+
* in) and `value` is the SHA-256 of the key authorization in
|
|
1308
|
+
* unpadded base64url (same as `dns-01`). Refuses when `newAccount`
|
|
1309
|
+
* has not run (no accountUrl yet); refuses non-string token /
|
|
1310
|
+
* identifier.
|
|
1311
|
+
*
|
|
1312
|
+
* @opts
|
|
1313
|
+
* identifier: string, // host being validated (required)
|
|
1314
|
+
* ttl: number, // suggested DNS TTL in seconds; default: 60
|
|
1315
|
+
*
|
|
1316
|
+
* @example
|
|
1317
|
+
* await acme.newAccount({ contact: ["mailto:ops@example.com"] });
|
|
1318
|
+
* var rec = acme.dnsAccount01ChallengeRecord("token123", {
|
|
1319
|
+
* identifier: "example.com",
|
|
1320
|
+
* });
|
|
1321
|
+
* // rec.name → "_<accountLabel>._acme-challenge.example.com"
|
|
1322
|
+
* // rec.value → "<base64url-of-sha256(token123.<thumbprint>)>"
|
|
1323
|
+
* // rec.ttl → 60
|
|
1324
|
+
*/
|
|
1325
|
+
function dnsAccount01ChallengeRecord(token, opts2) {
|
|
1326
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
1327
|
+
throw _err("acme/bad-token", "dnsAccount01ChallengeRecord: token must be a non-empty string", true);
|
|
1328
|
+
}
|
|
1329
|
+
if (!opts2 || typeof opts2 !== "object" || typeof opts2.identifier !== "string" || opts2.identifier.length === 0) {
|
|
1330
|
+
throw _err("acme/bad-identifier", "dnsAccount01ChallengeRecord: opts.identifier (host) is required", true);
|
|
1331
|
+
}
|
|
1332
|
+
if (opts2.identifier.length > C.BYTES.bytes(255)) {
|
|
1333
|
+
throw _err("acme/bad-identifier", "dnsAccount01ChallengeRecord: identifier exceeds 255 bytes", true);
|
|
1334
|
+
}
|
|
1335
|
+
if (!state.accountUrl) {
|
|
1336
|
+
throw _err("acme/no-account",
|
|
1337
|
+
"dnsAccount01ChallengeRecord: newAccount() must run first (account URL is the label seed)", true);
|
|
1338
|
+
}
|
|
1339
|
+
if (opts2.ttl !== undefined && (typeof opts2.ttl !== "number" || !isFinite(opts2.ttl) || opts2.ttl < 1 || opts2.ttl > C.TIME.hours(24) / C.TIME.seconds(1))) {
|
|
1340
|
+
throw _err("acme/bad-ttl",
|
|
1341
|
+
"dnsAccount01ChallengeRecord: ttl must be a positive integer <= 86400 seconds", true);
|
|
1342
|
+
}
|
|
1343
|
+
var nodeCrypto = require("node:crypto");
|
|
1344
|
+
// Account label: lowercase base32 of first 10 bytes of SHA-256(accountUrl)
|
|
1345
|
+
// (per draft-ietf-acme-dns-account-label §3.1 — 80-bit truncated label).
|
|
1346
|
+
var hash = nodeCrypto.createHash("sha256").update(state.accountUrl, "utf8").digest();
|
|
1347
|
+
var label = _base32lc(hash.subarray(0, 10));
|
|
1348
|
+
// Record value: same key-authorization digest shape as dns-01.
|
|
1349
|
+
var keyAuth = token + "." + _jwkThumbprint(publicJwk);
|
|
1350
|
+
var digest = nodeCrypto.createHash("sha256").update(keyAuth, "utf8").digest();
|
|
1351
|
+
return {
|
|
1352
|
+
name: "_" + label + "._acme-challenge." + opts2.identifier,
|
|
1353
|
+
value: _b64u(digest),
|
|
1354
|
+
ttl: typeof opts2.ttl === "number" ? Math.floor(opts2.ttl) : (C.TIME.minutes(1) / C.TIME.seconds(1)),
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
return Object.freeze({
|
|
1359
|
+
fetchDirectory: fetchDirectory,
|
|
1360
|
+
newAccount: newAccount,
|
|
1361
|
+
newOrder: newOrder,
|
|
1362
|
+
finalize: finalize,
|
|
1363
|
+
retrieveCert: retrieveCert,
|
|
1364
|
+
fetchAuthorization: fetchAuthorization,
|
|
1365
|
+
notifyChallengeReady: notifyChallengeReady,
|
|
1366
|
+
waitForAuthorization: waitForAuthorization,
|
|
1367
|
+
buildCsr: buildCsr,
|
|
1368
|
+
fetchAri: fetchAri,
|
|
1369
|
+
renewIfDue: renewIfDue,
|
|
1370
|
+
revokeCert: revokeCert,
|
|
1371
|
+
accountKeyRollover: accountKeyRollover,
|
|
1372
|
+
deactivateAccount: deactivateAccount,
|
|
1373
|
+
tlsAlpn01KeyAuthorization: tlsAlpn01KeyAuthorization,
|
|
1374
|
+
listProfiles: listProfiles,
|
|
1375
|
+
dnsAccount01ChallengeRecord: dnsAccount01ChallengeRecord,
|
|
1376
|
+
accountUrl: function () { return state.accountUrl; },
|
|
1377
|
+
directory: function () { return state.directory; },
|
|
1378
|
+
publicJwk: function () { return Object.assign({}, publicJwk); },
|
|
1379
|
+
keyAuthorization: function (token) {
|
|
1380
|
+
// RFC 8555 §8.1 — token + "." + base64url(SHA-256(JWK thumbprint)).
|
|
1381
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
1382
|
+
throw _err("acme/bad-token", "keyAuthorization: token must be a non-empty string", true);
|
|
1383
|
+
}
|
|
1384
|
+
return token + "." + _jwkThumbprint(publicJwk);
|
|
1385
|
+
},
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
// ---- helpers ----
|
|
1390
|
+
|
|
1391
|
+
function _parseJsonBody(body, where) {
|
|
1392
|
+
if (!body) return {};
|
|
1393
|
+
var s = Buffer.isBuffer(body) ? body.toString("utf8") : String(body);
|
|
1394
|
+
if (s.length === 0) return {};
|
|
1395
|
+
var parsed;
|
|
1396
|
+
try {
|
|
1397
|
+
parsed = safeJson.parse(s, { maxBytes: DEFAULT_BODY_CAP });
|
|
1398
|
+
} catch (e) {
|
|
1399
|
+
throw _err("acme/bad-json", where + " response is not valid JSON: " + e.message, true);
|
|
1400
|
+
}
|
|
1401
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
1402
|
+
throw _err("acme/bad-json", where + " response is not a JSON object", true);
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
function _extractProblemReason(body) {
|
|
1406
|
+
// RFC 7807 application/problem+json
|
|
1407
|
+
if (!body) return null;
|
|
1408
|
+
try {
|
|
1409
|
+
var parsed = _parseJsonBody(body, "problem");
|
|
1410
|
+
return (typeof parsed.type === "string" ? parsed.type : null) ||
|
|
1411
|
+
(typeof parsed.detail === "string" ? parsed.detail : null) ||
|
|
1412
|
+
(typeof parsed.title === "string" ? parsed.title : null);
|
|
1413
|
+
} catch (_e) { return null; }
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
function _sleep(ms) {
|
|
1417
|
+
return new Promise(function (resolve) {
|
|
1418
|
+
var t = setTimeout(resolve, ms);
|
|
1419
|
+
if (t && typeof t.unref === "function") t.unref();
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
// RFC 4648 §6 base32 lowercase (no padding) — used by
|
|
1424
|
+
// draft-ietf-acme-dns-account-label to derive the 80-bit account label
|
|
1425
|
+
// from SHA-256(accountUrl). 5-bit groups MSB-first.
|
|
1426
|
+
function _base32lc(buf) {
|
|
1427
|
+
var alphabet = "abcdefghijklmnopqrstuvwxyz234567";
|
|
1428
|
+
var out = "";
|
|
1429
|
+
var bits = 0;
|
|
1430
|
+
var value = 0;
|
|
1431
|
+
for (var i = 0; i < buf.length; i += 1) {
|
|
1432
|
+
value = (value << 8) | buf[i]; // allow:raw-byte-literal — bit-shift count, byte boundary
|
|
1433
|
+
bits += 8; // allow:raw-byte-literal — bits-per-byte constant
|
|
1434
|
+
while (bits >= 5) {
|
|
1435
|
+
out += alphabet[(value >>> (bits - 5)) & 31];
|
|
1436
|
+
bits -= 5;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
if (bits > 0) {
|
|
1440
|
+
out += alphabet[(value << (5 - bits)) & 31];
|
|
1441
|
+
}
|
|
1442
|
+
return out;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
module.exports = {
|
|
1446
|
+
create: create,
|
|
1447
|
+
AcmeError: AcmeError,
|
|
1448
|
+
};
|