@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,1162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.session
|
|
4
|
+
* @featured true
|
|
5
|
+
* @nav Data
|
|
6
|
+
* @title Session
|
|
7
|
+
*
|
|
8
|
+
* @intro
|
|
9
|
+
* Server-side session store with idle + absolute timeouts, encrypted
|
|
10
|
+
* at rest, sealed columns, audit on every login / logout, and
|
|
11
|
+
* cluster-aware leader gating.
|
|
12
|
+
*
|
|
13
|
+
* The session id (sid) is a 32-byte random value returned to the
|
|
14
|
+
* caller once and stored client-side (cookie / authorization header).
|
|
15
|
+
* The DB primary key is `sha3('bj-session:' || sid)` — the plaintext
|
|
16
|
+
* sid never lands in the database. DB exfiltration alone cannot
|
|
17
|
+
* impersonate a session: the attacker would also need the original
|
|
18
|
+
* sid the user holds. The `data` column is vault-sealed JSON;
|
|
19
|
+
* `userId` is sealed; `userIdHash` indexes for destroyAllForUser
|
|
20
|
+
* without unsealing every row.
|
|
21
|
+
*
|
|
22
|
+
* Idle + absolute timeout enforcement follows OWASP ASVS 5.0 §3.3
|
|
23
|
+
* and NIST SP 800-63B-4. Defaults: idle 30 minutes, absolute 12
|
|
24
|
+
* hours. Both shorten the effective lifetime even when the operator
|
|
25
|
+
* picked a long ttlMs; repeated `touch({ extendBy })` cannot push
|
|
26
|
+
* `expiresAt` past the absolute ceiling.
|
|
27
|
+
*
|
|
28
|
+
* Storage placement is mode-driven: single-node lives in the
|
|
29
|
+
* framework's main DB under `_blamejs_sessions` (baked into db.js's
|
|
30
|
+
* schema — apps cannot opt out); cluster mode lives in external-db
|
|
31
|
+
* under the same name. `clusterStorage.execute` routes by
|
|
32
|
+
* `cluster.isClusterMode()`; this module does not branch on mode.
|
|
33
|
+
*
|
|
34
|
+
* Cluster posture per blamejs-cluster-spec.md:
|
|
35
|
+
* `create` / `destroy` / `destroyAllForUser` / `touch` / `rotate` /
|
|
36
|
+
* `purgeExpired` are leader-only (gated by `cluster.requireLeader`
|
|
37
|
+
* at call entry); `verify` and `count` run anywhere.
|
|
38
|
+
*
|
|
39
|
+
* Optional fingerprint binding: pass `{ req, fingerprintFields }` to
|
|
40
|
+
* `create` and `verify` to bind a session to a stable hash of
|
|
41
|
+
* client-IP / user-agent / accept-language. Drift produces an audit
|
|
42
|
+
* event and surfaces as `fingerprintDrift: true`; strict operators
|
|
43
|
+
* pass `requireFingerprintMatch: true` (or a `maxAnomalyScore`
|
|
44
|
+
* threshold with a `scorer`) to refuse the session on drift.
|
|
45
|
+
*
|
|
46
|
+
* @card
|
|
47
|
+
* Server-side session store with idle + absolute timeouts, encrypted at rest, sealed columns, audit on every login / logout, and cluster-aware leader gating.
|
|
48
|
+
*/
|
|
49
|
+
var audit = require("./audit");
|
|
50
|
+
var canonicalJson = require("./canonical-json");
|
|
51
|
+
var cluster = require("./cluster");
|
|
52
|
+
var clusterStorage = require("./cluster-storage");
|
|
53
|
+
var C = require("./constants");
|
|
54
|
+
var { generateToken, sha3Hash } = require("./crypto");
|
|
55
|
+
var cryptoField = require("./crypto-field");
|
|
56
|
+
var lazyRequire = require("./lazy-require");
|
|
57
|
+
var requestHelpers = require("./request-helpers");
|
|
58
|
+
var safeJson = require("./safe-json");
|
|
59
|
+
var { SessionError } = require("./framework-error");
|
|
60
|
+
|
|
61
|
+
// vault is initialized at boot before sessions; lazyRequire keeps the
|
|
62
|
+
// load order independent of module-import order. Used to seal/unseal
|
|
63
|
+
// the cookie-side sid so the wire token is ciphertext rather than
|
|
64
|
+
// plaintext (sealed-cookie default since v0.8.61).
|
|
65
|
+
var vault = lazyRequire(function () { return require("./vault"); });
|
|
66
|
+
|
|
67
|
+
// Pluggable session-storage backend. Default uses cluster-storage (which
|
|
68
|
+
// in turn dispatches to the framework's main DB or external DB). An
|
|
69
|
+
// operator can switch to an isolated backend (e.g. an in-memory or
|
|
70
|
+
// tmpfs SQLite via `b.session.stores.localDbThin`) so heavy session
|
|
71
|
+
// churn doesn't fight the main DB's WAL fsync + at-rest re-encryption
|
|
72
|
+
// cycle. Set once at boot via `b.session.useStore(store)`; the store
|
|
73
|
+
// must expose `execute(sql, params)` and `executeOne(sql, params)`
|
|
74
|
+
// returning the same `{ rowCount, rows? }` / row-or-null shape the
|
|
75
|
+
// cluster-storage path returns.
|
|
76
|
+
var _store = null;
|
|
77
|
+
function _currentStore() { return _store || clusterStorage; }
|
|
78
|
+
|
|
79
|
+
var _err = SessionError.factory;
|
|
80
|
+
|
|
81
|
+
var DEFAULT_TTL_MS = C.TIME.days(7);
|
|
82
|
+
// Sanity bound: any session that lives longer than this is almost
|
|
83
|
+
// certainly a misconfigured Infinity / oversized literal. Keeps
|
|
84
|
+
// expiresAt away from epoch overflow + database-int boundary issues.
|
|
85
|
+
var MAX_TTL_MS = C.TIME.days(3650); // ~10 years
|
|
86
|
+
|
|
87
|
+
// Idle + absolute timeout defaults per OWASP ASVS 5.0 §3.3 + NIST
|
|
88
|
+
// SP 800-63B-4. expiresAt is the operator-set window; idle/absolute
|
|
89
|
+
// are independent enforcement floors that shorten the effective
|
|
90
|
+
// session lifetime even when the operator picked a long ttlMs.
|
|
91
|
+
//
|
|
92
|
+
// - idle: session expires N ms after the last verify() / touch().
|
|
93
|
+
// Default 30 minutes — short enough to defeat session-token
|
|
94
|
+
// theft via short-lived foothold; long enough that a user
|
|
95
|
+
// reading a long article doesn't get logged out.
|
|
96
|
+
// - absolute: session always expires at most N ms after creation,
|
|
97
|
+
// regardless of activity. Default 12 hours — re-auth at
|
|
98
|
+
// least once per shift even on a continuously-active
|
|
99
|
+
// session. Repeated touch() with extendBy cannot push past
|
|
100
|
+
// this ceiling.
|
|
101
|
+
var DEFAULT_IDLE_TIMEOUT_MS = C.TIME.minutes(30);
|
|
102
|
+
var DEFAULT_ABSOLUTE_TIMEOUT_MS = C.TIME.hours(12);
|
|
103
|
+
|
|
104
|
+
function _validateTtl(ttl, where) {
|
|
105
|
+
if (typeof ttl !== "number" || !isFinite(ttl) || ttl <= 0) {
|
|
106
|
+
throw _err("INVALID_ARG",
|
|
107
|
+
where + ": ttlMs must be a positive finite number, got " + JSON.stringify(ttl), true);
|
|
108
|
+
}
|
|
109
|
+
if (ttl > MAX_TTL_MS) {
|
|
110
|
+
throw _err("INVALID_ARG",
|
|
111
|
+
where + ": ttlMs " + ttl + " exceeds maximum " + MAX_TTL_MS + " (~10 years). " +
|
|
112
|
+
"Sessions this long suggest a misconfigured value.", true);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
var SID_NAMESPACE = "bj-session:";
|
|
116
|
+
// Session ID = 32 random bytes (64 hex chars) — 256-bit entropy floor
|
|
117
|
+
// keeps sids unforgeable even before sealed-cookie encryption layers on
|
|
118
|
+
// top. Routed through C.BYTES so every byte literal in the file lives
|
|
119
|
+
// behind the same helper.
|
|
120
|
+
var SID_BYTES = C.BYTES.bytes(32);
|
|
121
|
+
|
|
122
|
+
// Column order used for INSERT — kept as a constant so the placeholders
|
|
123
|
+
// list and the values list stay in sync. Must match _blamejs_sessions's
|
|
124
|
+
// schema in db.js (single-node) and framework-schema.js (cluster mode).
|
|
125
|
+
var SESSION_COLS = ["sidHash", "userId", "userIdHash", "data", "createdAt", "expiresAt", "lastActivity"];
|
|
126
|
+
|
|
127
|
+
function _hashSid(sid) {
|
|
128
|
+
return sha3Hash(SID_NAMESPACE + sid);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Sealed-cookie format. `b.vault.seal` produces a `vault:`-prefixed
|
|
132
|
+
// envelope (ML-KEM-1024 + P-384 hybrid + XChaCha20-Poly1305). Pre-
|
|
133
|
+
// v0.8.61 the framework returned the plaintext sid to the caller; the
|
|
134
|
+
// sealed default since v0.8.61 keeps the wire token as ciphertext. The
|
|
135
|
+
// DB still keys on `sha3('bj-session:' || sid)` — sealing is a
|
|
136
|
+
// wire-format upgrade, not a storage change.
|
|
137
|
+
//
|
|
138
|
+
// Pre-v1.0 the framework ships no backwards-compat path: raw-format
|
|
139
|
+
// cookies from before v0.8.61 fail to unseal here and the affected
|
|
140
|
+
// caller force-logs-out (re-auths and gets a sealed cookie). The
|
|
141
|
+
// upgrade is operator-visible and documented in the release notes.
|
|
142
|
+
var SEALED_COOKIE_PREFIX = "vault:";
|
|
143
|
+
|
|
144
|
+
function _sealCookieToken(sid) {
|
|
145
|
+
// vault.seal is idempotent on already-sealed input. Defensive null
|
|
146
|
+
// pass-through matches vault's contract — feed it the raw sid only.
|
|
147
|
+
return vault().seal(sid);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function _unsealCookieToken(token) {
|
|
151
|
+
if (typeof token !== "string" || token.length === 0) return null;
|
|
152
|
+
if (token.indexOf(SEALED_COOKIE_PREFIX) !== 0) {
|
|
153
|
+
// Pre-v0.8.61 raw-sid format — refused under the sealed-cookie
|
|
154
|
+
// default. Returning null surfaces as "session not found" at the
|
|
155
|
+
// verify call site so the caller force-logs-out cleanly.
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
try { return vault().unseal(token); }
|
|
159
|
+
catch (_e) {
|
|
160
|
+
// Tampered cookie / wrong keypair / vault rotation skew — treat as
|
|
161
|
+
// not-found. The caller already handles `null` (re-auth flow).
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Build a sealed row object with all SESSION_COLS keys present (null
|
|
167
|
+
// where not set). The cryptoField.sealRow call seals userId/data and
|
|
168
|
+
// produces userIdHash from userId.
|
|
169
|
+
function _sealForInsert(row) {
|
|
170
|
+
var sealed = cryptoField.sealRow("_blamejs_sessions", row);
|
|
171
|
+
for (var i = 0; i < SESSION_COLS.length; i++) {
|
|
172
|
+
if (!(SESSION_COLS[i] in sealed)) sealed[SESSION_COLS[i]] = null;
|
|
173
|
+
}
|
|
174
|
+
return sealed;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ---- Public API ----
|
|
178
|
+
|
|
179
|
+
// Build a stable fingerprint from a request's client-derived signals.
|
|
180
|
+
// Operators opt in via session.create({ req, fingerprintFields }) and
|
|
181
|
+
// session.verify({ req, ... }); when the fingerprint drifts (different
|
|
182
|
+
// IP / user-agent / accept-language), the verify result carries
|
|
183
|
+
// fingerprintDrift: true and an audit event fires. Operators in strict
|
|
184
|
+
// mode pass requireFingerprintMatch:true to make the drift kill the
|
|
185
|
+
// session; default returns the session (so a phone roaming between
|
|
186
|
+
// wifi and LTE doesn't get logged out, but the operator AND ops sees
|
|
187
|
+
// the drift signal).
|
|
188
|
+
//
|
|
189
|
+
// The fingerprint is HMAC'd with the session sid so a stolen DB can't
|
|
190
|
+
// be cross-correlated with public IP-UA logs to attribute sessions to
|
|
191
|
+
// users — same defense the sidHash already provides for the token
|
|
192
|
+
// itself, extended to the fingerprint.
|
|
193
|
+
var DEFAULT_FINGERPRINT_FIELDS = ["clientIp", "userAgent", "acceptLanguage"];
|
|
194
|
+
|
|
195
|
+
// Subnet binding: roaming carriers (T-Mobile / Verizon / etc.) flip the
|
|
196
|
+
// public client IP every few requests as the device hops cells, so a
|
|
197
|
+
// strict full-IP fingerprint logs out healthy mobile users. The
|
|
198
|
+
// "clientIpPrefix" field hashes a /24 mask for IPv4 (256-address bucket
|
|
199
|
+
// — same Class C-shaped neighborhood) and a /64 mask for IPv6 (the IPv6
|
|
200
|
+
// "site" prefix the RIRs allocate to every ISP customer). Drift across
|
|
201
|
+
// /24 OR /64 is meaningfully suspicious; drift within is not.
|
|
202
|
+
//
|
|
203
|
+
// Per the IPv6 addressing architecture (RFC 4291 §2.5.4) every customer
|
|
204
|
+
// LAN is assigned at least a /64; tightening below /64 punishes IPv6
|
|
205
|
+
// privacy-extension address rotation. /24 IPv4 is the original
|
|
206
|
+
// IP-geolocation bucket size and matches the legacy carrier-NAT pool
|
|
207
|
+
// stride. Operators with stricter needs pass a function-form
|
|
208
|
+
// fingerprint field for custom mask widths.
|
|
209
|
+
//
|
|
210
|
+
// Protocol constants — named so the bit-arithmetic stays readable.
|
|
211
|
+
var IP_BITS_PER_BYTE = 8; // allow:raw-byte-literal — bits per byte; protocol constant, not a byte size
|
|
212
|
+
var IPV4_OCTET_COUNT = 4;
|
|
213
|
+
var IPV4_OCTET_RANGE = 256; // allow:raw-byte-literal — 0..255 inclusive; v4 octet domain
|
|
214
|
+
var IPV4_TOTAL_BITS = 32; // allow:raw-byte-literal — IPv4 address width in bits
|
|
215
|
+
var IPV4_DEFAULT_PREFIX = 24; // allow:raw-byte-literal — /24 carrier-NAT pool stride
|
|
216
|
+
var IPV6_GROUP_COUNT = 8; // allow:raw-byte-literal — 8 16-bit groups in v6
|
|
217
|
+
var IPV6_BYTE_COUNT = 16; // allow:raw-byte-literal — 16 bytes in v6
|
|
218
|
+
var IPV6_DEFAULT_PREFIX = 64; // allow:raw-byte-literal — /64 customer LAN per RFC 4291 §2.5.4
|
|
219
|
+
var BYTE_MASK = 0xff;
|
|
220
|
+
var HEX_RADIX = 16; // allow:raw-byte-literal — base-16 radix
|
|
221
|
+
var V4_MAPPED_V6_PREFIX = "::ffff:";
|
|
222
|
+
|
|
223
|
+
function _maskIpv4(ip, prefix) {
|
|
224
|
+
// ip = "a.b.c.d"; prefix is bits to keep (1..32).
|
|
225
|
+
var parts = String(ip).split(".");
|
|
226
|
+
if (parts.length !== IPV4_OCTET_COUNT) return null;
|
|
227
|
+
var n = 0;
|
|
228
|
+
for (var i = 0; i < IPV4_OCTET_COUNT; i++) {
|
|
229
|
+
var oct = parseInt(parts[i], 10);
|
|
230
|
+
if (!Number.isInteger(oct) || oct < 0 || oct >= IPV4_OCTET_RANGE) return null;
|
|
231
|
+
n = (n * IPV4_OCTET_RANGE) + oct;
|
|
232
|
+
}
|
|
233
|
+
// Apply prefix mask.
|
|
234
|
+
var mask = prefix === 0 ? 0 : (-1 >>> (IPV4_TOTAL_BITS - prefix)) << (IPV4_TOTAL_BITS - prefix);
|
|
235
|
+
// Bitwise on 32-bit unsigned. JS coerces to 32-bit signed, so use
|
|
236
|
+
// unsigned right shift to recover.
|
|
237
|
+
var masked = (n & mask) >>> 0;
|
|
238
|
+
return ((masked >>> IP_BITS_PER_BYTE * 3) & BYTE_MASK) + "." +
|
|
239
|
+
((masked >>> IP_BITS_PER_BYTE * 2) & BYTE_MASK) + "." +
|
|
240
|
+
((masked >>> IP_BITS_PER_BYTE) & BYTE_MASK) + "." +
|
|
241
|
+
(masked & BYTE_MASK) + "/" + prefix;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function _maskIpv6(ip, prefix) {
|
|
245
|
+
// Expand to 8 16-bit groups. Accept :: shorthand. Reject if invalid.
|
|
246
|
+
var raw = String(ip).toLowerCase();
|
|
247
|
+
// Strip an embedded zone id (fe80::1%eth0); not part of the address.
|
|
248
|
+
var pct = raw.indexOf("%");
|
|
249
|
+
if (pct !== -1) raw = raw.substring(0, pct);
|
|
250
|
+
var doubleColonAt = raw.indexOf("::");
|
|
251
|
+
var groups;
|
|
252
|
+
if (doubleColonAt === -1) {
|
|
253
|
+
groups = raw.split(":");
|
|
254
|
+
if (groups.length !== IPV6_GROUP_COUNT) return null;
|
|
255
|
+
} else {
|
|
256
|
+
var left = raw.substring(0, doubleColonAt).split(":");
|
|
257
|
+
var right = raw.substring(doubleColonAt + 2).split(":");
|
|
258
|
+
if (left.length === 1 && left[0] === "") left = [];
|
|
259
|
+
if (right.length === 1 && right[0] === "") right = [];
|
|
260
|
+
var fillCount = IPV6_GROUP_COUNT - left.length - right.length;
|
|
261
|
+
if (fillCount < 0) return null;
|
|
262
|
+
var middle = [];
|
|
263
|
+
for (var fi = 0; fi < fillCount; fi++) middle.push("0");
|
|
264
|
+
groups = left.concat(middle).concat(right);
|
|
265
|
+
}
|
|
266
|
+
// Each group is 1–4 hex chars.
|
|
267
|
+
var bytes = [];
|
|
268
|
+
for (var gi = 0; gi < IPV6_GROUP_COUNT; gi++) {
|
|
269
|
+
var g = groups[gi];
|
|
270
|
+
if (typeof g !== "string" || g.length === 0 || g.length > 4 || /[^0-9a-f]/.test(g)) return null;
|
|
271
|
+
var v = parseInt(g, HEX_RADIX);
|
|
272
|
+
if (!Number.isInteger(v) || v < 0 || v > 0xffff) return null;
|
|
273
|
+
bytes.push((v >> IP_BITS_PER_BYTE) & BYTE_MASK);
|
|
274
|
+
bytes.push(v & BYTE_MASK);
|
|
275
|
+
}
|
|
276
|
+
// Apply prefix in bits.
|
|
277
|
+
var keepBytes = Math.floor(prefix / IP_BITS_PER_BYTE);
|
|
278
|
+
var keepBits = prefix % IP_BITS_PER_BYTE;
|
|
279
|
+
for (var bi = 0; bi < IPV6_BYTE_COUNT; bi++) {
|
|
280
|
+
if (bi < keepBytes) continue;
|
|
281
|
+
if (bi === keepBytes && keepBits > 0) {
|
|
282
|
+
var m = (BYTE_MASK << (IP_BITS_PER_BYTE - keepBits)) & BYTE_MASK;
|
|
283
|
+
bytes[bi] = bytes[bi] & m;
|
|
284
|
+
} else {
|
|
285
|
+
bytes[bi] = 0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Re-emit as colon-hex (no compression — deterministic for hashing).
|
|
289
|
+
var out = [];
|
|
290
|
+
for (var oi = 0; oi < IPV6_BYTE_COUNT; oi += 2) {
|
|
291
|
+
out.push(((bytes[oi] << IP_BITS_PER_BYTE) | bytes[oi + 1]).toString(HEX_RADIX));
|
|
292
|
+
}
|
|
293
|
+
return out.join(":") + "/" + prefix;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function _ipPrefix(ip) {
|
|
297
|
+
if (typeof ip !== "string" || ip.length === 0) return "";
|
|
298
|
+
// IPv4-mapped IPv6 (::ffff:1.2.3.4) — strip the wrapper so the v4
|
|
299
|
+
// mask applies. Same bucket regardless of how the proxy reported it.
|
|
300
|
+
var lower = ip.toLowerCase();
|
|
301
|
+
if (lower.indexOf(V4_MAPPED_V6_PREFIX) === 0 && lower.indexOf(".") !== -1) {
|
|
302
|
+
return _maskIpv4(lower.substring(V4_MAPPED_V6_PREFIX.length), IPV4_DEFAULT_PREFIX) || "";
|
|
303
|
+
}
|
|
304
|
+
if (ip.indexOf(":") !== -1) return _maskIpv6(ip, IPV6_DEFAULT_PREFIX) || "";
|
|
305
|
+
if (ip.indexOf(".") !== -1) return _maskIpv4(ip, IPV4_DEFAULT_PREFIX) || "";
|
|
306
|
+
return "";
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function _buildFingerprintInputs(req, fields) {
|
|
310
|
+
if (!req) return null;
|
|
311
|
+
var headers = req.headers || {};
|
|
312
|
+
var inputs = {};
|
|
313
|
+
for (var i = 0; i < fields.length; i++) {
|
|
314
|
+
var f = fields[i];
|
|
315
|
+
if (f === "clientIp") {
|
|
316
|
+
inputs.clientIp = requestHelpers.clientIp(req) || "";
|
|
317
|
+
} else if (f === "clientIpPrefix") {
|
|
318
|
+
// /24 v4 + /64 v6 — see _ipPrefix() commentary.
|
|
319
|
+
inputs.clientIpPrefix = _ipPrefix(requestHelpers.clientIp(req) || "");
|
|
320
|
+
} else if (f === "userAgent") {
|
|
321
|
+
inputs.userAgent = String(headers["user-agent"] || "");
|
|
322
|
+
} else if (f === "acceptLanguage") {
|
|
323
|
+
// Take only the primary tag (en-US,en;q=0.9 → en-US) so a
|
|
324
|
+
// browser's secondary q-list reordering doesn't flap drift.
|
|
325
|
+
var raw = String(headers["accept-language"] || "");
|
|
326
|
+
var primary = raw.split(",")[0] || "";
|
|
327
|
+
inputs.acceptLanguage = primary.split(";")[0].trim().toLowerCase();
|
|
328
|
+
} else if (typeof f === "function") {
|
|
329
|
+
try { inputs[f.name || ("custom" + i)] = String(f(req) || ""); }
|
|
330
|
+
catch (_e) { inputs[f.name || ("custom" + i)] = ""; }
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return inputs;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function _hashFingerprint(sid, inputs) {
|
|
337
|
+
if (!inputs) return null;
|
|
338
|
+
// Deterministic stringify with sorted keys at every depth — refuses to
|
|
339
|
+
// silently round-trip Date / Buffer / Map / Set / BigInt to "{}".
|
|
340
|
+
var canonical = canonicalJson.stringify(inputs);
|
|
341
|
+
return sha3Hash("bj-session-fingerprint:" + sid + ":" + canonical);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* @primitive b.session.create
|
|
346
|
+
* @signature b.session.create(opts)
|
|
347
|
+
* @since 0.1.0
|
|
348
|
+
* @related b.session.verify, b.session.rotate, b.session.destroy
|
|
349
|
+
*
|
|
350
|
+
* Mint a fresh session for a known userId and return the plaintext sid
|
|
351
|
+
* the caller stores client-side (cookie / authorization header). The
|
|
352
|
+
* sid is 32 random bytes (256-bit entropy floor); the DB stores
|
|
353
|
+
* `sha3('bj-session:' || sid)` so DB exfiltration alone cannot
|
|
354
|
+
* impersonate the session. `data` is vault-sealed JSON; `userId` is
|
|
355
|
+
* sealed; a derived `userIdHash` indexes for fast `destroyAllForUser`.
|
|
356
|
+
* Leader-only — followers raise NotLeaderError.
|
|
357
|
+
*
|
|
358
|
+
* Pass `{ req, fingerprintFields }` to bind the session to a stable
|
|
359
|
+
* hash of client-IP / user-agent / accept-language; the binding is
|
|
360
|
+
* checked on every `verify` call.
|
|
361
|
+
*
|
|
362
|
+
* @opts
|
|
363
|
+
* {
|
|
364
|
+
* userId: string, // required — opaque user id (sealed at rest)
|
|
365
|
+
* data?: object, // optional sealed JSON payload
|
|
366
|
+
* ttlMs?: number, // session lifetime; default 7d, max ~10y
|
|
367
|
+
* req?: IncomingMessage, // bind fingerprint to this request's signals
|
|
368
|
+
* fingerprintFields?: Array<string|fn>, // default ["clientIp","userAgent","acceptLanguage"]
|
|
369
|
+
* }
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* var s = await b.session.create({
|
|
373
|
+
* userId: "user-42",
|
|
374
|
+
* data: { roles: ["admin"] },
|
|
375
|
+
* ttlMs: b.constants.TIME.hours(8),
|
|
376
|
+
* });
|
|
377
|
+
* res.setHeader("Set-Cookie", "sid=" + s.token + "; HttpOnly; Secure; SameSite=Strict");
|
|
378
|
+
* // → { token: "9f2c…", expiresAt: 1735689600000 }
|
|
379
|
+
*/
|
|
380
|
+
// Anonymous-session prefix. b.session.create({ anonymous: true })
|
|
381
|
+
// auto-mints userId = ANON_PREFIX + crypto.randomUUID() so operators
|
|
382
|
+
// running pre-login flows (cart, partial-funnel telemetry, public
|
|
383
|
+
// landing-page personalization) keep the framework's full sealed-
|
|
384
|
+
// cookie + sealed-userId + sidHash + idle/absolute timeout posture
|
|
385
|
+
// without rolling their own opaque-id pattern. destroyAllForUser
|
|
386
|
+
// refuses anon ids: they're per-session and aren't portable.
|
|
387
|
+
var ANON_PREFIX = "anon:";
|
|
388
|
+
function _isAnonymousUserId(id) {
|
|
389
|
+
return typeof id === "string" && id.indexOf(ANON_PREFIX) === 0;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
async function create(opts) {
|
|
393
|
+
cluster.requireLeader();
|
|
394
|
+
opts = opts || {};
|
|
395
|
+
if (opts.anonymous === true) {
|
|
396
|
+
if (opts.userId !== undefined && opts.userId !== null) {
|
|
397
|
+
throw _err("INVALID_ARG",
|
|
398
|
+
"session.create: pass either anonymous: true OR userId, not both", true);
|
|
399
|
+
}
|
|
400
|
+
// crypto.randomUUID is the framework's existing entropy source
|
|
401
|
+
// for opaque ids; anon sessions inherit the same 122-bit space.
|
|
402
|
+
var nodeCryptoForUuid = require("node:crypto"); // allow:inline-require — only the anon path needs randomUUID
|
|
403
|
+
opts = Object.assign({}, opts, { userId: ANON_PREFIX + nodeCryptoForUuid.randomUUID() });
|
|
404
|
+
}
|
|
405
|
+
if (!opts.userId) {
|
|
406
|
+
throw _err("INVALID_ARG", "session.create requires { userId } (or { anonymous: true })", true);
|
|
407
|
+
}
|
|
408
|
+
var ttl = opts.ttlMs !== undefined ? opts.ttlMs : DEFAULT_TTL_MS;
|
|
409
|
+
_validateTtl(ttl, "session.create");
|
|
410
|
+
|
|
411
|
+
var sid = generateToken(SID_BYTES); // hex-encoded; only place the plaintext sid lives
|
|
412
|
+
var sidHash = _hashSid(sid);
|
|
413
|
+
var nowMs = Date.now();
|
|
414
|
+
var expiresAt = nowMs + ttl;
|
|
415
|
+
|
|
416
|
+
// Fingerprint capture (opt-in via opts.req). Stored as a reserved
|
|
417
|
+
// key inside the sealed `data` field so it lives alongside the
|
|
418
|
+
// operator-supplied session data without needing a schema column.
|
|
419
|
+
var dataObj = opts.data ? Object.assign({}, opts.data) : null;
|
|
420
|
+
var fpFields = Array.isArray(opts.fingerprintFields) && opts.fingerprintFields.length > 0
|
|
421
|
+
? opts.fingerprintFields : DEFAULT_FINGERPRINT_FIELDS;
|
|
422
|
+
var fpInputs = _buildFingerprintInputs(opts.req, fpFields);
|
|
423
|
+
if (fpInputs) {
|
|
424
|
+
if (!dataObj) dataObj = {};
|
|
425
|
+
dataObj.__bj_fingerprint = _hashFingerprint(sid, fpInputs);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
var sealed = _sealForInsert({
|
|
429
|
+
sidHash: sidHash,
|
|
430
|
+
userId: opts.userId,
|
|
431
|
+
data: dataObj ? JSON.stringify(dataObj) : null,
|
|
432
|
+
createdAt: nowMs,
|
|
433
|
+
expiresAt: expiresAt,
|
|
434
|
+
lastActivity: nowMs,
|
|
435
|
+
});
|
|
436
|
+
var values = SESSION_COLS.map(function (c) { return sealed[c]; });
|
|
437
|
+
var placeholders = SESSION_COLS.map(function () { return "?"; }).join(", ");
|
|
438
|
+
var quoted = SESSION_COLS.map(function (c) { return '"' + c + '"'; }).join(", ");
|
|
439
|
+
await _currentStore().execute(
|
|
440
|
+
"INSERT INTO _blamejs_sessions (" + quoted + ") VALUES (" + placeholders + ")",
|
|
441
|
+
values
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
return { token: _sealCookieToken(sid), expiresAt: expiresAt };
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* @primitive b.session.verify
|
|
449
|
+
* @signature b.session.verify(token, opts?)
|
|
450
|
+
* @since 0.1.0
|
|
451
|
+
* @related b.session.create, b.session.touch, b.session.rotate
|
|
452
|
+
*
|
|
453
|
+
* Look up a session by its plaintext sid, enforce TTL + idle +
|
|
454
|
+
* absolute timeouts, optionally check fingerprint drift, and return
|
|
455
|
+
* the unsealed payload. Returns `null` for unknown / expired / idle-
|
|
456
|
+
* expired / absolute-expired sessions; runs anywhere (leader or
|
|
457
|
+
* follower). On expiry, leader nodes best-effort delete the row;
|
|
458
|
+
* followers skip cleanup.
|
|
459
|
+
*
|
|
460
|
+
* `idleTimeoutMs` defaults to 30 minutes, `absoluteTimeoutMs` to 12
|
|
461
|
+
* hours; pass 0 to disable either floor. Pass `{ req }` to evaluate
|
|
462
|
+
* the bound fingerprint — the result carries `fingerprintDrift: true`
|
|
463
|
+
* on mismatch (audit event always fires). `requireFingerprintMatch:
|
|
464
|
+
* true` or a `maxAnomalyScore` threshold (with a `scorer` callback)
|
|
465
|
+
* makes drift refuse the session by returning `null`.
|
|
466
|
+
*
|
|
467
|
+
* @opts
|
|
468
|
+
* {
|
|
469
|
+
* idleTimeoutMs?: number, // default 30m; 0 disables
|
|
470
|
+
* absoluteTimeoutMs?: number, // default 12h; 0 disables
|
|
471
|
+
* req?: IncomingMessage, // for fingerprint check
|
|
472
|
+
* fingerprintFields?: Array<string|fn>,
|
|
473
|
+
* requireFingerprintMatch?: boolean, // strict — drift kills the session
|
|
474
|
+
* maxAnomalyScore?: number, // 0..1; drift above kills
|
|
475
|
+
* scorer?: function, // ({storedHash,currentInputs,currentHash,sessionAge}) -> 0..1
|
|
476
|
+
* }
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* var info = await b.session.verify(req.cookies.sid, { req: req });
|
|
480
|
+
* if (!info) {
|
|
481
|
+
* res.statusCode = 401;
|
|
482
|
+
* res.end("login required");
|
|
483
|
+
* return;
|
|
484
|
+
* }
|
|
485
|
+
* var userId = info.userId;
|
|
486
|
+
* var roles = (info.data && info.data.roles) || [];
|
|
487
|
+
* // → { userId: "user-42", data: { roles: ["admin"] }, createdAt: ..., expiresAt: ..., lastActivity: ..., fingerprintDrift: false, fingerprintAnomalyScore: null }
|
|
488
|
+
*/
|
|
489
|
+
async function verify(token, verifyOpts) {
|
|
490
|
+
if (typeof token !== "string" || token.length === 0) return null;
|
|
491
|
+
verifyOpts = verifyOpts || {};
|
|
492
|
+
// Sealed-cookie default — unseal the wire token to recover the sid.
|
|
493
|
+
// Pre-v0.8.61 raw cookies / tampered envelopes return null and the
|
|
494
|
+
// caller re-auths. The plaintext sid never leaves this function.
|
|
495
|
+
var sid = _unsealCookieToken(token);
|
|
496
|
+
if (sid === null) return null;
|
|
497
|
+
var sidHash = _hashSid(sid);
|
|
498
|
+
|
|
499
|
+
var row = await _currentStore().executeOne(
|
|
500
|
+
"SELECT sidHash, userId, userIdHash, data, createdAt, expiresAt, lastActivity " +
|
|
501
|
+
"FROM _blamejs_sessions WHERE sidHash = ?",
|
|
502
|
+
[sidHash]
|
|
503
|
+
);
|
|
504
|
+
if (!row) return null;
|
|
505
|
+
var nowMs = Date.now();
|
|
506
|
+
if (Number(row.expiresAt) < nowMs) {
|
|
507
|
+
// Expired (operator-set ttl) — clean up and return null. Cleanup
|
|
508
|
+
// is leader-only; verify is anywhere, so a follower observing an
|
|
509
|
+
// expired row skips the cleanup (next leader-side call purges it).
|
|
510
|
+
if (cluster.isLeader()) {
|
|
511
|
+
try { await _deleteBySidHash(sidHash); } catch (_e) { /* best-effort */ }
|
|
512
|
+
}
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Idle + absolute timeout enforcement (OWASP ASVS 5.0 §3.3 / NIST
|
|
517
|
+
// SP 800-63B-4). These shorten the effective lifetime even when the
|
|
518
|
+
// operator picked a long ttlMs. Defaults: idle 30m, absolute 12h.
|
|
519
|
+
// Operator opt-out by passing 0 (disables that timeout).
|
|
520
|
+
var idleMs = verifyOpts.idleTimeoutMs !== undefined
|
|
521
|
+
? verifyOpts.idleTimeoutMs : DEFAULT_IDLE_TIMEOUT_MS;
|
|
522
|
+
var absMs = verifyOpts.absoluteTimeoutMs !== undefined
|
|
523
|
+
? verifyOpts.absoluteTimeoutMs : DEFAULT_ABSOLUTE_TIMEOUT_MS;
|
|
524
|
+
if (idleMs > 0) {
|
|
525
|
+
var lastActivity = Number(row.lastActivity);
|
|
526
|
+
if ((nowMs - lastActivity) > idleMs) {
|
|
527
|
+
try {
|
|
528
|
+
audit.safeEmit({
|
|
529
|
+
action: "auth.session.expired_idle", outcome: "success",
|
|
530
|
+
metadata: { idleMs: nowMs - lastActivity, threshold: idleMs },
|
|
531
|
+
});
|
|
532
|
+
} catch (_ignored) { /* audit best-effort */ }
|
|
533
|
+
if (cluster.isLeader()) {
|
|
534
|
+
try { await _deleteBySidHash(sidHash); } catch (_e) { /* best-effort */ }
|
|
535
|
+
}
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (absMs > 0) {
|
|
540
|
+
var createdAt = Number(row.createdAt);
|
|
541
|
+
if ((nowMs - createdAt) > absMs) {
|
|
542
|
+
try {
|
|
543
|
+
audit.safeEmit({
|
|
544
|
+
action: "auth.session.expired_absolute", outcome: "success",
|
|
545
|
+
metadata: { ageMs: nowMs - createdAt, threshold: absMs },
|
|
546
|
+
});
|
|
547
|
+
} catch (_ignored) { /* audit best-effort */ }
|
|
548
|
+
if (cluster.isLeader()) {
|
|
549
|
+
try { await _deleteBySidHash(sidHash); } catch (_e) { /* best-effort */ }
|
|
550
|
+
}
|
|
551
|
+
return null;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// Unseal sealed columns (userId, data) using the cryptoField pipeline
|
|
555
|
+
// so we return cleartext to the caller — same shape as the previous
|
|
556
|
+
// db().from(...).first() path delivered.
|
|
557
|
+
var unsealed = cryptoField.unsealRow("_blamejs_sessions", row);
|
|
558
|
+
var data = null;
|
|
559
|
+
var storedFingerprint = null;
|
|
560
|
+
if (unsealed.data) {
|
|
561
|
+
try {
|
|
562
|
+
data = safeJson.parse(unsealed.data);
|
|
563
|
+
if (data && typeof data === "object" && typeof data.__bj_fingerprint === "string") {
|
|
564
|
+
storedFingerprint = data.__bj_fingerprint;
|
|
565
|
+
// Strip the reserved key from the operator-visible data so
|
|
566
|
+
// routes don't accidentally render it / log it / pass it on.
|
|
567
|
+
delete data.__bj_fingerprint;
|
|
568
|
+
if (Object.keys(data).length === 0) data = null;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
catch (e) {
|
|
572
|
+
// Decrypt-then-parse failure is rare but operationally important —
|
|
573
|
+
// it usually signals key-rotation skew, DB corruption, or
|
|
574
|
+
// tampering. Emit an audit event so ops can spot it before the
|
|
575
|
+
// operator notices empty-`data` flows. data stays null so the
|
|
576
|
+
// session remains usable for non-data flows.
|
|
577
|
+
data = null;
|
|
578
|
+
try {
|
|
579
|
+
audit.safeEmit({
|
|
580
|
+
action: "auth.session.data_unparseable",
|
|
581
|
+
outcome: "failure",
|
|
582
|
+
reason: (e && e.message) || String(e),
|
|
583
|
+
metadata: { hasUserId: !!unsealed.userId },
|
|
584
|
+
});
|
|
585
|
+
} catch (_ignored) { /* audit best-effort */ }
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Fingerprint check — opt-in via verifyOpts.req. When the stored
|
|
590
|
+
// fingerprint differs from the current request's fingerprint, audit
|
|
591
|
+
// the drift and (in strict mode) refuse the session. Default mode
|
|
592
|
+
// returns the session with `fingerprintDrift: true` so the operator
|
|
593
|
+
// can decide (some drift — phone roaming wifi/LTE — is benign; a
|
|
594
|
+
// login-from-Tokyo-then-immediately-from-Brazil pattern is not).
|
|
595
|
+
var fingerprintDrift = false;
|
|
596
|
+
var fingerprintAnomalyScore = null;
|
|
597
|
+
if (storedFingerprint && verifyOpts.req) {
|
|
598
|
+
var fpFields = Array.isArray(verifyOpts.fingerprintFields) && verifyOpts.fingerprintFields.length > 0
|
|
599
|
+
? verifyOpts.fingerprintFields : DEFAULT_FINGERPRINT_FIELDS;
|
|
600
|
+
var currentInputs = _buildFingerprintInputs(verifyOpts.req, fpFields);
|
|
601
|
+
var currentHash = _hashFingerprint(sid, currentInputs);
|
|
602
|
+
if (currentHash !== storedFingerprint) {
|
|
603
|
+
fingerprintDrift = true;
|
|
604
|
+
// Operator-supplied scorer: receives { storedHash, currentInputs,
|
|
605
|
+
// currentHash, sessionAge: ms-since-create }. Returns a number
|
|
606
|
+
// in [0, 1] — 0 = benign drift (phone roaming wifi), 1 =
|
|
607
|
+
// definitely-malicious. Errors are swallowed; scorer-throw
|
|
608
|
+
// doesn't break verify.
|
|
609
|
+
if (typeof verifyOpts.scorer === "function") {
|
|
610
|
+
try {
|
|
611
|
+
var rawScore = verifyOpts.scorer({
|
|
612
|
+
storedHash: storedFingerprint,
|
|
613
|
+
currentInputs: currentInputs,
|
|
614
|
+
currentHash: currentHash,
|
|
615
|
+
sessionAge: Date.now() - Number(unsealed.createdAt),
|
|
616
|
+
});
|
|
617
|
+
if (typeof rawScore === "number" && isFinite(rawScore)) {
|
|
618
|
+
fingerprintAnomalyScore = Math.max(0, Math.min(1, rawScore));
|
|
619
|
+
}
|
|
620
|
+
} catch (_e) { /* scorer best-effort */ }
|
|
621
|
+
}
|
|
622
|
+
try {
|
|
623
|
+
audit.safeEmit({
|
|
624
|
+
action: "auth.session.fingerprint_drift",
|
|
625
|
+
outcome: "success",
|
|
626
|
+
metadata: { hasUserId: !!unsealed.userId,
|
|
627
|
+
anomalyScore: fingerprintAnomalyScore },
|
|
628
|
+
});
|
|
629
|
+
} catch (_ignored) { /* audit best-effort */ }
|
|
630
|
+
// Strict modes:
|
|
631
|
+
// requireFingerprintMatch: true — any drift kills the session
|
|
632
|
+
// maxAnomalyScore: <0..1> — drift above threshold kills
|
|
633
|
+
if (verifyOpts.requireFingerprintMatch === true) {
|
|
634
|
+
return null;
|
|
635
|
+
}
|
|
636
|
+
if (typeof verifyOpts.maxAnomalyScore === "number" &&
|
|
637
|
+
fingerprintAnomalyScore !== null &&
|
|
638
|
+
fingerprintAnomalyScore > verifyOpts.maxAnomalyScore) {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
return {
|
|
645
|
+
userId: unsealed.userId,
|
|
646
|
+
data: data,
|
|
647
|
+
createdAt: Number(unsealed.createdAt),
|
|
648
|
+
expiresAt: Number(unsealed.expiresAt),
|
|
649
|
+
lastActivity: Number(unsealed.lastActivity),
|
|
650
|
+
fingerprintDrift: fingerprintDrift,
|
|
651
|
+
fingerprintAnomalyScore: fingerprintAnomalyScore,
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* @primitive b.session.destroy
|
|
657
|
+
* @signature b.session.destroy(token)
|
|
658
|
+
* @since 0.1.0
|
|
659
|
+
* @related b.session.destroyAllForUser, b.session.create
|
|
660
|
+
*
|
|
661
|
+
* Revoke a single session by sid. Returns `true` when a row was
|
|
662
|
+
* deleted, `false` when the sid is unknown / already gone / empty.
|
|
663
|
+
* Standard logout flow: clear the client's cookie AND call
|
|
664
|
+
* `destroy(sid)` so the row vanishes from the DB and verify(sid)
|
|
665
|
+
* starts returning null cluster-wide. Leader-only.
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* await b.session.destroy(req.cookies.sid);
|
|
669
|
+
* res.setHeader("Set-Cookie", "sid=; HttpOnly; Max-Age=0");
|
|
670
|
+
* res.end("logged out");
|
|
671
|
+
* // → true
|
|
672
|
+
*/
|
|
673
|
+
async function destroy(token) {
|
|
674
|
+
cluster.requireLeader();
|
|
675
|
+
if (typeof token !== "string" || token.length === 0) return false;
|
|
676
|
+
var sid = _unsealCookieToken(token);
|
|
677
|
+
if (sid === null) return false;
|
|
678
|
+
return await _deleteBySidHash(_hashSid(sid));
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
async function _deleteBySidHash(sidHash) {
|
|
682
|
+
var result = await _currentStore().execute(
|
|
683
|
+
"DELETE FROM _blamejs_sessions WHERE sidHash = ?",
|
|
684
|
+
[sidHash]
|
|
685
|
+
);
|
|
686
|
+
return (result.rowCount || 0) > 0;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* @primitive b.session.destroyAllForUser
|
|
691
|
+
* @signature b.session.destroyAllForUser(userId)
|
|
692
|
+
* @since 0.1.0
|
|
693
|
+
* @related b.session.destroy, b.session.rotate
|
|
694
|
+
*
|
|
695
|
+
* Revoke every active session for a userId at once. Returns the count
|
|
696
|
+
* of rows deleted. Use after password change, role revocation,
|
|
697
|
+
* compromised-account reports, or "log me out everywhere" UI flows.
|
|
698
|
+
* Lookup goes through the derived `userIdHash` — no row needs
|
|
699
|
+
* unsealing to find matches. Leader-only.
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* var revoked = await b.session.destroyAllForUser("user-42");
|
|
703
|
+
* b.audit.emit({ action: "auth.session.revoke_all", outcome: "success",
|
|
704
|
+
* metadata: { userId: "user-42", count: revoked } });
|
|
705
|
+
* // → 3
|
|
706
|
+
*/
|
|
707
|
+
async function destroyAllForUser(userId) {
|
|
708
|
+
cluster.requireLeader();
|
|
709
|
+
if (!userId) throw _err("INVALID_ARG", "session.destroyAllForUser requires a userId", true);
|
|
710
|
+
if (_isAnonymousUserId(userId)) {
|
|
711
|
+
// Anon ids are minted per-session and aren't reused — destroying
|
|
712
|
+
// "all" anon sessions for one anon id is the same as destroying
|
|
713
|
+
// that single session. Refuse loudly so the operator doesn't
|
|
714
|
+
// think they're sweeping across an anon population.
|
|
715
|
+
throw _err("INVALID_ARG",
|
|
716
|
+
"session.destroyAllForUser: anonymous-prefix ids (\"anon:...\") are per-session — " +
|
|
717
|
+
"use destroy(token) for that session, OR purgeExpired() for housekeeping",
|
|
718
|
+
true);
|
|
719
|
+
}
|
|
720
|
+
// userId is sealed; look up via derived userIdHash.
|
|
721
|
+
var lookup = cryptoField.lookupHash("_blamejs_sessions", "userId", userId);
|
|
722
|
+
if (!lookup) {
|
|
723
|
+
throw _err("MISCONFIGURED",
|
|
724
|
+
"_blamejs_sessions schema is missing the userIdHash derived hash — framework misconfigured",
|
|
725
|
+
true);
|
|
726
|
+
}
|
|
727
|
+
var result = await _currentStore().execute(
|
|
728
|
+
"DELETE FROM _blamejs_sessions WHERE userIdHash = ?",
|
|
729
|
+
[lookup.value]
|
|
730
|
+
);
|
|
731
|
+
return result.rowCount || 0;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* @primitive b.session.touch
|
|
736
|
+
* @signature b.session.touch(token, opts)
|
|
737
|
+
* @since 0.1.0
|
|
738
|
+
* @related b.session.verify, b.session.rotate
|
|
739
|
+
*
|
|
740
|
+
* Refresh `lastActivity` (resets the idle-timeout countdown) and
|
|
741
|
+
* optionally extend `expiresAt`. Returns `true` when a non-expired
|
|
742
|
+
* row was updated, `false` when the sid is unknown or the row is
|
|
743
|
+
* already past its TTL. Pass `extendBy` to push `expiresAt` forward
|
|
744
|
+
* relative to NOW (not the existing expiry — soaked sessions with
|
|
745
|
+
* continuous traffic don't accumulate unbounded expiry); the
|
|
746
|
+
* framework's MAX_TTL_MS bound applies. Leader-only.
|
|
747
|
+
*
|
|
748
|
+
* @opts
|
|
749
|
+
* {
|
|
750
|
+
* extendBy?: number, // ms to set new expiresAt = now + extendBy
|
|
751
|
+
* }
|
|
752
|
+
*
|
|
753
|
+
* @example
|
|
754
|
+
* // Bump idle clock on every request:
|
|
755
|
+
* await b.session.touch(req.cookies.sid);
|
|
756
|
+
*
|
|
757
|
+
* // Sliding-window: extend by another 8 hours when activity continues.
|
|
758
|
+
* await b.session.touch(req.cookies.sid, { extendBy: b.constants.TIME.hours(8) });
|
|
759
|
+
* // → true
|
|
760
|
+
*/
|
|
761
|
+
async function touch(token, opts) {
|
|
762
|
+
cluster.requireLeader();
|
|
763
|
+
opts = opts || {};
|
|
764
|
+
if (typeof token !== "string" || token.length === 0) return false;
|
|
765
|
+
var sid = _unsealCookieToken(token);
|
|
766
|
+
if (sid === null) return false;
|
|
767
|
+
var sidHash = _hashSid(sid);
|
|
768
|
+
var nowMs = Date.now();
|
|
769
|
+
// Two SQL paths so the SET list stays static (no dynamic column
|
|
770
|
+
// assembly) and matches the call shape clusterStorage expects.
|
|
771
|
+
// extendBy resets expiresAt relative to NOW, not relative to the
|
|
772
|
+
// current expiresAt — a soaked session with continuous traffic
|
|
773
|
+
// shouldn't accumulate unbounded expiry. The same MAX_TTL_MS
|
|
774
|
+
// ceiling create() and rotate() apply gates extendBy too — repeated
|
|
775
|
+
// touch() calls cannot push expiresAt past the framework's bound.
|
|
776
|
+
if (opts.extendBy !== undefined && opts.extendBy !== null) {
|
|
777
|
+
_validateTtl(opts.extendBy, "session.touch");
|
|
778
|
+
var newExpires = nowMs + opts.extendBy;
|
|
779
|
+
var result = await _currentStore().execute(
|
|
780
|
+
"UPDATE _blamejs_sessions SET lastActivity = ?, expiresAt = ? " +
|
|
781
|
+
"WHERE sidHash = ? AND expiresAt >= ?",
|
|
782
|
+
[nowMs, newExpires, sidHash, nowMs]
|
|
783
|
+
);
|
|
784
|
+
return (result.rowCount || 0) > 0;
|
|
785
|
+
}
|
|
786
|
+
var result2 = await _currentStore().execute(
|
|
787
|
+
"UPDATE _blamejs_sessions SET lastActivity = ? " +
|
|
788
|
+
"WHERE sidHash = ? AND expiresAt >= ?",
|
|
789
|
+
[nowMs, sidHash, nowMs]
|
|
790
|
+
);
|
|
791
|
+
return (result2.rowCount || 0) > 0;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* @primitive b.session.rotate
|
|
796
|
+
* @signature b.session.rotate(oldToken, opts)
|
|
797
|
+
* @since 0.1.0
|
|
798
|
+
* @related b.session.create, b.session.verify, b.session.destroy
|
|
799
|
+
*
|
|
800
|
+
* Session-fixation defense: generate a fresh sid for the same userId +
|
|
801
|
+
* data, atomically replacing the old sid in the row. Call after every
|
|
802
|
+
* auth state change (login from anonymous, multifactor verified, role
|
|
803
|
+
* escalation) so any sid an attacker planted pre-login becomes invalid.
|
|
804
|
+
* Returns `{ token, expiresAt }` on success, `null` when the old token
|
|
805
|
+
* is unknown / expired (operator distinguishes by checking for null).
|
|
806
|
+
* Leader-only.
|
|
807
|
+
*
|
|
808
|
+
* Atomicity: a single WHERE-guarded UPDATE swaps `sidHash`. The old
|
|
809
|
+
* and new tokens never coexist — the moment the UPDATE commits, only
|
|
810
|
+
* the new token verifies. Audit event `auth.session.rotate` fires
|
|
811
|
+
* best-effort with `metadata.reason`.
|
|
812
|
+
*
|
|
813
|
+
* @opts
|
|
814
|
+
* {
|
|
815
|
+
* data?: object, // replacement session data (re-sealed)
|
|
816
|
+
* ttlMs?: number, // new TTL; if absent, existing expiresAt preserved
|
|
817
|
+
* reason?: string, // audit metadata ("login", "mfa", "role-change")
|
|
818
|
+
* }
|
|
819
|
+
*
|
|
820
|
+
* @example
|
|
821
|
+
* var rotated = await b.session.rotate(req.cookies.sid, {
|
|
822
|
+
* ttlMs: b.constants.TIME.hours(8),
|
|
823
|
+
* reason: "mfa",
|
|
824
|
+
* });
|
|
825
|
+
* if (rotated) {
|
|
826
|
+
* res.setHeader("Set-Cookie", "sid=" + rotated.token + "; HttpOnly; Secure; SameSite=Strict");
|
|
827
|
+
* }
|
|
828
|
+
* // → { token: "7a1e…", expiresAt: 1735689600000 }
|
|
829
|
+
*/
|
|
830
|
+
async function rotate(oldToken, opts) {
|
|
831
|
+
cluster.requireLeader();
|
|
832
|
+
if (typeof oldToken !== "string" || oldToken.length === 0) return null;
|
|
833
|
+
opts = opts || {};
|
|
834
|
+
var oldSid = _unsealCookieToken(oldToken);
|
|
835
|
+
if (oldSid === null) return null;
|
|
836
|
+
|
|
837
|
+
var newSid = generateToken(SID_BYTES);
|
|
838
|
+
var newSidHash = _hashSid(newSid);
|
|
839
|
+
var oldSidHash = _hashSid(oldSid);
|
|
840
|
+
var nowMs = Date.now();
|
|
841
|
+
var newExpires = null;
|
|
842
|
+
if (opts.ttlMs !== undefined) {
|
|
843
|
+
_validateTtl(opts.ttlMs, "session.rotate");
|
|
844
|
+
newExpires = nowMs + opts.ttlMs;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
var setParts = ['"sidHash" = ?', '"lastActivity" = ?'];
|
|
848
|
+
var setParams = [newSidHash, nowMs];
|
|
849
|
+
|
|
850
|
+
if (opts.data !== undefined) {
|
|
851
|
+
var dataJson = opts.data ? JSON.stringify(opts.data) : null;
|
|
852
|
+
var sealedRow = cryptoField.sealRow("_blamejs_sessions", { data: dataJson });
|
|
853
|
+
setParts.push('"data" = ?');
|
|
854
|
+
setParams.push(sealedRow.data);
|
|
855
|
+
}
|
|
856
|
+
if (newExpires !== null) {
|
|
857
|
+
setParts.push('"expiresAt" = ?');
|
|
858
|
+
setParams.push(newExpires);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
var sql = "UPDATE _blamejs_sessions SET " + setParts.join(", ") +
|
|
862
|
+
" WHERE sidHash = ? AND expiresAt >= ?";
|
|
863
|
+
var params = setParams.concat([oldSidHash, nowMs]);
|
|
864
|
+
var result = await _currentStore().execute(sql, params);
|
|
865
|
+
if ((result.rowCount || 0) === 0) return null;
|
|
866
|
+
|
|
867
|
+
// Read the row's effective expiresAt to return — single source of truth.
|
|
868
|
+
var row = await _currentStore().executeOne(
|
|
869
|
+
'SELECT "expiresAt" FROM _blamejs_sessions WHERE sidHash = ?',
|
|
870
|
+
[newSidHash]
|
|
871
|
+
);
|
|
872
|
+
var expiresAt = row ? Number(row.expiresAt) : null;
|
|
873
|
+
|
|
874
|
+
// Audit emit — best-effort. The framework's audit chain logs the
|
|
875
|
+
// privilege transition so post-incident review can trace which
|
|
876
|
+
// session id covered which privilege state.
|
|
877
|
+
try {
|
|
878
|
+
audit.emit({
|
|
879
|
+
action: "auth.session.rotate",
|
|
880
|
+
outcome: "success",
|
|
881
|
+
metadata: { reason: opts.reason || "explicit" },
|
|
882
|
+
});
|
|
883
|
+
} catch (_e) { /* audit emit best-effort — never block rotate() */ }
|
|
884
|
+
|
|
885
|
+
return { token: _sealCookieToken(newSid), expiresAt: expiresAt };
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* @primitive b.session.updateData
|
|
890
|
+
* @signature b.session.updateData(token, data, opts?)
|
|
891
|
+
* @since 0.8.66
|
|
892
|
+
* @related b.session.verify, b.session.rotate
|
|
893
|
+
*
|
|
894
|
+
* Update the sealed `data` payload on a session WITHOUT rotating the
|
|
895
|
+
* sid. Use cases: cart-state writes, user-preference flips, step-up-
|
|
896
|
+
* auth completion flags, fingerprint-anomaly score updates. Anything
|
|
897
|
+
* that doesn't change the security boundary (login transition, role
|
|
898
|
+
* escalation, multifactor verified) — those still go through
|
|
899
|
+
* `b.session.rotate({ data })` so the sid moves and any pre-login
|
|
900
|
+
* tokens an attacker may have planted become invalid.
|
|
901
|
+
*
|
|
902
|
+
* Default semantics:
|
|
903
|
+
* - `data` REPLACES the existing payload (full overwrite). The
|
|
904
|
+
* reserved `__bj_fingerprint` key is preserved automatically so
|
|
905
|
+
* fingerprint-binding survives the update.
|
|
906
|
+
* - `lastActivity` is bumped (idle-timeout reset) unless
|
|
907
|
+
* `opts.touchLastActivity: false`.
|
|
908
|
+
* - The session must be live (not expired) for the write to land;
|
|
909
|
+
* returns `false` for unknown / expired tokens.
|
|
910
|
+
*
|
|
911
|
+
* Pass `opts.merge: true` to deep-merge top-level keys into the
|
|
912
|
+
* existing payload instead of replacing — useful for incremental
|
|
913
|
+
* writes where the operator doesn't want to round-trip read+merge
|
|
914
|
+
* themselves. Inner objects merge ONE LEVEL DEEP; arrays REPLACE.
|
|
915
|
+
*
|
|
916
|
+
* Leader-only.
|
|
917
|
+
*
|
|
918
|
+
* @opts
|
|
919
|
+
* {
|
|
920
|
+
* merge?: boolean, // default false (full replace)
|
|
921
|
+
* touchLastActivity?: boolean, // default true
|
|
922
|
+
* }
|
|
923
|
+
*
|
|
924
|
+
* @example
|
|
925
|
+
* // Replace the data payload entirely.
|
|
926
|
+
* await b.session.updateData(req.cookies.sid, { roles: ["admin"], theme: "dark" });
|
|
927
|
+
*
|
|
928
|
+
* // Merge a single field without disturbing the rest of the payload.
|
|
929
|
+
* await b.session.updateData(req.cookies.sid,
|
|
930
|
+
* { stepUpAt: Date.now() }, { merge: true });
|
|
931
|
+
* // → true
|
|
932
|
+
*/
|
|
933
|
+
async function updateData(token, data, opts) {
|
|
934
|
+
cluster.requireLeader();
|
|
935
|
+
opts = opts || {};
|
|
936
|
+
if (typeof token !== "string" || token.length === 0) return false;
|
|
937
|
+
if (data !== null && (typeof data !== "object" || Array.isArray(data))) {
|
|
938
|
+
throw _err("INVALID_ARG",
|
|
939
|
+
"session.updateData: data must be a plain object or null", true);
|
|
940
|
+
}
|
|
941
|
+
var sid = _unsealCookieToken(token);
|
|
942
|
+
if (sid === null) return false;
|
|
943
|
+
var sidHash = _hashSid(sid);
|
|
944
|
+
var nowMs = Date.now();
|
|
945
|
+
|
|
946
|
+
// Read the live row so we can preserve __bj_fingerprint and (in
|
|
947
|
+
// merge mode) carry forward existing keys. Single SELECT + UPDATE
|
|
948
|
+
// — racing concurrent updateData calls fall through to last-write-
|
|
949
|
+
// wins on the same sid, which is the right shape for cart-style
|
|
950
|
+
// writes; operators needing strict serialization wrap with
|
|
951
|
+
// b.resourceAccessLock.
|
|
952
|
+
var row = await _currentStore().executeOne(
|
|
953
|
+
'SELECT "userId", "userIdHash", "data", "createdAt", "expiresAt", "lastActivity" ' +
|
|
954
|
+
'FROM _blamejs_sessions WHERE sidHash = ? AND expiresAt >= ?',
|
|
955
|
+
[sidHash, nowMs]
|
|
956
|
+
);
|
|
957
|
+
if (!row) return false;
|
|
958
|
+
|
|
959
|
+
// Recover the existing data + reserved fingerprint key (vault-
|
|
960
|
+
// sealed at rest). Operators that want a fresh fingerprint also
|
|
961
|
+
// call b.session.rotate; updateData preserves the binding.
|
|
962
|
+
var unsealed = cryptoField.unsealRow("_blamejs_sessions", row);
|
|
963
|
+
var existing = null;
|
|
964
|
+
var storedFingerprint = null;
|
|
965
|
+
if (unsealed.data) {
|
|
966
|
+
try {
|
|
967
|
+
existing = safeJson.parse(unsealed.data);
|
|
968
|
+
if (existing && typeof existing === "object" &&
|
|
969
|
+
typeof existing.__bj_fingerprint === "string") {
|
|
970
|
+
storedFingerprint = existing.__bj_fingerprint;
|
|
971
|
+
}
|
|
972
|
+
} catch (_e) {
|
|
973
|
+
// Decrypt-then-parse failure mirrors verify() — drop existing
|
|
974
|
+
// and proceed with the new payload only. Operator gets the
|
|
975
|
+
// same auth.session.data_unparseable signal next verify().
|
|
976
|
+
existing = null;
|
|
977
|
+
storedFingerprint = null;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// Build the next payload. merge:true does a one-level deep merge
|
|
982
|
+
// into the existing object (arrays at the top level REPLACE);
|
|
983
|
+
// default replaces wholesale.
|
|
984
|
+
var next;
|
|
985
|
+
if (opts.merge === true && existing && typeof existing === "object") {
|
|
986
|
+
next = Object.assign({}, existing);
|
|
987
|
+
if (data && typeof data === "object") {
|
|
988
|
+
Object.keys(data).forEach(function (k) {
|
|
989
|
+
if (k === "__bj_fingerprint") return; // reserved — only fingerprint binding writes this
|
|
990
|
+
next[k] = data[k];
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
} else {
|
|
994
|
+
next = (data && typeof data === "object") ? Object.assign({}, data) : null;
|
|
995
|
+
if (next) delete next.__bj_fingerprint; // reserved — operator can't overwrite the binding
|
|
996
|
+
}
|
|
997
|
+
if (storedFingerprint && next) next.__bj_fingerprint = storedFingerprint;
|
|
998
|
+
|
|
999
|
+
// Re-seal the data column. cryptoField.sealRow handles the AAD
|
|
1000
|
+
// binding + sealedFields registration automatically.
|
|
1001
|
+
var sealedRow = cryptoField.sealRow("_blamejs_sessions", {
|
|
1002
|
+
data: next ? JSON.stringify(next) : null,
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
var setParts = ['"data" = ?'];
|
|
1006
|
+
var setParams = [sealedRow.data];
|
|
1007
|
+
if (opts.touchLastActivity !== false) {
|
|
1008
|
+
setParts.push('"lastActivity" = ?');
|
|
1009
|
+
setParams.push(nowMs);
|
|
1010
|
+
}
|
|
1011
|
+
var sql = "UPDATE _blamejs_sessions SET " + setParts.join(", ") +
|
|
1012
|
+
" WHERE sidHash = ? AND expiresAt >= ?";
|
|
1013
|
+
var result = await _currentStore().execute(sql, setParams.concat([sidHash, nowMs]));
|
|
1014
|
+
return (result.rowCount || 0) > 0;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* @primitive b.session.purgeExpired
|
|
1019
|
+
* @signature b.session.purgeExpired()
|
|
1020
|
+
* @since 0.1.0
|
|
1021
|
+
* @related b.session.count, b.session.destroy
|
|
1022
|
+
*
|
|
1023
|
+
* Bulk-delete every row whose `expiresAt` is in the past. Returns the
|
|
1024
|
+
* count of rows removed. The framework purges opportunistically on
|
|
1025
|
+
* `verify` (leader-side), but a periodic sweep keeps the table from
|
|
1026
|
+
* accumulating dead rows when verify traffic is sparse. Safe to schedule
|
|
1027
|
+
* on a recurring timer (the framework's scheduler primitive is the
|
|
1028
|
+
* intended caller). Leader-only.
|
|
1029
|
+
*
|
|
1030
|
+
* @example
|
|
1031
|
+
* // Hourly purge from a scheduler:
|
|
1032
|
+
* b.scheduler.every(b.constants.TIME.hours(1), async function () {
|
|
1033
|
+
* var dropped = await b.session.purgeExpired();
|
|
1034
|
+
* b.audit.emit({
|
|
1035
|
+
* action: "auth.session.purge_expired", outcome: "success",
|
|
1036
|
+
* metadata: { dropped: dropped },
|
|
1037
|
+
* });
|
|
1038
|
+
* });
|
|
1039
|
+
* // → 17
|
|
1040
|
+
*/
|
|
1041
|
+
async function purgeExpired() {
|
|
1042
|
+
cluster.requireLeader();
|
|
1043
|
+
var result = await _currentStore().execute(
|
|
1044
|
+
"DELETE FROM _blamejs_sessions WHERE expiresAt < ?",
|
|
1045
|
+
[Date.now()]
|
|
1046
|
+
);
|
|
1047
|
+
return result.rowCount || 0;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* @primitive b.session.count
|
|
1052
|
+
* @signature b.session.count()
|
|
1053
|
+
* @since 0.1.0
|
|
1054
|
+
* @related b.session.purgeExpired, b.session.destroyAllForUser
|
|
1055
|
+
*
|
|
1056
|
+
* Return the number of currently-live sessions (rows whose `expiresAt`
|
|
1057
|
+
* is in the future). Useful for ops dashboards, capacity tracking, and
|
|
1058
|
+
* "active users" metrics. Runs anywhere — leader or follower — because
|
|
1059
|
+
* it only reads. Note that idle-timeout-eligible rows are still counted
|
|
1060
|
+
* until a `verify` or `purgeExpired` removes them; the value is an
|
|
1061
|
+
* upper bound on truly-active sessions.
|
|
1062
|
+
*
|
|
1063
|
+
* @example
|
|
1064
|
+
* var live = await b.session.count();
|
|
1065
|
+
* b.observability.event({ name: "session.live", value: live });
|
|
1066
|
+
* // → 482
|
|
1067
|
+
*/
|
|
1068
|
+
async function count() {
|
|
1069
|
+
var row = await _currentStore().executeOne(
|
|
1070
|
+
"SELECT COUNT(*) AS c FROM _blamejs_sessions WHERE expiresAt >= ?",
|
|
1071
|
+
[Date.now()]
|
|
1072
|
+
);
|
|
1073
|
+
return row ? Number(row.c) : 0;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
function _resetForTest() { _store = null; }
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* @primitive b.session.useStore
|
|
1080
|
+
* @signature b.session.useStore(store)
|
|
1081
|
+
* @since 0.8.61
|
|
1082
|
+
* @status stable
|
|
1083
|
+
* @related b.session.stores.localDbThin
|
|
1084
|
+
*
|
|
1085
|
+
* Replace the default `_blamejs_sessions` storage backend (the
|
|
1086
|
+
* framework's main DB / external DB via cluster-storage) with an
|
|
1087
|
+
* operator-supplied store. The store must expose
|
|
1088
|
+
* `execute(sql, params)` and `executeOne(sql, params)` returning the
|
|
1089
|
+
* same `{ rows, rowCount }` / `row | null` shape `b.clusterStorage`
|
|
1090
|
+
* returns. Pass `null` to revert to the default.
|
|
1091
|
+
*
|
|
1092
|
+
* Typical use is to point session writes at an isolated SQLite file
|
|
1093
|
+
* (often tmpfs) so session churn doesn't fight the main DB's encrypted-
|
|
1094
|
+
* at-rest re-flush cycle. The first-party adapter is
|
|
1095
|
+
* `b.session.stores.localDbThin({ file })`.
|
|
1096
|
+
*
|
|
1097
|
+
* Call this once at boot, BEFORE the first `session.create` /
|
|
1098
|
+
* `session.verify`. Switching stores on a running app strands every
|
|
1099
|
+
* existing session in the old store.
|
|
1100
|
+
*
|
|
1101
|
+
* @example
|
|
1102
|
+
* var b = require("@blamejs/core");
|
|
1103
|
+
* await b.vault.init({ dataDir: "/var/lib/blamejs", mode: "plaintext" });
|
|
1104
|
+
* await b.db.init({ dataDir: "/var/lib/blamejs" });
|
|
1105
|
+
* var sessionStore = b.session.stores.localDbThin({ file: "/dev/shm/sessions.db" });
|
|
1106
|
+
* b.session.useStore(sessionStore);
|
|
1107
|
+
* // Every b.session.* call now routes through the tmpfs file.
|
|
1108
|
+
*/
|
|
1109
|
+
function useStore(store) {
|
|
1110
|
+
if (store === null || store === undefined) {
|
|
1111
|
+
_store = null;
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
if (typeof store !== "object" ||
|
|
1115
|
+
typeof store.execute !== "function" ||
|
|
1116
|
+
typeof store.executeOne !== "function") {
|
|
1117
|
+
throw _err("INVALID_ARG",
|
|
1118
|
+
"session.useStore: store must expose execute(sql,params) and executeOne(sql,params)", true);
|
|
1119
|
+
}
|
|
1120
|
+
_store = store;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* @primitive b.session.isAnonymous
|
|
1125
|
+
* @signature b.session.isAnonymous(userId)
|
|
1126
|
+
* @since 0.8.62
|
|
1127
|
+
* @status stable
|
|
1128
|
+
* @related b.session.create
|
|
1129
|
+
*
|
|
1130
|
+
* Returns `true` if the supplied userId was minted by
|
|
1131
|
+
* `b.session.create({ anonymous: true })` (i.e., starts with the
|
|
1132
|
+
* `anon:` prefix). Operators use this to gate post-auth behavior
|
|
1133
|
+
* (e.g., refuse a payment confirmation when the session is still
|
|
1134
|
+
* anonymous, or render the "log in to continue" banner).
|
|
1135
|
+
*
|
|
1136
|
+
* @example
|
|
1137
|
+
* var info = await b.session.verify(req.cookies.sid);
|
|
1138
|
+
* if (info && b.session.isAnonymous(info.userId)) {
|
|
1139
|
+
* res.statusCode = 401; res.end("login required"); return;
|
|
1140
|
+
* }
|
|
1141
|
+
*/
|
|
1142
|
+
function isAnonymous(userId) {
|
|
1143
|
+
return _isAnonymousUserId(userId);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
module.exports = {
|
|
1147
|
+
create: create,
|
|
1148
|
+
verify: verify,
|
|
1149
|
+
destroy: destroy,
|
|
1150
|
+
destroyAllForUser: destroyAllForUser,
|
|
1151
|
+
touch: touch,
|
|
1152
|
+
rotate: rotate,
|
|
1153
|
+
updateData: updateData,
|
|
1154
|
+
purgeExpired: purgeExpired,
|
|
1155
|
+
count: count,
|
|
1156
|
+
useStore: useStore,
|
|
1157
|
+
isAnonymous: isAnonymous,
|
|
1158
|
+
stores: require("./session-stores"), // allow:inline-require — session-stores depends on local-db-thin which requires audit lazily; eager require is fine here
|
|
1159
|
+
DEFAULT_TTL_MS: DEFAULT_TTL_MS,
|
|
1160
|
+
ANON_PREFIX: ANON_PREFIX,
|
|
1161
|
+
_resetForTest: _resetForTest,
|
|
1162
|
+
};
|