@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,964 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.middleware.idempotencyKey
|
|
4
|
+
* @nav Middleware
|
|
5
|
+
* @title Idempotency-Key
|
|
6
|
+
* @order 400
|
|
7
|
+
*
|
|
8
|
+
* @intro
|
|
9
|
+
* draft-ietf-httpapi-idempotency-key middleware — replay-safe POST /
|
|
10
|
+
* PUT / PATCH / DELETE handling for retry-capable clients. A client
|
|
11
|
+
* sends `Idempotency-Key: <opaque>` on a mutating request; the
|
|
12
|
+
* middleware:
|
|
13
|
+
*
|
|
14
|
+
* 1. Looks up the key in the operator-supplied `store`. A hit
|
|
15
|
+
* replays the cached `{ statusCode, headers, body }` without
|
|
16
|
+
* invoking the handler (idempotent replay).
|
|
17
|
+
* 2. Compares the inbound request fingerprint (method + path +
|
|
18
|
+
* body hash) against the cached fingerprint. A mismatch is a
|
|
19
|
+
* client-side mistake — same key, different request — and
|
|
20
|
+
* refuses with 422 + RFC 9457 Problem Details
|
|
21
|
+
* `idempotency/key-reuse-mismatch` per the draft §4.3.
|
|
22
|
+
* 3. On miss, attaches a capture wrapper to `res.end` so the
|
|
23
|
+
* handler's response is intercepted, persisted, and replayed
|
|
24
|
+
* on every subsequent retry within `ttlMs`.
|
|
25
|
+
*
|
|
26
|
+
* `Idempotency-Key` is OPTIONAL — clients that don't send it skip
|
|
27
|
+
* the cache and the middleware is a no-op. Idempotency is a
|
|
28
|
+
* client-asserted contract; the server promises "if you send the
|
|
29
|
+
* same key + same body, you get the same answer." Operators
|
|
30
|
+
* wanting strict idempotency on a particular route compose with
|
|
31
|
+
* `requireIdempotencyKey: true` to refuse missing headers with
|
|
32
|
+
* `400 idempotency/missing-key`.
|
|
33
|
+
*
|
|
34
|
+
* Store interface is operator-supplied so cluster deployments can
|
|
35
|
+
* plug their distributed store (Redis, SQLite-cluster, etc.). The
|
|
36
|
+
* first-party `memoryStore` is included for single-instance
|
|
37
|
+
* testing — it accepts `{ ttlMs }` and exposes `_resetForTest()`.
|
|
38
|
+
*
|
|
39
|
+
* @card
|
|
40
|
+
* draft-ietf-httpapi-idempotency-key middleware — replay-safe POST/PUT/PATCH/DELETE handling for retry-capable clients with operator-supplied distributed store.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
var nodeCrypto = require("node:crypto");
|
|
44
|
+
var lazyRequire = require("../lazy-require");
|
|
45
|
+
var numericBounds = require("../numeric-bounds");
|
|
46
|
+
var validateOpts = require("../validate-opts");
|
|
47
|
+
var safeBuffer = require("../safe-buffer");
|
|
48
|
+
var safeJson = require("../safe-json");
|
|
49
|
+
var safeSql = require("../safe-sql");
|
|
50
|
+
var bCrypto = require("../crypto");
|
|
51
|
+
var cryptoField = require("../crypto-field");
|
|
52
|
+
var vault = require("../vault");
|
|
53
|
+
var { defineClass } = require("../framework-error");
|
|
54
|
+
|
|
55
|
+
var audit = lazyRequire(function () { return require("../audit"); });
|
|
56
|
+
var problemDetails = lazyRequire(function () { return require("../problem-details"); });
|
|
57
|
+
var C = require("../constants");
|
|
58
|
+
|
|
59
|
+
var IdempotencyError = defineClass("IdempotencyError", { alwaysPermanent: true });
|
|
60
|
+
|
|
61
|
+
// Default applicable methods per draft-ietf-httpapi-idempotency-key §3:
|
|
62
|
+
// GET / HEAD / OPTIONS are inherently idempotent (RFC 9110 §9.2.2) so
|
|
63
|
+
// the middleware skips them by default. DELETE is included because
|
|
64
|
+
// the draft endorses it as the canonical "idempotent but not safe"
|
|
65
|
+
// retry surface.
|
|
66
|
+
var DEFAULT_METHODS = Object.freeze(["POST", "PUT", "PATCH", "DELETE"]);
|
|
67
|
+
|
|
68
|
+
// Idempotency-Key shape per the draft §2 — ASCII printable, no
|
|
69
|
+
// control chars, length 1..255 (typical client implementations cap
|
|
70
|
+
// at 36 for UUID + a few extra for vendor prefixes; 255 is the
|
|
71
|
+
// upper bound that still fits a single HTTP header line).
|
|
72
|
+
var KEY_RE = /^[\x21-\x7E]+$/; // allow:raw-byte-literal — printable ASCII codepoint range
|
|
73
|
+
var KEY_MAX_LEN = 255; // allow:raw-byte-literal — draft §2 upper bound
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @primitive b.middleware.idempotencyKey.memoryStore
|
|
77
|
+
* @signature b.middleware.idempotencyKey.memoryStore(opts?)
|
|
78
|
+
* @since 0.8.84
|
|
79
|
+
* @status stable
|
|
80
|
+
* @related b.middleware.idempotencyKey
|
|
81
|
+
*
|
|
82
|
+
* First-party in-memory store for `idempotencyKey` middleware.
|
|
83
|
+
* Single-instance only — cluster deployments compose against a
|
|
84
|
+
* distributed store (Redis / SQLite-cluster) matching the
|
|
85
|
+
* three-method interface: `get(key) → record | null`,
|
|
86
|
+
* `set(key, value, ttlMs)`, `delete(key)`. TTL is enforced lazily
|
|
87
|
+
* at read time; the store's resident size is operator-supplied via
|
|
88
|
+
* `opts.maxEntries` (default 10000) — when the cap is hit, the
|
|
89
|
+
* oldest entry is evicted (FIFO; the recorded request was
|
|
90
|
+
* idempotent anyway so re-running is correct, not just safe).
|
|
91
|
+
*
|
|
92
|
+
* @opts
|
|
93
|
+
* maxEntries: number, // default 10000 — FIFO eviction on overflow
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* var store = b.middleware.idempotencyKey.memoryStore({ maxEntries: 5000 });
|
|
97
|
+
* var mw = b.middleware.idempotencyKey({ store: store, ttlMs: C.TIME.hours(24) });
|
|
98
|
+
* app.use(mw);
|
|
99
|
+
*/
|
|
100
|
+
function memoryStore(opts) {
|
|
101
|
+
opts = opts || {};
|
|
102
|
+
numericBounds.requirePositiveFiniteIntIfPresent(
|
|
103
|
+
opts.maxEntries, "memoryStore.maxEntries", IdempotencyError, "idempotency/bad-max-entries");
|
|
104
|
+
var maxEntries = opts.maxEntries !== undefined ? opts.maxEntries : 10000; // allow:raw-byte-literal — default in-memory cap, not bytes
|
|
105
|
+
var data = new Map();
|
|
106
|
+
return {
|
|
107
|
+
get: function (key) {
|
|
108
|
+
var rec = data.get(key);
|
|
109
|
+
if (!rec) return null;
|
|
110
|
+
if (rec.expiresAt < Date.now()) {
|
|
111
|
+
data.delete(key);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return rec.value;
|
|
115
|
+
},
|
|
116
|
+
set: function (key, value, ttlMs) {
|
|
117
|
+
if (data.size >= maxEntries) {
|
|
118
|
+
var oldest = data.keys().next().value;
|
|
119
|
+
data.delete(oldest);
|
|
120
|
+
}
|
|
121
|
+
data.set(key, { value: value, expiresAt: Date.now() + ttlMs });
|
|
122
|
+
},
|
|
123
|
+
delete: function (key) {
|
|
124
|
+
data.delete(key);
|
|
125
|
+
},
|
|
126
|
+
_resetForTest: function () {
|
|
127
|
+
data.clear();
|
|
128
|
+
},
|
|
129
|
+
_size: function () { return data.size; },
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Operator-supplied table name is validated via b.safeSql.validateIdentifier
|
|
134
|
+
// — single source of truth for the framework's SQL-identifier shape
|
|
135
|
+
// (ASCII identifier chars only, 63-char cap, no reserved words). Direct
|
|
136
|
+
// interpolation is safe once the validator throws on bad input.
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @primitive b.middleware.idempotencyKey.dbStore
|
|
140
|
+
* @signature b.middleware.idempotencyKey.dbStore(opts)
|
|
141
|
+
* @since 0.9.14
|
|
142
|
+
* @status stable
|
|
143
|
+
* @related b.middleware.idempotencyKey, b.middleware.idempotencyKey.memoryStore, b.db, b.cryptoField
|
|
144
|
+
*
|
|
145
|
+
* Persistent-backed store for `idempotencyKey` middleware. Implements
|
|
146
|
+
* the same three-method interface as `memoryStore` (`get` / `set` /
|
|
147
|
+
* `delete`) but stores records in a SQLite-shaped database — the
|
|
148
|
+
* framework's internal `b.db`, an operator-supplied better-sqlite3
|
|
149
|
+
* instance, or any object exposing `prepare(sql) → { run, get, all }`.
|
|
150
|
+
*
|
|
151
|
+
* Use `dbStore` instead of `memoryStore` when:
|
|
152
|
+
*
|
|
153
|
+
* - multiple processes share the request-handling fleet (forks
|
|
154
|
+
* behind a load balancer, multi-instance K8s deployment) and a
|
|
155
|
+
* retry can land on a different process than the original;
|
|
156
|
+
* - the daemon may restart between the original request and the
|
|
157
|
+
* retry (graceful rolling deploy, OOM kill, planned reboot) —
|
|
158
|
+
* `memoryStore` is volatile, `dbStore` survives the restart;
|
|
159
|
+
* - audit / compliance review needs to walk historic
|
|
160
|
+
* idempotency cache decisions queryable with
|
|
161
|
+
* `SELECT k, status_code, expires_at FROM <tableName>` —
|
|
162
|
+
* non-sealed columns are forensic-queryable without unsealing.
|
|
163
|
+
*
|
|
164
|
+
* **Defense-in-depth defaults — every option below ships on by default:**
|
|
165
|
+
*
|
|
166
|
+
* - `hashKeys: true` (since 0.9.15) — operator-supplied keys are
|
|
167
|
+
* sha3-512 namespace-hashed via
|
|
168
|
+
* `b.crypto.namespaceHash("idempotency-key", key)` before
|
|
169
|
+
* insert/lookup. The `k` column carries the hash, not the raw key.
|
|
170
|
+
* Operator keys often carry PII (order numbers, emails, vendor
|
|
171
|
+
* prefixes); the DB never sees them.
|
|
172
|
+
* - `seal: true` (since 0.9.15) — `headers` and `body` columns are
|
|
173
|
+
* sealed via `b.cryptoField.sealRow` (vault-managed key, AEAD
|
|
174
|
+
* envelope) so a DB dump leaks neither cached response bodies nor
|
|
175
|
+
* headers. Requires `b.vault.init(...)` to have run; falls back to
|
|
176
|
+
* plain-text with a one-shot audit warning when vault isn't ready,
|
|
177
|
+
* so test-fixture / boot-script callers still work.
|
|
178
|
+
* - `aad: true` (since 0.9.58 — CRYPTO-1) — sealed columns are bound
|
|
179
|
+
* via Additional Authenticated Data to (table, k, column,
|
|
180
|
+
* schemaVersion) so a DB-write attacker can't copy a sealed
|
|
181
|
+
* header/body cell from one row to another (which previously
|
|
182
|
+
* decrypted cleanly under plain `vault.seal`). Existing v0.9.15-
|
|
183
|
+
* v0.9.57 dbStore tables continue to read because unsealRow auto-
|
|
184
|
+
* detects the envelope shape; lazy re-seal on next `set()` upgrades
|
|
185
|
+
* each row to AAD form. Operators wanting a one-shot migration
|
|
186
|
+
* call `b.middleware.idempotencyKey.resealMigrate(store)`.
|
|
187
|
+
* - `fingerprintSeal: true` (since 0.9.58 — CRYPTO-4) — the request
|
|
188
|
+
* `fingerprint` column carries an HMAC under a vault-derived
|
|
189
|
+
* secret instead of a bare SHA3-256 of method+path+body. The
|
|
190
|
+
* compare path is constant-time so the column doubles as a
|
|
191
|
+
* mismatch oracle without offline-brute-force exposure.
|
|
192
|
+
* - `bodyFingerprintFallback: "deny"` (since 0.9.58 — SUBSTRATE-13) —
|
|
193
|
+
* when neither `bodyFingerprint` nor `req._rawBody`/`req.body` is
|
|
194
|
+
* populated for a body-bearing method, the middleware previously
|
|
195
|
+
* silently degraded the fingerprint to method+path. Set to
|
|
196
|
+
* `"deny"` (the new default) and the middleware refuses the
|
|
197
|
+
* request with HTTP 400 `idempotency/missing-body-fingerprint`
|
|
198
|
+
* instead. Operators with a documented "no body" use case set
|
|
199
|
+
* `bodyFingerprintFallback: "method-path-only"` to restore the
|
|
200
|
+
* pre-0.9.58 behavior — the audit chain still emits
|
|
201
|
+
* `idempotency.empty_body_fingerprint` so the misorder is visible.
|
|
202
|
+
*
|
|
203
|
+
* Lazily-expired: `get(key)` returns `null` for any row whose
|
|
204
|
+
* `expires_at` has passed. The cleanup is scoped by the observed
|
|
205
|
+
* `expires_at` so a concurrent upsert from a sibling process isn't
|
|
206
|
+
* clobbered.
|
|
207
|
+
*
|
|
208
|
+
* **Schema (v0.9.15, split columns):**
|
|
209
|
+
*
|
|
210
|
+
* ```
|
|
211
|
+
* k TEXT PRIMARY KEY -- hashed key when hashKeys=true
|
|
212
|
+
* fingerprint TEXT NOT NULL -- request method+path+body digest
|
|
213
|
+
* status_code INTEGER NOT NULL -- forensic-queryable
|
|
214
|
+
* headers TEXT NOT NULL -- JSON, sealed when seal=true
|
|
215
|
+
* body TEXT NOT NULL -- base64, sealed when seal=true
|
|
216
|
+
* expires_at INTEGER NOT NULL
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* **Migration note**: v0.9.14 used a single `v` JSON envelope column.
|
|
220
|
+
* Operators with a v0.9.14 table must `DROP TABLE <tableName>;` (or
|
|
221
|
+
* pick a fresh `tableName`) before upgrading — `CREATE TABLE IF NOT
|
|
222
|
+
* EXISTS` won't migrate column layout. Pre-v1 the framework breaks
|
|
223
|
+
* across patch versions for security correctness.
|
|
224
|
+
*
|
|
225
|
+
* @opts
|
|
226
|
+
* db: object, // required — sqlite-shaped: { prepare(sql) → { run, get, all } }
|
|
227
|
+
* tableName?: string, // default "blamejs_idempotency_keys"; validated via b.safeSql.validateIdentifier
|
|
228
|
+
* init?: boolean, // default true — run CREATE TABLE IF NOT EXISTS at construction
|
|
229
|
+
* hashKeys?: boolean, // default true — store sha3-512 namespace-hash of the key, not the raw key
|
|
230
|
+
* seal?: boolean, // default true — seal headers + body via b.cryptoField when vault is ready
|
|
231
|
+
* aad?: boolean, // default true — AAD-bind seal to (table,k,column) so a DB-write attacker can't cross-row swap (CRYPTO-1)
|
|
232
|
+
* fingerprintSeal?: boolean, // default true — HMAC fingerprint under a vault-derived secret instead of bare sha3-256 (CRYPTO-4)
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* // single-process daemon, framework's internal sqlite, both defaults on:
|
|
236
|
+
* var b = require("blamejs");
|
|
237
|
+
* await b.vault.init({ dataDir: "/var/lib/myapp" });
|
|
238
|
+
* await b.db.init({ dataDir: "/var/lib/myapp", schema: [] });
|
|
239
|
+
* var store = b.middleware.idempotencyKey.dbStore({ db: b.db });
|
|
240
|
+
* var mw = b.middleware.idempotencyKey({
|
|
241
|
+
* store: store,
|
|
242
|
+
* ttlMs: b.constants.TIME.hours(24),
|
|
243
|
+
* });
|
|
244
|
+
* app.use(mw);
|
|
245
|
+
*/
|
|
246
|
+
function dbStore(opts) {
|
|
247
|
+
opts = opts || {};
|
|
248
|
+
if (!opts.db || typeof opts.db !== "object" || typeof opts.db.prepare !== "function") {
|
|
249
|
+
throw new IdempotencyError("idempotency/bad-db",
|
|
250
|
+
"dbStore: opts.db must be a sqlite-shaped database with a `prepare(sql)` method", true);
|
|
251
|
+
}
|
|
252
|
+
var tableNameRaw = opts.tableName !== undefined ? opts.tableName : "blamejs_idempotency_keys";
|
|
253
|
+
// Quote-and-validate via safeSql.quoteIdentifier — runs
|
|
254
|
+
// validateIdentifier internally + emits the dialect-correct quoted
|
|
255
|
+
// form. Identifier always reaches SQL through the quoted form.
|
|
256
|
+
var qTable;
|
|
257
|
+
try { qTable = safeSql.quoteIdentifier(tableNameRaw, "sqlite"); }
|
|
258
|
+
catch (sqlErr) {
|
|
259
|
+
throw new IdempotencyError("idempotency/bad-table-name",
|
|
260
|
+
"dbStore: opts.tableName is not a valid SQL identifier: " +
|
|
261
|
+
(sqlErr && sqlErr.message ? sqlErr.message : String(sqlErr)), true);
|
|
262
|
+
}
|
|
263
|
+
var qIndex = safeSql.quoteIdentifier(tableNameRaw + "_expires_idx", "sqlite");
|
|
264
|
+
var doInit = opts.init !== false;
|
|
265
|
+
var hashKeys = opts.hashKeys !== false;
|
|
266
|
+
var sealReq = opts.seal !== false;
|
|
267
|
+
// CRYPTO-1 — AAD-bind sealing to (table, k, column) by default.
|
|
268
|
+
// Forms a defense-in-depth pair with seal: cross-row swap fails
|
|
269
|
+
// Poly1305 even when the attacker controls the DB layer.
|
|
270
|
+
var aadOn = opts.aad !== false;
|
|
271
|
+
// CRYPTO-4 — HMAC the fingerprint under a vault-derived secret by
|
|
272
|
+
// default. Bare SHA3-256 of method+path+body is offline-brute-
|
|
273
|
+
// forceable for any DB-dump attacker; HMAC under a vault secret
|
|
274
|
+
// forces them to break the vault first.
|
|
275
|
+
var fpSealOn = opts.fingerprintSeal !== false;
|
|
276
|
+
var db = opts.db;
|
|
277
|
+
|
|
278
|
+
// Probe vault readiness with a sentinel seal. If vault.init() hasn't
|
|
279
|
+
// run (test fixture / boot-script / operator simply hasn't wired the
|
|
280
|
+
// posture yet) sealing falls back to plaintext for the lifetime of
|
|
281
|
+
// this dbStore instance and a single audit warning emits so the
|
|
282
|
+
// posture gap is visible in the chain.
|
|
283
|
+
var sealEnabled = false;
|
|
284
|
+
if (sealReq) {
|
|
285
|
+
try {
|
|
286
|
+
// allow:seal-without-aad — vault-readiness probe; throwaway
|
|
287
|
+
// sentinel value, not row-bound data
|
|
288
|
+
vault.seal("__idempotency_seal_probe__");
|
|
289
|
+
sealEnabled = true;
|
|
290
|
+
} catch (_vaultErr) {
|
|
291
|
+
_emitAudit("idempotency.seal_skipped_no_vault",
|
|
292
|
+
{ tableName: tableNameRaw,
|
|
293
|
+
reason: "vault.init() has not run; sealing falls back to plaintext" },
|
|
294
|
+
"warning");
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Register the table with cryptoField. registerTable is idempotent
|
|
299
|
+
// — subsequent dbStore() calls with the same tableName re-declare
|
|
300
|
+
// the same sealedFields and no-op. CRYPTO-1: when aad is on,
|
|
301
|
+
// (table, k, column) is threaded into the AEAD AAD so a DB-write
|
|
302
|
+
// attacker can't copy a sealed value between rows.
|
|
303
|
+
if (sealEnabled) {
|
|
304
|
+
cryptoField.registerTable(tableNameRaw, {
|
|
305
|
+
sealedFields: ["headers", "body"],
|
|
306
|
+
aad: aadOn,
|
|
307
|
+
rowIdField: "k",
|
|
308
|
+
schemaVersion: "1",
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// CRYPTO-4 — derive a per-vault HMAC secret for fingerprint sealing.
|
|
313
|
+
// The vault root key is the trust root; without it the secret is
|
|
314
|
+
// unrecoverable. Lazy: only derived when fpSealOn is enabled AND the
|
|
315
|
+
// vault is ready, so test fixtures that haven't initialized the
|
|
316
|
+
// vault still construct a dbStore (the fingerprint then falls back
|
|
317
|
+
// to bare sha3-256 with a single audit warning).
|
|
318
|
+
var fpHmacSecret = null;
|
|
319
|
+
if (fpSealOn) {
|
|
320
|
+
try {
|
|
321
|
+
// Use vault.aad.buildContextAad as a stable derivation input;
|
|
322
|
+
// the derivedHashSalt is per-deployment so the same dbStore
|
|
323
|
+
// instance across hosts converges on the same HMAC key.
|
|
324
|
+
var fpDeriveInput = "idempotency.fingerprint:" + tableNameRaw + ":" +
|
|
325
|
+
vault.getDerivedHashSalt().toString("hex");
|
|
326
|
+
fpHmacSecret = bCrypto.kdf(Buffer.from(fpDeriveInput, "utf8"), C.BYTES.bytes(32));
|
|
327
|
+
} catch (_fpErr) {
|
|
328
|
+
_emitAudit("idempotency.fingerprint_seal_skipped_no_vault",
|
|
329
|
+
{ tableName: tableNameRaw,
|
|
330
|
+
reason: "vault.getDerivedHashSalt() unavailable; fingerprint falls back to plain sha3-256" },
|
|
331
|
+
"warning");
|
|
332
|
+
fpHmacSecret = null;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (doInit) {
|
|
337
|
+
db.prepare("CREATE TABLE IF NOT EXISTS " + qTable + " (" +
|
|
338
|
+
"k TEXT PRIMARY KEY, " +
|
|
339
|
+
"fingerprint TEXT NOT NULL, " +
|
|
340
|
+
"status_code INTEGER NOT NULL, " +
|
|
341
|
+
"headers TEXT NOT NULL, " +
|
|
342
|
+
"body TEXT NOT NULL, " +
|
|
343
|
+
"expires_at INTEGER NOT NULL)").run();
|
|
344
|
+
db.prepare("CREATE INDEX IF NOT EXISTS " + qIndex + " ON " +
|
|
345
|
+
qTable + "(expires_at)").run();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Prepared statements. status_code + expires_at stay non-sealed
|
|
349
|
+
// so audit/forensic SELECTs don't have to unseal-everything. The
|
|
350
|
+
// `k` column is selected even when not strictly needed for read
|
|
351
|
+
// because cryptoField.unsealRow uses it as the rowId in AAD when
|
|
352
|
+
// the table is AAD-bound (CRYPTO-1).
|
|
353
|
+
var stmtGet = db.prepare(
|
|
354
|
+
"SELECT k, fingerprint, status_code, headers, body, expires_at FROM " +
|
|
355
|
+
qTable + " WHERE k = ?");
|
|
356
|
+
var stmtUpsert = db.prepare(
|
|
357
|
+
"INSERT INTO " + qTable +
|
|
358
|
+
"(k, fingerprint, status_code, headers, body, expires_at) " +
|
|
359
|
+
"VALUES (?, ?, ?, ?, ?, ?) " +
|
|
360
|
+
"ON CONFLICT(k) DO UPDATE SET " +
|
|
361
|
+
" fingerprint = excluded.fingerprint, " +
|
|
362
|
+
" status_code = excluded.status_code, " +
|
|
363
|
+
" headers = excluded.headers, " +
|
|
364
|
+
" body = excluded.body, " +
|
|
365
|
+
" expires_at = excluded.expires_at");
|
|
366
|
+
var stmtDeleteStale = db.prepare("DELETE FROM " + qTable +
|
|
367
|
+
" WHERE k = ? AND expires_at <= ?");
|
|
368
|
+
var stmtDelete = db.prepare("DELETE FROM " + qTable + " WHERE k = ?");
|
|
369
|
+
|
|
370
|
+
function _k(rawKey) {
|
|
371
|
+
if (!hashKeys) return rawKey;
|
|
372
|
+
return bCrypto.namespaceHash("idempotency-key", rawKey);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// CRYPTO-4 — emit / compare HMAC-shape fingerprints. The store
|
|
376
|
+
// round-trips the column as plain text (no transformation per-get);
|
|
377
|
+
// sealing happens at MINT time (when the middleware builds the
|
|
378
|
+
// fingerprint and hands it to set()). The store's responsibility is
|
|
379
|
+
// pass-through. The middleware's `_fingerprintRequest` consults
|
|
380
|
+
// `store.fingerprintMode` to know whether to HMAC.
|
|
381
|
+
|
|
382
|
+
return {
|
|
383
|
+
get: function (rawKey) {
|
|
384
|
+
var row = stmtGet.get(_k(rawKey));
|
|
385
|
+
if (!row) return null;
|
|
386
|
+
if (row.expires_at < Date.now()) {
|
|
387
|
+
stmtDeleteStale.run(_k(rawKey), row.expires_at);
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
var liveRow = row;
|
|
391
|
+
if (sealEnabled) {
|
|
392
|
+
try { liveRow = cryptoField.unsealRow(tableNameRaw, row); }
|
|
393
|
+
catch (_unsealErr) {
|
|
394
|
+
// CRYPTO-13 — decryption failure used to delete the row,
|
|
395
|
+
// which let an attacker probe key presence via a "tamper +
|
|
396
|
+
// observe subsequent SELECT" oracle. The fix: emit audit,
|
|
397
|
+
// return null, do NOT delete. TTL sweeps stale rows out
|
|
398
|
+
// bounded by ttlMs; an out-of-band sweeper handles the
|
|
399
|
+
// corrupt-but-not-yet-expired case.
|
|
400
|
+
_emitAudit("idempotency.unseal_failed",
|
|
401
|
+
{ tableName: tableNameRaw,
|
|
402
|
+
keyHash: _hashKey(rawKey),
|
|
403
|
+
reason: String(_unsealErr && _unsealErr.message || _unsealErr) },
|
|
404
|
+
"warning");
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
var headersObj;
|
|
409
|
+
try {
|
|
410
|
+
// CRYPTO-22 — route through C.BYTES.mib(4); raw `4 * 1024 * 1024`
|
|
411
|
+
// was a drift smell flagged by codebase-patterns. 4 MiB ceiling
|
|
412
|
+
// unchanged.
|
|
413
|
+
headersObj = safeJson.parse(liveRow.headers, { maxBytes: C.BYTES.mib(4) });
|
|
414
|
+
} catch (_jsonErr) {
|
|
415
|
+
// Parse failure has two distinct causes:
|
|
416
|
+
// 1. Genuine corruption (truncated row, encoding mishap) — drop.
|
|
417
|
+
// 2. The row was sealed by a sibling process (vault: prefix
|
|
418
|
+
// present) but THIS process has sealEnabled=false (vault
|
|
419
|
+
// not initialized OR opts.seal=false). The row is valid
|
|
420
|
+
// cross-process state we just can't read locally;
|
|
421
|
+
// DELETING it would clobber another process's cache and
|
|
422
|
+
// turn a hit into a miss with potential side-effect re-
|
|
423
|
+
// execution. Treat as miss + LEAVE the row in place.
|
|
424
|
+
// Per Codex P1 on PR #45.
|
|
425
|
+
var lookedSealed = typeof liveRow.headers === "string" &&
|
|
426
|
+
(liveRow.headers.indexOf("vault:") === 0 ||
|
|
427
|
+
liveRow.headers.indexOf("vault.aad:") === 0);
|
|
428
|
+
if (!lookedSealed) {
|
|
429
|
+
stmtDeleteStale.run(_k(rawKey), row.expires_at);
|
|
430
|
+
}
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
fingerprint: liveRow.fingerprint,
|
|
435
|
+
statusCode: liveRow.status_code,
|
|
436
|
+
headers: headersObj,
|
|
437
|
+
body: liveRow.body,
|
|
438
|
+
};
|
|
439
|
+
},
|
|
440
|
+
set: function (rawKey, value, ttlMs) {
|
|
441
|
+
var rowOut = {
|
|
442
|
+
k: _k(rawKey),
|
|
443
|
+
fingerprint: value.fingerprint,
|
|
444
|
+
status_code: value.statusCode,
|
|
445
|
+
headers: JSON.stringify(value.headers || {}),
|
|
446
|
+
body: value.body || "",
|
|
447
|
+
expires_at: Date.now() + ttlMs,
|
|
448
|
+
};
|
|
449
|
+
if (sealEnabled) {
|
|
450
|
+
rowOut = cryptoField.sealRow(tableNameRaw, rowOut);
|
|
451
|
+
}
|
|
452
|
+
stmtUpsert.run(
|
|
453
|
+
rowOut.k, rowOut.fingerprint, rowOut.status_code,
|
|
454
|
+
rowOut.headers, rowOut.body, rowOut.expires_at);
|
|
455
|
+
},
|
|
456
|
+
delete: function (rawKey) {
|
|
457
|
+
stmtDelete.run(_k(rawKey));
|
|
458
|
+
},
|
|
459
|
+
// CRYPTO-4 — the middleware consults this hook to HMAC the
|
|
460
|
+
// method+path+body digest under a vault-derived secret before
|
|
461
|
+
// insert + compare. Returns null when fpSeal is disabled OR the
|
|
462
|
+
// vault wasn't ready at construction; the middleware then falls
|
|
463
|
+
// back to bare sha3-256.
|
|
464
|
+
fingerprintHmac: function (preimageBytes) {
|
|
465
|
+
if (!fpSealOn || !fpHmacSecret) return null;
|
|
466
|
+
return nodeCrypto.createHmac("sha3-256", fpHmacSecret)
|
|
467
|
+
.update(preimageBytes).digest("hex");
|
|
468
|
+
},
|
|
469
|
+
// CRYPTO-1 — operator helper: walk the table and reseal every row
|
|
470
|
+
// under the AAD form. Existing v0.9.15-v0.9.57 rows continue to
|
|
471
|
+
// read on a per-row basis (unsealRow auto-detects shape), but
|
|
472
|
+
// operators wanting an explicit migration step call this once.
|
|
473
|
+
// Idempotent; rows already AAD-sealed pass through unchanged.
|
|
474
|
+
resealMigrate: function () {
|
|
475
|
+
if (!sealEnabled || !aadOn) {
|
|
476
|
+
return { migrated: 0, skipped: 0, reason: "aad-or-seal-disabled" };
|
|
477
|
+
}
|
|
478
|
+
var migrated = 0;
|
|
479
|
+
var skipped = 0;
|
|
480
|
+
var rows = db.prepare("SELECT k, fingerprint, status_code, headers, body, expires_at FROM " +
|
|
481
|
+
qTable).all();
|
|
482
|
+
for (var i = 0; i < rows.length; i += 1) {
|
|
483
|
+
var r = rows[i];
|
|
484
|
+
// If headers/body already start with vault.aad: this row is
|
|
485
|
+
// already migrated.
|
|
486
|
+
var alreadyAad = typeof r.headers === "string" &&
|
|
487
|
+
r.headers.indexOf("vault.aad:") === 0 &&
|
|
488
|
+
typeof r.body === "string" &&
|
|
489
|
+
r.body.indexOf("vault.aad:") === 0;
|
|
490
|
+
if (alreadyAad) { skipped += 1; continue; }
|
|
491
|
+
var unsealed;
|
|
492
|
+
try { unsealed = cryptoField.unsealRow(tableNameRaw, r); }
|
|
493
|
+
catch (_e) { skipped += 1; continue; }
|
|
494
|
+
var resealed = cryptoField.sealRow(tableNameRaw, unsealed);
|
|
495
|
+
stmtUpsert.run(
|
|
496
|
+
resealed.k, resealed.fingerprint, resealed.status_code,
|
|
497
|
+
resealed.headers, resealed.body, resealed.expires_at);
|
|
498
|
+
migrated += 1;
|
|
499
|
+
}
|
|
500
|
+
_emitAudit("idempotency.reseal_migrate_complete",
|
|
501
|
+
{ tableName: tableNameRaw, migrated: migrated, skipped: skipped });
|
|
502
|
+
return { migrated: migrated, skipped: skipped, reason: null };
|
|
503
|
+
},
|
|
504
|
+
_tableName: tableNameRaw,
|
|
505
|
+
_hashKeys: hashKeys,
|
|
506
|
+
_sealEnabled: sealEnabled,
|
|
507
|
+
_aadOn: aadOn,
|
|
508
|
+
_fpSealOn: fpSealOn && fpHmacSecret !== null,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function _validateStore(store, where) {
|
|
513
|
+
if (!store || typeof store !== "object") {
|
|
514
|
+
throw new IdempotencyError("idempotency/bad-store",
|
|
515
|
+
where + ": store must be an object", true);
|
|
516
|
+
}
|
|
517
|
+
if (typeof store.get !== "function" ||
|
|
518
|
+
typeof store.set !== "function" ||
|
|
519
|
+
typeof store.delete !== "function") {
|
|
520
|
+
throw new IdempotencyError("idempotency/bad-store",
|
|
521
|
+
where + ": store must implement { get, set, delete }", true);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function _fingerprintRequest(req, bodyBytes, store) {
|
|
526
|
+
// Fingerprint preimage = method + path + body. Per the draft §4.3,
|
|
527
|
+
// a key+body mismatch is a client-side mistake; our preimage covers
|
|
528
|
+
// method + path so a client reusing a key across different
|
|
529
|
+
// endpoints is also caught. CRYPTO-4: when the store exposes a
|
|
530
|
+
// `fingerprintHmac` hook (dbStore with fingerprintSeal:true + vault
|
|
531
|
+
// ready), the preimage is HMAC'd under a vault-derived secret so a
|
|
532
|
+
// DB dump leaks neither the preimage nor a brute-forceable digest.
|
|
533
|
+
// The middleware then compares the HMAC'd column directly; both
|
|
534
|
+
// sides of the compare use the same secret so the equality is
|
|
535
|
+
// exact, no key-recovery is performed on the dump side.
|
|
536
|
+
var preimage = Buffer.concat([
|
|
537
|
+
Buffer.from((req.method || "GET") + "\n", "utf8"),
|
|
538
|
+
Buffer.from((req.url || "/") + "\n", "utf8"),
|
|
539
|
+
bodyBytes && bodyBytes.length > 0 ? bodyBytes : Buffer.alloc(0),
|
|
540
|
+
]);
|
|
541
|
+
if (store && typeof store.fingerprintHmac === "function") {
|
|
542
|
+
var hmacOut = store.fingerprintHmac(preimage);
|
|
543
|
+
if (hmacOut !== null) return hmacOut;
|
|
544
|
+
}
|
|
545
|
+
return nodeCrypto.createHash("sha3-256").update(preimage).digest("hex");
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function _emitAudit(action, metadata, outcome) {
|
|
549
|
+
try {
|
|
550
|
+
audit().safeEmit({
|
|
551
|
+
action: action,
|
|
552
|
+
outcome: outcome || "success",
|
|
553
|
+
metadata: metadata,
|
|
554
|
+
});
|
|
555
|
+
} catch (_e) { /* best-effort */ }
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* @primitive b.middleware.idempotencyKey
|
|
560
|
+
* @signature b.middleware.idempotencyKey(opts)
|
|
561
|
+
* @since 0.8.84
|
|
562
|
+
* @status stable
|
|
563
|
+
* @related b.middleware.idempotencyKey.memoryStore, b.problemDetails
|
|
564
|
+
*
|
|
565
|
+
* Build the Idempotency-Key middleware. Returns a connect-style
|
|
566
|
+
* `(req, res, next) => void` handler.
|
|
567
|
+
*
|
|
568
|
+
* - When `req.method` is not in `opts.methods` (default POST / PUT /
|
|
569
|
+
* PATCH / DELETE), the middleware is a pass-through.
|
|
570
|
+
* - When the request lacks an `Idempotency-Key` header and
|
|
571
|
+
* `opts.requireIdempotencyKey === true`, refuses with HTTP 400 +
|
|
572
|
+
* `application/problem+json` body
|
|
573
|
+
* `idempotency/missing-key`.
|
|
574
|
+
* - When the key is present but malformed (control chars, length
|
|
575
|
+
* out of range), refuses with HTTP 400 +
|
|
576
|
+
* `idempotency/bad-key`.
|
|
577
|
+
* - When the store has a hit AND the cached fingerprint matches the
|
|
578
|
+
* inbound request fingerprint, replays the cached
|
|
579
|
+
* `{ statusCode, headers, body }` and DOES NOT call `next()`.
|
|
580
|
+
* - When the store has a hit AND the fingerprint differs, refuses
|
|
581
|
+
* with HTTP 422 + `idempotency/key-reuse-mismatch`.
|
|
582
|
+
* - On a miss, wraps `res.end` to capture the handler's response
|
|
583
|
+
* and persist `{ fingerprint, statusCode, headers, body }` to
|
|
584
|
+
* the store with `ttlMs` (default 24h) after the handler
|
|
585
|
+
* finishes. The wrapper does NOT capture 5xx server-error
|
|
586
|
+
* responses — replaying a transient infrastructure failure is
|
|
587
|
+
* not idempotent.
|
|
588
|
+
*
|
|
589
|
+
* Per the draft §4.4, a concurrent-retry from the same client (two
|
|
590
|
+
* requests with the same key arriving in quick succession before
|
|
591
|
+
* the first has written to the store) is allowed to handler-execute
|
|
592
|
+
* twice and either response is acceptable; the framework does not
|
|
593
|
+
* lock the key. Operators wanting strict at-most-once execution
|
|
594
|
+
* implement a distributed-lock layer in their store's `set()`
|
|
595
|
+
* method (the interface is opaque to the middleware).
|
|
596
|
+
*
|
|
597
|
+
* @opts
|
|
598
|
+
* store: object, // required — get/set/delete interface
|
|
599
|
+
* ttlMs: number, // default: 24h
|
|
600
|
+
* methods: string[], // default: ["POST","PUT","PATCH","DELETE"]
|
|
601
|
+
* headerName: string, // default: "idempotency-key"
|
|
602
|
+
* requireIdempotencyKey: boolean, // default: false — refuse missing-key
|
|
603
|
+
* bodyFingerprint: function, // (req) => Buffer|string|object|null — operator-supplied body extractor
|
|
604
|
+
* maxBodyBytes: number, // default: 1 MiB — replay-cache body cap
|
|
605
|
+
* bodyFingerprintFallback: string, // default "deny" (SUBSTRATE-13) — when neither
|
|
606
|
+
* // bodyFingerprint nor req._rawBody / req.body is
|
|
607
|
+
* // available for POST/PUT/PATCH, refuse with HTTP 400
|
|
608
|
+
* // idempotency/missing-body-fingerprint instead of
|
|
609
|
+
* // silently degrading the fingerprint to method+path.
|
|
610
|
+
* // Set to "method-path-only" to restore the pre-0.9.58
|
|
611
|
+
* // behavior (the audit chain still logs
|
|
612
|
+
* // idempotency.empty_body_fingerprint so the
|
|
613
|
+
* // misorder is visible in operator review).
|
|
614
|
+
*
|
|
615
|
+
* **Mount order — idempotency MUST run AFTER body-parser.** The hook
|
|
616
|
+
* (and the default `req._rawBody||req.body` lookup) reads request
|
|
617
|
+
* state at the moment the idempotency middleware runs; if it runs
|
|
618
|
+
* before body-parser, `req.body` is still unset and the fingerprint
|
|
619
|
+
* silently degrades to method+path only — which fails the §4.3
|
|
620
|
+
* "same key, different body" guarantee. `b.middleware.composePipeline`
|
|
621
|
+
* places bodyParser=20 / idempotency=30 by default so the canonical
|
|
622
|
+
* order is correct; operators wiring middleware manually must mount
|
|
623
|
+
* idempotency AFTER bodyParser. The runtime emits
|
|
624
|
+
* `idempotency.empty_body_fingerprint` audit (warning) whenever a
|
|
625
|
+
* body-bearing request reaches the middleware with no body data,
|
|
626
|
+
* so the misordering is detectable from audit logs.
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
* var store = b.middleware.idempotencyKey.memoryStore({ maxEntries: 10000 });
|
|
630
|
+
* var mw = b.middleware.idempotencyKey({
|
|
631
|
+
* store: store,
|
|
632
|
+
* ttlMs: C.TIME.hours(24),
|
|
633
|
+
* methods: ["POST", "PUT", "PATCH"],
|
|
634
|
+
* // Optional: provide a body-fingerprint extractor that pulls
|
|
635
|
+
* // from the parsed body shape. The extractor only runs against
|
|
636
|
+
* // state populated by upstream middleware; mount idempotency
|
|
637
|
+
* // AFTER bodyParser (composePipeline does this by default).
|
|
638
|
+
* bodyFingerprint: function (req) { return req.body || null; },
|
|
639
|
+
* });
|
|
640
|
+
* app.use(mw);
|
|
641
|
+
*/
|
|
642
|
+
function create(opts) {
|
|
643
|
+
if (!opts || typeof opts !== "object") {
|
|
644
|
+
throw new IdempotencyError("idempotency/bad-opts",
|
|
645
|
+
"idempotencyKey: opts must be a non-null object", true);
|
|
646
|
+
}
|
|
647
|
+
_validateStore(opts.store, "idempotencyKey");
|
|
648
|
+
numericBounds.requirePositiveFiniteIntIfPresent(
|
|
649
|
+
opts.ttlMs, "idempotencyKey.ttlMs", IdempotencyError, "idempotency/bad-ttl");
|
|
650
|
+
var ttlMs = opts.ttlMs !== undefined ? opts.ttlMs : C.TIME.hours(24);
|
|
651
|
+
var methods = Array.isArray(opts.methods) && opts.methods.length > 0
|
|
652
|
+
? opts.methods.map(function (m) { return String(m).toUpperCase(); })
|
|
653
|
+
: DEFAULT_METHODS.slice();
|
|
654
|
+
var headerName = typeof opts.headerName === "string" && opts.headerName.length > 0
|
|
655
|
+
? opts.headerName.toLowerCase()
|
|
656
|
+
: "idempotency-key";
|
|
657
|
+
var requireKey = opts.requireIdempotencyKey === true;
|
|
658
|
+
// Operator-supplied body-fingerprint extractor. When provided,
|
|
659
|
+
// the middleware calls this instead of the inline
|
|
660
|
+
// `req._rawBody || req.body` lookup. Lets operators mount
|
|
661
|
+
// body-parser BEFORE the idempotency middleware and surface the
|
|
662
|
+
// parsed body shape (req.body is the typical post-parser
|
|
663
|
+
// attachment point); the inline lookup runs BEFORE body-parser
|
|
664
|
+
// by default, so the fingerprint silently degrades to
|
|
665
|
+
// method+path-only when body-parser mounts after. With this
|
|
666
|
+
// hook the middleware reads the body shape the operator
|
|
667
|
+
// canonically attached, regardless of mount order.
|
|
668
|
+
var bodyFingerprintFn = validateOpts.optionalFunction(
|
|
669
|
+
opts.bodyFingerprint, "idempotencyKey.bodyFingerprint",
|
|
670
|
+
IdempotencyError, "idempotency/bad-body-fingerprint"
|
|
671
|
+
) || null;
|
|
672
|
+
// SUBSTRATE-13 — default "deny" refuses body-bearing requests that
|
|
673
|
+
// arrive with neither req._rawBody / req.body NOR an operator-
|
|
674
|
+
// supplied bodyFingerprint hook. The silent-degrade-to-method+path
|
|
675
|
+
// path was a §4.3 violation (same key + different body returned
|
|
676
|
+
// false replays); the runtime now refuses with HTTP 400 instead.
|
|
677
|
+
// Operators with a documented "method-path-only" use case opt in.
|
|
678
|
+
var bodyFpFallback = "deny";
|
|
679
|
+
if (opts.bodyFingerprintFallback !== undefined) {
|
|
680
|
+
if (opts.bodyFingerprintFallback !== "deny" &&
|
|
681
|
+
opts.bodyFingerprintFallback !== "method-path-only") {
|
|
682
|
+
throw new IdempotencyError("idempotency/bad-body-fingerprint-fallback",
|
|
683
|
+
"idempotencyKey: opts.bodyFingerprintFallback must be \"deny\" or \"method-path-only\", got " +
|
|
684
|
+
JSON.stringify(opts.bodyFingerprintFallback), true);
|
|
685
|
+
}
|
|
686
|
+
bodyFpFallback = opts.bodyFingerprintFallback;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// Per-response collector cap. Idempotency replay only makes sense
|
|
690
|
+
// for response bodies that fit in memory; the cap is operator-
|
|
691
|
+
// tunable via opts.maxBodyBytes (default 1 MiB).
|
|
692
|
+
numericBounds.requirePositiveFiniteIntIfPresent(
|
|
693
|
+
opts.maxBodyBytes, "idempotencyKey.maxBodyBytes", IdempotencyError, "idempotency/bad-max-body");
|
|
694
|
+
var maxBodyBytes = opts.maxBodyBytes !== undefined ? opts.maxBodyBytes : C.BYTES.mib(1);
|
|
695
|
+
|
|
696
|
+
return function idempotencyMiddleware(req, res, next) {
|
|
697
|
+
var method = (req.method || "GET").toUpperCase();
|
|
698
|
+
if (methods.indexOf(method) === -1) return next();
|
|
699
|
+
|
|
700
|
+
var key = req.headers && req.headers[headerName];
|
|
701
|
+
if (Array.isArray(key)) key = key[0];
|
|
702
|
+
|
|
703
|
+
if (!key || typeof key !== "string" || key.length === 0) {
|
|
704
|
+
if (!requireKey) return next();
|
|
705
|
+
var missing = problemDetails().create({
|
|
706
|
+
type: problemDetails().getBase() + "/idempotency/missing-key",
|
|
707
|
+
title: "Idempotency-Key header required",
|
|
708
|
+
status: 400, // allow:raw-byte-literal — HTTP status 400 Bad Request
|
|
709
|
+
detail: "This endpoint requires an Idempotency-Key header (draft-ietf-httpapi-idempotency-key).",
|
|
710
|
+
});
|
|
711
|
+
_emitAudit("idempotency.missing_key", { method: method, path: req.url }, "denied");
|
|
712
|
+
return problemDetails().respond(res, missing);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
if (key.length > KEY_MAX_LEN || !KEY_RE.test(key)) {
|
|
716
|
+
var bad = problemDetails().create({
|
|
717
|
+
type: problemDetails().getBase() + "/idempotency/bad-key",
|
|
718
|
+
title: "Idempotency-Key malformed",
|
|
719
|
+
status: 400, // allow:raw-byte-literal — HTTP status 400
|
|
720
|
+
detail: "Idempotency-Key must be ASCII printable, length 1.." + KEY_MAX_LEN + " (draft §2).",
|
|
721
|
+
});
|
|
722
|
+
_emitAudit("idempotency.bad_key", { method: method, keyLen: key.length }, "denied");
|
|
723
|
+
return problemDetails().respond(res, bad);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
var bodyBytes;
|
|
727
|
+
if (bodyFingerprintFn) {
|
|
728
|
+
// Operator-supplied hook — called after body-parser so req.body
|
|
729
|
+
// is populated. Hook returns Buffer / string / null.
|
|
730
|
+
try {
|
|
731
|
+
var fpVal = bodyFingerprintFn(req);
|
|
732
|
+
if (fpVal === null || fpVal === undefined) {
|
|
733
|
+
bodyBytes = null;
|
|
734
|
+
} else if (Buffer.isBuffer(fpVal)) {
|
|
735
|
+
bodyBytes = fpVal;
|
|
736
|
+
} else if (typeof fpVal === "string") {
|
|
737
|
+
bodyBytes = Buffer.from(fpVal, "utf8");
|
|
738
|
+
} else {
|
|
739
|
+
// Object / array — JSON-stringify so the hash is stable.
|
|
740
|
+
bodyBytes = Buffer.from(JSON.stringify(fpVal), "utf8");
|
|
741
|
+
}
|
|
742
|
+
} catch (e) {
|
|
743
|
+
_emitAudit("idempotency.body_fingerprint_failed",
|
|
744
|
+
{ error: String(e && e.message || e) }, "warning");
|
|
745
|
+
bodyBytes = null;
|
|
746
|
+
}
|
|
747
|
+
} else {
|
|
748
|
+
bodyBytes = req._rawBody || req.body || null;
|
|
749
|
+
if (bodyBytes && typeof bodyBytes === "object" && !Buffer.isBuffer(bodyBytes)) {
|
|
750
|
+
// Buffer-ize a non-buffer body (already-parsed JSON, etc.) so the
|
|
751
|
+
// hash is stable. JSON.stringify with sorted keys would be more
|
|
752
|
+
// robust but the operator-attached body shape is whatever the
|
|
753
|
+
// upstream parser produced; canonicalization is operator-side.
|
|
754
|
+
try {
|
|
755
|
+
bodyBytes = Buffer.from(JSON.stringify(bodyBytes), "utf8");
|
|
756
|
+
} catch (_e) {
|
|
757
|
+
bodyBytes = null;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Misordered-mount detector — body-bearing method reached us
|
|
763
|
+
// with neither a parsed body nor a raw-body buffer. Most likely
|
|
764
|
+
// body-parser hasn't run yet, which used to silently degrade the
|
|
765
|
+
// fingerprint to method+path; SUBSTRATE-13 (v0.9.58) makes that
|
|
766
|
+
// case refuse with HTTP 400 by default. The audit emit fires in
|
|
767
|
+
// both fallback modes so operator review surfaces the
|
|
768
|
+
// misconfiguration regardless of the chosen fallback.
|
|
769
|
+
if (!bodyBytes && (method === "POST" || method === "PUT" || method === "PATCH")) {
|
|
770
|
+
_emitAudit("idempotency.empty_body_fingerprint",
|
|
771
|
+
{
|
|
772
|
+
method: method,
|
|
773
|
+
path: req.url,
|
|
774
|
+
hasRawBody: Boolean(req._rawBody),
|
|
775
|
+
hasParsedBody: req.body !== undefined && req.body !== null,
|
|
776
|
+
hasFingerprintHook: Boolean(bodyFingerprintFn),
|
|
777
|
+
fallback: bodyFpFallback,
|
|
778
|
+
},
|
|
779
|
+
bodyFpFallback === "deny" ? "denied" : "warning");
|
|
780
|
+
if (bodyFpFallback === "deny") {
|
|
781
|
+
var missingBody = problemDetails().create({
|
|
782
|
+
type: problemDetails().getBase() + "/idempotency/missing-body-fingerprint",
|
|
783
|
+
title: "Idempotency body fingerprint unavailable",
|
|
784
|
+
status: 400, // allow:raw-byte-literal — HTTP status 400 Bad Request
|
|
785
|
+
detail: "The idempotency middleware could not derive a body fingerprint for this " +
|
|
786
|
+
"request. Mount body-parser BEFORE the idempotency middleware, OR provide an " +
|
|
787
|
+
"opts.bodyFingerprint(req) hook. To restore the pre-0.9.58 method+path-only " +
|
|
788
|
+
"behavior, set opts.bodyFingerprintFallback=\"method-path-only\".",
|
|
789
|
+
});
|
|
790
|
+
return problemDetails().respond(res, missingBody);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
var fingerprint = _fingerprintRequest(req, bodyBytes, opts.store);
|
|
795
|
+
|
|
796
|
+
var cached = null;
|
|
797
|
+
try { cached = opts.store.get(key); }
|
|
798
|
+
catch (_storeErr) {
|
|
799
|
+
// Store-read failure — emit audit + treat as miss. Idempotency is
|
|
800
|
+
// a best-effort optimization; the handler runs anyway.
|
|
801
|
+
_emitAudit("idempotency.store_read_failed",
|
|
802
|
+
{ key: _redactKey(key), error: String(_storeErr.message || _storeErr) }, "warning");
|
|
803
|
+
cached = null;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
if (cached) {
|
|
807
|
+
if (cached.fingerprint !== fingerprint) {
|
|
808
|
+
// §4.3 — same key, different request body. Client mistake.
|
|
809
|
+
var mismatch = problemDetails().create({
|
|
810
|
+
type: problemDetails().getBase() + "/idempotency/key-reuse-mismatch",
|
|
811
|
+
title: "Idempotency-Key reused with different request",
|
|
812
|
+
status: 422, // allow:raw-byte-literal — HTTP status 422 Unprocessable Content (RFC 9110)
|
|
813
|
+
detail: "The Idempotency-Key matches a prior request but the request body/method/path differs (draft §4.3).",
|
|
814
|
+
});
|
|
815
|
+
_emitAudit("idempotency.key_reuse_mismatch",
|
|
816
|
+
{ method: method, path: req.url, keyHash: _hashKey(key) }, "denied");
|
|
817
|
+
return problemDetails().respond(res, mismatch);
|
|
818
|
+
}
|
|
819
|
+
// Replay. The cached body is a base64 string of the original
|
|
820
|
+
// bytes; restore Buffer + write through the response.
|
|
821
|
+
var rawBody;
|
|
822
|
+
try { rawBody = Buffer.from(cached.body || "", "base64"); }
|
|
823
|
+
catch (_decodeErr) { rawBody = Buffer.alloc(0); }
|
|
824
|
+
res.statusCode = cached.statusCode;
|
|
825
|
+
var headerKeys = Object.keys(cached.headers || {});
|
|
826
|
+
for (var i = 0; i < headerKeys.length; i += 1) {
|
|
827
|
+
try { res.setHeader(headerKeys[i], cached.headers[headerKeys[i]]); }
|
|
828
|
+
catch (_hdrErr) { /* operator-restricted header — skip */ }
|
|
829
|
+
}
|
|
830
|
+
_emitAudit("idempotency.replay",
|
|
831
|
+
{ method: method, path: req.url, statusCode: cached.statusCode, keyHash: _hashKey(key) });
|
|
832
|
+
res.end(rawBody);
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// Miss — capture the handler's response. The bounded collector
|
|
837
|
+
// refuses bodies > maxBodyBytes at push() time (operator can
|
|
838
|
+
// tune via opts.maxBodyBytes; default 1 MiB). When the cap is
|
|
839
|
+
// hit, we abandon the capture + emit audit + DO NOT cache;
|
|
840
|
+
// operators wanting larger replay windows raise the cap.
|
|
841
|
+
var origEnd = res.end.bind(res);
|
|
842
|
+
var origWrite = res.write.bind(res);
|
|
843
|
+
var collector = safeBuffer.boundedChunkCollector({
|
|
844
|
+
maxBytes: maxBodyBytes,
|
|
845
|
+
errorClass: IdempotencyError,
|
|
846
|
+
sizeCode: "idempotency/body-too-large",
|
|
847
|
+
sizeMessage: "idempotency: response body exceeded maxBodyBytes (cap=" + maxBodyBytes + "); not cached.",
|
|
848
|
+
});
|
|
849
|
+
var captured = false;
|
|
850
|
+
var oversized = false;
|
|
851
|
+
function _pushChunk(chunk, encoding) {
|
|
852
|
+
if (oversized || !chunk) return;
|
|
853
|
+
try { collector.push(_toBuffer(chunk, encoding)); }
|
|
854
|
+
catch (_capErr) {
|
|
855
|
+
oversized = true;
|
|
856
|
+
_emitAudit("idempotency.body_too_large",
|
|
857
|
+
{ method: method, path: req.url, cap: maxBodyBytes, keyHash: _hashKey(key) }, "warning");
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
res.write = function (chunk, encoding) {
|
|
861
|
+
_pushChunk(chunk, encoding);
|
|
862
|
+
return origWrite(chunk, encoding);
|
|
863
|
+
};
|
|
864
|
+
res.end = function (chunk, encoding) {
|
|
865
|
+
if (!captured) {
|
|
866
|
+
captured = true;
|
|
867
|
+
_pushChunk(chunk, encoding);
|
|
868
|
+
var status = res.statusCode || 200; // allow:raw-byte-literal — default HTTP status 200
|
|
869
|
+
// Only persist 2xx-4xx responses; 5xx is transient infra
|
|
870
|
+
// failure that should be retried fresh, not replayed.
|
|
871
|
+
if (!oversized && status >= 200 && status < 500) { // allow:raw-byte-literal — HTTP status class boundaries
|
|
872
|
+
var headerMap = {};
|
|
873
|
+
try {
|
|
874
|
+
var allHeaders = typeof res.getHeaders === "function" ? res.getHeaders() : {};
|
|
875
|
+
var hk = Object.keys(allHeaders);
|
|
876
|
+
for (var j = 0; j < hk.length; j += 1) {
|
|
877
|
+
if (hk[j] === "set-cookie") continue; // Set-Cookie is per-request and unsafe to replay
|
|
878
|
+
headerMap[hk[j]] = allHeaders[hk[j]];
|
|
879
|
+
}
|
|
880
|
+
} catch (_e) { /* ignore */ }
|
|
881
|
+
var combined = collector.result();
|
|
882
|
+
try {
|
|
883
|
+
opts.store.set(key, {
|
|
884
|
+
fingerprint: fingerprint,
|
|
885
|
+
statusCode: status,
|
|
886
|
+
headers: headerMap,
|
|
887
|
+
body: combined.toString("base64"),
|
|
888
|
+
}, ttlMs);
|
|
889
|
+
_emitAudit("idempotency.cache_store",
|
|
890
|
+
{ method: method, path: req.url, statusCode: status, keyHash: _hashKey(key), bodyBytes: combined.length });
|
|
891
|
+
} catch (storeErr) {
|
|
892
|
+
_emitAudit("idempotency.store_write_failed",
|
|
893
|
+
{ key: _redactKey(key), error: String(storeErr.message || storeErr) }, "warning");
|
|
894
|
+
}
|
|
895
|
+
} else if (!oversized) {
|
|
896
|
+
_emitAudit("idempotency.skip_5xx",
|
|
897
|
+
{ method: method, path: req.url, statusCode: status, keyHash: _hashKey(key) });
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
return origEnd(chunk, encoding);
|
|
901
|
+
};
|
|
902
|
+
next();
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
function _toBuffer(chunk, encoding) {
|
|
907
|
+
if (Buffer.isBuffer(chunk)) return chunk;
|
|
908
|
+
if (typeof chunk === "string") return Buffer.from(chunk, encoding || "utf8");
|
|
909
|
+
return Buffer.from(String(chunk));
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
function _hashKey(key) {
|
|
913
|
+
// Hash before logging — operator's audit chain shouldn't carry raw
|
|
914
|
+
// idempotency keys (clients sometimes inadvertently put PII / order
|
|
915
|
+
// numbers in them).
|
|
916
|
+
return nodeCrypto.createHash("sha3-256").update(key, "utf8").digest("hex").slice(0, 16); // allow:raw-byte-literal — log-truncation length, not bytes
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function _redactKey(key) {
|
|
920
|
+
if (typeof key !== "string") return "<non-string>";
|
|
921
|
+
if (key.length <= 8) return "<short:" + key.length + ">"; // allow:raw-byte-literal — log-redaction length threshold
|
|
922
|
+
return key.slice(0, 4) + "..." + key.slice(-2) + " (len=" + key.length + ")"; // allow:raw-byte-literal — log-redaction prefix/suffix lengths
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* @primitive b.middleware.idempotencyKey.resealMigrate
|
|
927
|
+
* @signature b.middleware.idempotencyKey.resealMigrate(store)
|
|
928
|
+
* @since 0.9.58
|
|
929
|
+
* @related b.middleware.idempotencyKey.dbStore
|
|
930
|
+
*
|
|
931
|
+
* One-shot operator helper that walks a dbStore's table and reseals
|
|
932
|
+
* every row under the AAD-bound envelope shape introduced in v0.9.58
|
|
933
|
+
* (CRYPTO-1). Existing v0.9.15-v0.9.57 rows continue to read on a
|
|
934
|
+
* per-row basis (unsealRow auto-detects shape) so a deploy without
|
|
935
|
+
* this call is correct, but operators who want to upgrade in bulk
|
|
936
|
+
* call this once after upgrading.
|
|
937
|
+
*
|
|
938
|
+
* Returns `{ migrated, skipped, reason }`. `migrated` counts rows
|
|
939
|
+
* rewritten with AAD-bound ciphertext; `skipped` counts rows already
|
|
940
|
+
* AAD-shaped or that failed unseal under the current key (those rows
|
|
941
|
+
* stay in place and surface via the standard
|
|
942
|
+
* `idempotency.unseal_failed` audit on next read). `reason` is null
|
|
943
|
+
* on success; populated when the store doesn't support migration
|
|
944
|
+
* (in-memory store, custom operator-supplied store, etc.).
|
|
945
|
+
*
|
|
946
|
+
* @example
|
|
947
|
+
* var store = b.middleware.idempotencyKey.dbStore({ db: myDb });
|
|
948
|
+
* var info = b.middleware.idempotencyKey.resealMigrate(store);
|
|
949
|
+
* logger.info("idempotency migration", info);
|
|
950
|
+
*/
|
|
951
|
+
function resealMigrate(store) {
|
|
952
|
+
if (!store || typeof store.resealMigrate !== "function") {
|
|
953
|
+
return { migrated: 0, skipped: 0, reason: "store-does-not-support-reseal" };
|
|
954
|
+
}
|
|
955
|
+
return store.resealMigrate();
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
module.exports = create;
|
|
959
|
+
module.exports.create = create;
|
|
960
|
+
module.exports.memoryStore = memoryStore;
|
|
961
|
+
module.exports.dbStore = dbStore;
|
|
962
|
+
module.exports.resealMigrate = resealMigrate;
|
|
963
|
+
module.exports.DEFAULT_METHODS = DEFAULT_METHODS;
|
|
964
|
+
module.exports.IdempotencyError = IdempotencyError;
|