@blamejs/blamejs-shop 0.5.12 → 0.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/sales-tax-filings.js +143 -0
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- 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 +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
* W3C Server-Timing response header builder — per-request timing-metric collector that surfaces server-side latency in the browser's Performance API.
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
+
var safeBuffer = require("./safe-buffer");
|
|
40
41
|
var validateOpts = require("./validate-opts");
|
|
41
42
|
var { defineClass } = require("./framework-error");
|
|
42
43
|
|
|
@@ -46,9 +47,6 @@ var ServerTimingError = defineClass("ServerTimingError", { alwaysPermanent: true
|
|
|
46
47
|
// at 128 chars for sanity; operator-supplied desc is sf-string.
|
|
47
48
|
var METRIC_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]{1,128}$/; // RFC 7230 token shape + length cap
|
|
48
49
|
|
|
49
|
-
function _quoteDesc(s) {
|
|
50
|
-
return "\"" + String(s).replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\"";
|
|
51
|
-
}
|
|
52
50
|
|
|
53
51
|
/**
|
|
54
52
|
* @primitive b.serverTiming.create
|
|
@@ -120,7 +118,7 @@ function create() {
|
|
|
120
118
|
return entries.map(function (e) {
|
|
121
119
|
var parts = [e.name];
|
|
122
120
|
if (e.dur !== null) parts.push("dur=" + _formatDur(e.dur));
|
|
123
|
-
if (e.desc !== null) parts.push("desc=" +
|
|
121
|
+
if (e.desc !== null) parts.push("desc=" + safeBuffer.quoteString(e.desc));
|
|
124
122
|
return parts.join("; ");
|
|
125
123
|
}).join(", ");
|
|
126
124
|
}
|
|
@@ -488,7 +488,12 @@ async function create(opts) {
|
|
|
488
488
|
* the bound fingerprint — the result carries `fingerprintDrift: true`
|
|
489
489
|
* on mismatch (audit event always fires). `requireFingerprintMatch:
|
|
490
490
|
* true` or a `maxAnomalyScore` threshold (with a `scorer` callback)
|
|
491
|
-
* makes drift refuse the session by returning `null`.
|
|
491
|
+
* makes drift refuse the session by returning `null`. A strict policy
|
|
492
|
+
* also refuses (returns `null`) a session that carries no comparable
|
|
493
|
+
* binding — one created without `{ req }`, or whose sealed binding
|
|
494
|
+
* cannot be decrypted — since the device match cannot be proven; bind
|
|
495
|
+
* every session you intend to verify strictly by passing `{ req }` to
|
|
496
|
+
* `create`.
|
|
492
497
|
*
|
|
493
498
|
* @opts
|
|
494
499
|
* {
|
|
@@ -627,15 +632,24 @@ async function verify(token, verifyOpts) {
|
|
|
627
632
|
// login-from-Tokyo-then-immediately-from-Brazil pattern is not).
|
|
628
633
|
var fingerprintDrift = false;
|
|
629
634
|
var fingerprintAnomalyScore = null;
|
|
630
|
-
// A strict binding policy (requireFingerprintMatch / maxAnomalyScore)
|
|
631
|
-
//
|
|
632
|
-
//
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
635
|
+
// A strict binding policy (requireFingerprintMatch / maxAnomalyScore) is a
|
|
636
|
+
// per-request assertion that this session IS device-bound and the current
|
|
637
|
+
// device matches. It cannot be satisfied when there is no stored fingerprint
|
|
638
|
+
// to compare against — whether the binding is UNREADABLE (the sealed data
|
|
639
|
+
// cell exists but won't decrypt: key-rotation skew / corruption / tamper) or
|
|
640
|
+
// simply ABSENT (the session was created without { req }, so it was never
|
|
641
|
+
// bound). Either way the device match cannot be proven, so fail CLOSED rather
|
|
642
|
+
// than silently skip the gate. Treating "no binding to compare" as "the
|
|
643
|
+
// binding matches" is the fail-open this refuses: it admitted an unbound (or
|
|
644
|
+
// unreadable-binding) session from ANY device even under a strict policy.
|
|
645
|
+
var strictBindingRequested = !!verifyOpts.req &&
|
|
646
|
+
(verifyOpts.requireFingerprintMatch === true ||
|
|
647
|
+
typeof verifyOpts.maxAnomalyScore === "number");
|
|
648
|
+
if (strictBindingRequested && !storedFingerprint) {
|
|
636
649
|
try {
|
|
637
650
|
audit.safeEmit({
|
|
638
|
-
action: "auth.session.binding_unreadable"
|
|
651
|
+
action: bindingUnreadable ? "auth.session.binding_unreadable"
|
|
652
|
+
: "auth.session.binding_missing",
|
|
639
653
|
outcome: "failure",
|
|
640
654
|
metadata: { hasUserId: !!unsealed.userId },
|
|
641
655
|
});
|
|
@@ -681,10 +695,18 @@ async function verify(token, verifyOpts) {
|
|
|
681
695
|
if (verifyOpts.requireFingerprintMatch === true) {
|
|
682
696
|
return null;
|
|
683
697
|
}
|
|
684
|
-
if (typeof verifyOpts.maxAnomalyScore === "number"
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
698
|
+
if (typeof verifyOpts.maxAnomalyScore === "number") {
|
|
699
|
+
// Genuine drift under a declared strict anomaly threshold. Refuse when
|
|
700
|
+
// the computed score exceeds the threshold — AND when no decisive score
|
|
701
|
+
// could be produced (no scorer supplied, or the scorer threw / returned
|
|
702
|
+
// a non-finite value, leaving fingerprintAnomalyScore null). An
|
|
703
|
+
// uncomputable anomaly score on real drift must FAIL CLOSED, not be
|
|
704
|
+
// treated as "below threshold" and silently admit a relocated device.
|
|
705
|
+
// Same fail-closed discipline the unreadable-binding branch above applies.
|
|
706
|
+
if (fingerprintAnomalyScore === null ||
|
|
707
|
+
fingerprintAnomalyScore > verifyOpts.maxAnomalyScore) {
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
688
710
|
}
|
|
689
711
|
}
|
|
690
712
|
}
|
|
@@ -1760,7 +1760,21 @@ class SelectBuilder extends Builder {
|
|
|
1760
1760
|
if (h.sql) { sql += " HAVING " + h.sql; for (var hi = 0; hi < h.params.length; hi++) params.push(h.params[hi]); }
|
|
1761
1761
|
|
|
1762
1762
|
if (this._orderBy.length > 0) sql += " ORDER BY " + this._orderBy.join(", ");
|
|
1763
|
-
|
|
1763
|
+
// OFFSET without LIMIT is valid only on Postgres; SQLite and MySQL both
|
|
1764
|
+
// reject a bare OFFSET as a syntax error (there is no bare-OFFSET spelling
|
|
1765
|
+
// for "skip N, return the rest" on those backends). Emit the dialect's
|
|
1766
|
+
// unbounded-limit sentinel so one query text runs unchanged across all
|
|
1767
|
+
// three: SQLite `LIMIT -1`, MySQL the max unsigned BIGINT, Postgres
|
|
1768
|
+
// `LIMIT ALL`. When a real LIMIT is set the existing token is emitted
|
|
1769
|
+
// untouched, so limit-present statements are byte-for-byte unchanged.
|
|
1770
|
+
var limitToken = null;
|
|
1771
|
+
if (this._limit !== null) {
|
|
1772
|
+
limitToken = String(this._limit);
|
|
1773
|
+
} else if (this._offset !== null) {
|
|
1774
|
+
limitToken = dialect === "sqlite" ? "-1"
|
|
1775
|
+
: (dialect === "mysql" ? "18446744073709551615" : "ALL");
|
|
1776
|
+
}
|
|
1777
|
+
if (limitToken !== null) sql += " LIMIT " + limitToken;
|
|
1764
1778
|
if (this._offset !== null) sql += " OFFSET " + this._offset;
|
|
1765
1779
|
|
|
1766
1780
|
if (this._lockMode !== null) {
|
|
@@ -820,6 +820,56 @@ function isPrivate(ip) { return classify(ip) === "private"; }
|
|
|
820
820
|
*/
|
|
821
821
|
function isLoopback(ip) { return classify(ip) === "loopback"; }
|
|
822
822
|
|
|
823
|
+
/**
|
|
824
|
+
* @primitive b.ssrfGuard.isLoopbackHost
|
|
825
|
+
* @signature b.ssrfGuard.isLoopbackHost(host)
|
|
826
|
+
* @since 0.17.13
|
|
827
|
+
* @status stable
|
|
828
|
+
* @related b.ssrfGuard.isExactLoopbackName, b.ssrfGuard.isLoopback, b.ssrfGuard.canonicalizeHost
|
|
829
|
+
*
|
|
830
|
+
* Hostname-aware loopback test. Unlike `isLoopback` (IP literals only) this
|
|
831
|
+
* canonicalizes `host` (strips `[]` brackets + trailing dots, folds an
|
|
832
|
+
* IPv4-mapped IPv6, lowercases) and returns `true` for a loopback IP literal
|
|
833
|
+
* OR the RFC 6761 §6.3 reserved names `localhost` and any `*.localhost`. Pure
|
|
834
|
+
* name-shape — never resolves DNS.
|
|
835
|
+
*
|
|
836
|
+
* @example
|
|
837
|
+
* b.ssrfGuard.isLoopbackHost("localhost"); // → true
|
|
838
|
+
* b.ssrfGuard.isLoopbackHost("[::1]"); // → true
|
|
839
|
+
* b.ssrfGuard.isLoopbackHost("app.localhost"); // → true
|
|
840
|
+
* b.ssrfGuard.isLoopbackHost("example.com"); // → false
|
|
841
|
+
*/
|
|
842
|
+
function isLoopbackHost(host) {
|
|
843
|
+
if (typeof host !== "string" || host.length === 0) return false;
|
|
844
|
+
var canon = canonicalizeHost(host);
|
|
845
|
+
if (net.isIP(canon)) return classify(canon) === "loopback";
|
|
846
|
+
return canon === "localhost" || /\.localhost$/.test(canon);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* @primitive b.ssrfGuard.isExactLoopbackName
|
|
851
|
+
* @signature b.ssrfGuard.isExactLoopbackName(host)
|
|
852
|
+
* @since 0.17.13
|
|
853
|
+
* @status stable
|
|
854
|
+
* @related b.ssrfGuard.isLoopbackHost
|
|
855
|
+
*
|
|
856
|
+
* Like `isLoopbackHost` but WITHOUT the `*.localhost` subdomain reservation —
|
|
857
|
+
* accepts only the exact `localhost` name or a loopback IP literal. For the
|
|
858
|
+
* OAuth/OIDC cleartext-redirect loopback exception (RFC 9700 §4.1.1), which
|
|
859
|
+
* must not widen to a `*.localhost` name an attacker could register in a resolver.
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* b.ssrfGuard.isExactLoopbackName("localhost"); // → true
|
|
863
|
+
* b.ssrfGuard.isExactLoopbackName("127.0.0.1"); // → true
|
|
864
|
+
* b.ssrfGuard.isExactLoopbackName("app.localhost"); // → false
|
|
865
|
+
*/
|
|
866
|
+
function isExactLoopbackName(host) {
|
|
867
|
+
if (typeof host !== "string" || host.length === 0) return false;
|
|
868
|
+
var canon = canonicalizeHost(host);
|
|
869
|
+
if (net.isIP(canon)) return classify(canon) === "loopback";
|
|
870
|
+
return canon === "localhost";
|
|
871
|
+
}
|
|
872
|
+
|
|
823
873
|
/**
|
|
824
874
|
* @primitive b.ssrfGuard.isLinkLocal
|
|
825
875
|
* @signature b.ssrfGuard.isLinkLocal(ip)
|
|
@@ -958,6 +1008,8 @@ module.exports = {
|
|
|
958
1008
|
createAllowlist: createAllowlist,
|
|
959
1009
|
isPrivate: isPrivate,
|
|
960
1010
|
isLoopback: isLoopback,
|
|
1011
|
+
isLoopbackHost: isLoopbackHost,
|
|
1012
|
+
isExactLoopbackName: isExactLoopbackName,
|
|
961
1013
|
isLinkLocal: isLinkLocal,
|
|
962
1014
|
isCloudMetadata: isCloudMetadata,
|
|
963
1015
|
isReserved: isReserved,
|
|
@@ -50,6 +50,7 @@ var gateContract = require("./gate-contract");
|
|
|
50
50
|
var lazyRequire = require("./lazy-require");
|
|
51
51
|
var numericBounds = require("./numeric-bounds");
|
|
52
52
|
var requestHelpers = require("./request-helpers");
|
|
53
|
+
var safePath = require("./safe-path");
|
|
53
54
|
var validateOpts = require("./validate-opts");
|
|
54
55
|
var { StaticServeError } = require("./framework-error");
|
|
55
56
|
|
|
@@ -205,11 +206,10 @@ function _assertInsideRoot(root, candidate) {
|
|
|
205
206
|
rel.indexOf(".." + nodePath.sep) !== -1 ||
|
|
206
207
|
rel.indexOf(".." + (nodePath.sep === "/" ? "\\" : "/")) !== -1 ||
|
|
207
208
|
nodePath.isAbsolute(rel)) return null;
|
|
208
|
-
|
|
209
|
-
//
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return safe;
|
|
209
|
+
// Final lexical containment via the shared traversal-containment primitive
|
|
210
|
+
// (cross-platform-aware resolve + strict base-prefix check). rel is already
|
|
211
|
+
// `..`-stripped and relative above, so this confines to root or returns null.
|
|
212
|
+
return safePath.confineToBase(rootResolved, rel);
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
// Module-level metadata cache. Entries hold:
|
|
@@ -274,6 +274,24 @@ async function _readMeta(root, candidate) {
|
|
|
274
274
|
return entry;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
// _integrityHeadersForBytes — recompute the strong ETag + SRI integrity for
|
|
278
|
+
// an in-memory buffer, mirroring the digest shape `_readMeta` derives from a
|
|
279
|
+
// file on disk (SHA3-512-truncated ETag for the PQC posture, SHA-384 SRI for
|
|
280
|
+
// the W3C subresource-integrity spec). Used on the content-safety SANITIZE
|
|
281
|
+
// path: the meta cache holds digests of the on-disk ORIGINAL, but the gate
|
|
282
|
+
// replaces the served bytes, so the validators the response advertises must be
|
|
283
|
+
// computed over the bytes actually delivered — otherwise SRI verification of
|
|
284
|
+
// the served body fails and a strong-validator / If-None-Match cache is keyed
|
|
285
|
+
// to a representation the client never receives.
|
|
286
|
+
function _integrityHeadersForBytes(buf) {
|
|
287
|
+
var sha3Hex = nodeCrypto.createHash("sha3-512").update(buf).digest("hex");
|
|
288
|
+
var sriDigest = nodeCrypto.createHash("sha384").update(buf).digest("base64");
|
|
289
|
+
return {
|
|
290
|
+
etag: '"' + sha3Hex.slice(0, ETAG_HEX_PREFIX) + '"',
|
|
291
|
+
integrity: "sha384-" + sriDigest,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
277
295
|
function _resolveSafe(root, requestedPath) {
|
|
278
296
|
if (typeof requestedPath !== "string" || requestedPath.length === 0) return null;
|
|
279
297
|
if (requestedPath.indexOf("\0") !== -1) return null;
|
|
@@ -845,7 +863,11 @@ function create(opts) {
|
|
|
845
863
|
var auditSuccess = cfg.auditSuccess;
|
|
846
864
|
var auditFailures = cfg.auditFailures;
|
|
847
865
|
var acceptRanges = cfg.acceptRanges;
|
|
848
|
-
|
|
866
|
+
// Read straight from opts: safeAttachmentForRiskyMimes is not a DEFAULTS
|
|
867
|
+
// key, so applyDefaults(opts, DEFAULTS) never carries it into cfg — reading
|
|
868
|
+
// it off cfg silently dropped the opt and left the drive-by-execution
|
|
869
|
+
// defense (Content-Disposition: attachment for risky inline MIMEs) inert.
|
|
870
|
+
var safeAttachment = !!opts.safeAttachmentForRiskyMimes;
|
|
849
871
|
// forceAttachmentForNonText default follows mountType (v0.15.0): a
|
|
850
872
|
// mount TYPED "user-content" forces risky inline MIMEs to download by
|
|
851
873
|
// default (stored-XSS defense for untrusted uploads); a "curated" mount
|
|
@@ -1180,15 +1202,26 @@ function create(opts) {
|
|
|
1180
1202
|
|
|
1181
1203
|
var cacheControl = _cacheControlFor(urlPath);
|
|
1182
1204
|
|
|
1205
|
+
// The validators the response advertises must describe the bytes ACTUALLY
|
|
1206
|
+
// delivered. On the content-safety SANITIZE path the gate replaced the
|
|
1207
|
+
// bytes, so the strong ETag + SRI X-Integrity are recomputed over the
|
|
1208
|
+
// override buffer rather than reused from the meta cache (which hashed the
|
|
1209
|
+
// on-disk original). The conditional-request checks below compare against
|
|
1210
|
+
// this same effective ETag so a strong-validator / If-None-Match cache
|
|
1211
|
+
// revalidates against the representation it was actually served.
|
|
1212
|
+
var served = gateBytesOverride
|
|
1213
|
+
? _integrityHeadersForBytes(gateBytesOverride)
|
|
1214
|
+
: { etag: meta.etag, integrity: meta.integrity };
|
|
1215
|
+
|
|
1183
1216
|
var headersIn = req.headers || {};
|
|
1184
1217
|
|
|
1185
1218
|
// Conditional: If-None-Match (304)
|
|
1186
1219
|
var ifNone = headersIn["if-none-match"];
|
|
1187
|
-
if (ifNone && ifNone ===
|
|
1220
|
+
if (ifNone && ifNone === served.etag) {
|
|
1188
1221
|
stats.etagHits += 1;
|
|
1189
1222
|
_emitObs("staticServe.etag_hits", 1, { route: urlPath });
|
|
1190
1223
|
res.writeHead(HTTP.NOT_MODIFIED, {
|
|
1191
|
-
"ETag":
|
|
1224
|
+
"ETag": served.etag,
|
|
1192
1225
|
"Cache-Control": cacheControl,
|
|
1193
1226
|
"Last-Modified": meta.lastModified,
|
|
1194
1227
|
});
|
|
@@ -1197,7 +1230,7 @@ function create(opts) {
|
|
|
1197
1230
|
|
|
1198
1231
|
// Conditional: If-Match (412 if no match — strong validator only)
|
|
1199
1232
|
var ifMatch = headersIn["if-match"];
|
|
1200
|
-
if (ifMatch && ifMatch !== "*" && ifMatch !==
|
|
1233
|
+
if (ifMatch && ifMatch !== "*" && ifMatch !== served.etag) {
|
|
1201
1234
|
stats.failures += 1;
|
|
1202
1235
|
_emitObs("staticServe.precondition_failed", 1, { route: urlPath, header: "if-match" });
|
|
1203
1236
|
return writeErr(res, HTTP.PRECONDITION_FAILED || 412,
|
|
@@ -1215,7 +1248,7 @@ function create(opts) {
|
|
|
1215
1248
|
stats.etagHits += 1;
|
|
1216
1249
|
_emitObs("staticServe.if_modified_since_hits", 1, { route: urlPath });
|
|
1217
1250
|
res.writeHead(HTTP.NOT_MODIFIED, {
|
|
1218
|
-
"ETag":
|
|
1251
|
+
"ETag": served.etag,
|
|
1219
1252
|
"Cache-Control": cacheControl,
|
|
1220
1253
|
"Last-Modified": meta.lastModified,
|
|
1221
1254
|
});
|
|
@@ -1305,10 +1338,10 @@ function create(opts) {
|
|
|
1305
1338
|
var headers = {
|
|
1306
1339
|
"Content-Type": _contentTypeFor(absPath, contentTypes),
|
|
1307
1340
|
"Content-Length": sendBytes,
|
|
1308
|
-
"ETag":
|
|
1341
|
+
"ETag": served.etag,
|
|
1309
1342
|
"Cache-Control": cacheControl,
|
|
1310
1343
|
"Last-Modified": meta.lastModified,
|
|
1311
|
-
"X-Integrity":
|
|
1344
|
+
"X-Integrity": served.integrity,
|
|
1312
1345
|
};
|
|
1313
1346
|
// Drive-by-execution defense — when safeAttachmentForRiskyMimes is
|
|
1314
1347
|
// on, force Content-Disposition: attachment for HTML / JS / SVG /
|
|
@@ -1358,6 +1391,15 @@ function create(opts) {
|
|
|
1358
1391
|
}
|
|
1359
1392
|
|
|
1360
1393
|
if (req.method === "HEAD") {
|
|
1394
|
+
// A sanitized resource is delivered as the override buffer on GET, so a
|
|
1395
|
+
// HEAD must advertise that same length (and drop Content-Range) — the
|
|
1396
|
+
// meta-cache size describes the on-disk original the client never gets.
|
|
1397
|
+
var headSize = gateBytesOverride ? gateBytesOverride.length : meta.size;
|
|
1398
|
+
if (gateBytesOverride) {
|
|
1399
|
+
headers = Object.assign({}, headers, { "Content-Length": headSize });
|
|
1400
|
+
delete headers["Content-Range"];
|
|
1401
|
+
status = HTTP.OK;
|
|
1402
|
+
}
|
|
1361
1403
|
res.writeHead(status, headers);
|
|
1362
1404
|
res.end();
|
|
1363
1405
|
stats.requestsServed += 1;
|
|
@@ -1365,7 +1407,7 @@ function create(opts) {
|
|
|
1365
1407
|
if (auditSuccess) {
|
|
1366
1408
|
emitAudit("staticServe.serve.success", Object.assign({
|
|
1367
1409
|
outcome: "success", resource: urlPath, method: "HEAD",
|
|
1368
|
-
size:
|
|
1410
|
+
size: headSize, contentType: headers["Content-Type"],
|
|
1369
1411
|
}, actorCtx));
|
|
1370
1412
|
}
|
|
1371
1413
|
return;
|
|
@@ -162,9 +162,15 @@ function _normalizeConfig(opts) {
|
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
164
|
if (opts.backend === "http-put" || opts.backend === "sigv4" || opts.backend === "gcs" || opts.backend === "azure-blob") {
|
|
165
|
-
// Forward
|
|
165
|
+
// Forward the single-backend spec, translating the `backend` shorthand
|
|
166
|
+
// into the `protocol` key the object-store adapter builds against — the
|
|
167
|
+
// local branch above already spells it `protocol`, and buildBackend keys
|
|
168
|
+
// off `protocol`, so forwarding `backend` verbatim left the default
|
|
169
|
+
// backend without a protocol and failed to build.
|
|
170
|
+
var remoteCfg = Object.assign({}, opts, { protocol: opts.backend, name: undefined });
|
|
171
|
+
delete remoteCfg.backend;
|
|
166
172
|
return {
|
|
167
|
-
backends: { "default":
|
|
173
|
+
backends: { "default": remoteCfg },
|
|
168
174
|
defaultClassification: null,
|
|
169
175
|
refuseUnclassified: false,
|
|
170
176
|
};
|
|
@@ -133,7 +133,12 @@ function exportData(subjectId, opts) {
|
|
|
133
133
|
|
|
134
134
|
var tables = db()._getSubjectTables();
|
|
135
135
|
if (tables.length === 0) {
|
|
136
|
-
|
|
136
|
+
// No subjectField-tagged tables: still audit, but return the documented
|
|
137
|
+
// empty dump ({}) — _writeAudit returns undefined, so returning its value
|
|
138
|
+
// (with a vestigial 5th arg) silently handed callers `undefined`, crashing
|
|
139
|
+
// `Object.keys(dump)` / `dump.<table>` before any table is even declared.
|
|
140
|
+
_writeAudit("subject.export", subjectId, "success", { reason: opts.reason || null });
|
|
141
|
+
return {};
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
var dump = {};
|
|
@@ -55,12 +55,14 @@
|
|
|
55
55
|
var C = require("./constants");
|
|
56
56
|
var lazyRequire = require("./lazy-require");
|
|
57
57
|
var boundedMap = require("./bounded-map");
|
|
58
|
+
var sql = require("./sql");
|
|
58
59
|
var validateOpts = require("./validate-opts");
|
|
59
60
|
var { defineClass } = require("./framework-error");
|
|
60
61
|
|
|
61
62
|
var TenantQuotaError = defineClass("TenantQuotaError", { alwaysPermanent: true });
|
|
62
63
|
|
|
63
64
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
65
|
+
var cryptoField = lazyRequire(function () { return require("./crypto-field"); });
|
|
64
66
|
var observability = lazyRequire(function () { return require("./observability"); });
|
|
65
67
|
|
|
66
68
|
var DEFAULT_CACHE_TTL_MS = C.TIME.seconds(30);
|
|
@@ -115,6 +117,7 @@ function create(opts) {
|
|
|
115
117
|
], "tenantQuota.create");
|
|
116
118
|
|
|
117
119
|
if (!opts.db || typeof opts.db.from !== "function" ||
|
|
120
|
+
typeof opts.db.prepare !== "function" ||
|
|
118
121
|
typeof opts.db.getTableMetadata !== "function") {
|
|
119
122
|
throw new TenantQuotaError("tenant-quota/bad-db",
|
|
120
123
|
"tenantQuota.create: opts.db must be the framework's b.db namespace");
|
|
@@ -197,25 +200,61 @@ function create(opts) {
|
|
|
197
200
|
var tables = _resolveTables();
|
|
198
201
|
var total = 0;
|
|
199
202
|
for (var i = 0; i < tables.length; i++) {
|
|
200
|
-
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
var table = tables[i];
|
|
204
|
+
// Resolve the tenant predicate. When tenantField is itself a SEALED
|
|
205
|
+
// column, the plaintext tenantId never equals the on-disk vault
|
|
206
|
+
// envelope, so the framework filters it by its derived-hash blind index.
|
|
207
|
+
// Reuse cryptoField.lookupHash — the same rewrite db.from().where()
|
|
208
|
+
// applies — so a sealed tenantField resolves correctly (including the
|
|
209
|
+
// legacy dual-read across the keyed-MAC flip). A plaintext tenantField
|
|
210
|
+
// compares directly. Without this, a schema that seals the tenant id
|
|
211
|
+
// matches zero rows and the cap silently never fires.
|
|
212
|
+
var whereField = tenantField;
|
|
213
|
+
var whereVals = [tenantId];
|
|
214
|
+
var sealed = cryptoField().getSealedFields(table) || [];
|
|
215
|
+
if (sealed.indexOf(tenantField) !== -1) {
|
|
216
|
+
var lk = cryptoField().lookupHash(table, tenantField, tenantId);
|
|
217
|
+
if (!lk) {
|
|
218
|
+
throw new TenantQuotaError("tenant-quota/sealed-tenant-no-hash",
|
|
219
|
+
"tenantQuota: tenantField '" + tenantField + "' on table '" + table +
|
|
220
|
+
"' is a sealed column without a derived hash; declare " +
|
|
221
|
+
"derivedHashes: { <name>: { from: '" + tenantField + "' } } so it can be queried");
|
|
222
|
+
}
|
|
223
|
+
whereField = lk.field;
|
|
224
|
+
whereVals = (lk.legacyValue != null && lk.legacyValue !== lk.value)
|
|
225
|
+
? [lk.value, lk.legacyValue]
|
|
226
|
+
: [lk.value];
|
|
227
|
+
}
|
|
228
|
+
// Build the read with b.sql — the same builder db.from() uses — so the
|
|
229
|
+
// table and column identifiers get identical handling (schema-qualified
|
|
230
|
+
// "schema.table" names, reserved-word names, dialect quoting) without
|
|
231
|
+
// re-implementing any of it here. Run it raw via db.prepare and, unlike
|
|
232
|
+
// db.from().all(), do NOT route rows through cryptoField.unsealRow: a
|
|
233
|
+
// storage cap must count what is actually on disk — the (much larger)
|
|
234
|
+
// vault envelope of a sealed column, not the plaintext it unseals to —
|
|
235
|
+
// or a tenant whose data lives in sealed columns sails under the cap.
|
|
236
|
+
// The tenant value(s) are bound parameters.
|
|
237
|
+
var built = sql.select(table, { dialect: "sqlite", quoteName: true })
|
|
238
|
+
.whereIn(whereField, whereVals)
|
|
239
|
+
.toSql();
|
|
240
|
+
var stmt = db.prepare(built.sql);
|
|
241
|
+
var rows = stmt.all.apply(stmt, built.params);
|
|
211
242
|
for (var r = 0; r < rows.length; r++) {
|
|
212
243
|
var row = rows[r];
|
|
213
244
|
var keys = Object.keys(row);
|
|
214
245
|
for (var k = 0; k < keys.length; k++) {
|
|
215
246
|
var v = row[keys[k]];
|
|
216
247
|
if (v == null) continue;
|
|
217
|
-
|
|
218
|
-
|
|
248
|
+
// BLOB columns round-trip as a typed-array view (node:sqlite hands
|
|
249
|
+
// them back as Uint8Array, not a Node Buffer), so count the true
|
|
250
|
+
// byte length off any ArrayBuffer view rather than stringifying it
|
|
251
|
+
// — String(Uint8Array) is the decimal-joined bytes, a ~3x overcount
|
|
252
|
+
// that would refuse inserts well below the real storage cap. Text
|
|
253
|
+
// (including a sealed column's "vault:" envelope) is counted as its
|
|
254
|
+
// UTF-8 byte length, not the JS string .length — a multi-byte
|
|
255
|
+
// character occupies more than one byte on disk.
|
|
256
|
+
if (ArrayBuffer.isView(v)) total += v.byteLength;
|
|
257
|
+
else total += Buffer.byteLength(String(v), "utf8");
|
|
219
258
|
}
|
|
220
259
|
}
|
|
221
260
|
}
|
|
@@ -106,7 +106,7 @@ function _resolveTlsSocket(socketOrReq) {
|
|
|
106
106
|
* }
|
|
107
107
|
*
|
|
108
108
|
* @example
|
|
109
|
-
* var b = require("blamejs")
|
|
109
|
+
* var b = require("blamejs");
|
|
110
110
|
* var server = b.https.createServer({ key: KEY, cert: CERT }, function (req, res) {
|
|
111
111
|
* var exporter = b.tlsExporter.fromSocket(req, { length: 32 });
|
|
112
112
|
* res.end("exporter bytes: " + exporter.length);
|
|
@@ -175,7 +175,7 @@ function fromSocket(socketOrReq, opts) {
|
|
|
175
175
|
* compare via `verifyTokenBinding` on the next request.
|
|
176
176
|
*
|
|
177
177
|
* @example
|
|
178
|
-
* var b = require("blamejs")
|
|
178
|
+
* var b = require("blamejs");
|
|
179
179
|
* b.https.createServer({ key: KEY, cert: CERT }, function (req, res) {
|
|
180
180
|
* var binding = b.tlsExporter.bindToken(req, "session-token-abc123");
|
|
181
181
|
* binding.length;
|
|
@@ -214,7 +214,7 @@ function bindToken(socketOrReq, token) {
|
|
|
214
214
|
* the input shape is wrong.
|
|
215
215
|
*
|
|
216
216
|
* @example
|
|
217
|
-
* var b = require("blamejs")
|
|
217
|
+
* var b = require("blamejs");
|
|
218
218
|
* b.https.createServer({ key: KEY, cert: CERT }, function (req, res) {
|
|
219
219
|
* var stored = b.tlsExporter.bindToken(req, "session-token-abc123");
|
|
220
220
|
* var ok = b.tlsExporter.verifyTokenBinding(req, "session-token-abc123", stored);
|
|
@@ -122,11 +122,11 @@ function _normHex(h) {
|
|
|
122
122
|
// Resolve the message imprint: hash the data, or use a pre-computed hash.
|
|
123
123
|
function _imprint(data, opts, fnName) {
|
|
124
124
|
var hashName = opts.hashAlg || "SHA-512";
|
|
125
|
-
|
|
126
|
-
if (!h) {
|
|
125
|
+
if (!Object.prototype.hasOwnProperty.call(IMPRINT_HASHES, hashName)) {
|
|
127
126
|
throw new TsaError("tsa/bad-hash-alg",
|
|
128
127
|
fnName + ": hashAlg must be one of " + Object.keys(IMPRINT_HASHES).join(" / "));
|
|
129
128
|
}
|
|
129
|
+
var h = IMPRINT_HASHES[hashName];
|
|
130
130
|
var digest;
|
|
131
131
|
if (opts.hashed) {
|
|
132
132
|
digest = _bytes(data, "hash");
|
|
@@ -567,9 +567,13 @@ function _assertValidAt(cert, atMs) {
|
|
|
567
567
|
* <code>id-ct-TSTInfo</code>, the message imprint equals the hash of
|
|
568
568
|
* <code>opts.data</code> (or <code>opts.hash</code>), a sent nonce
|
|
569
569
|
* round-trips, the signer cert's extendedKeyUsage is a critical, sole
|
|
570
|
-
* <code>id-kp-timeStamping</code>, and the CMS signature verifies.
|
|
571
|
-
*
|
|
572
|
-
*
|
|
570
|
+
* <code>id-kp-timeStamping</code>, and the CMS signature verifies. The
|
|
571
|
+
* signer certificate is embedded in the token (and therefore
|
|
572
|
+
* attacker-controlled), so <code>opts.trustAnchorsPem</code> is
|
|
573
|
+
* <strong>required by default</strong> — without it a self-signed token
|
|
574
|
+
* would pass on its self-contained signature alone. To accept an
|
|
575
|
+
* unauthenticated timestamp, set <code>opts.allowUntrustedIssuer:true</code>;
|
|
576
|
+
* the result then carries <code>issuerTrusted:false</code>.
|
|
573
577
|
*
|
|
574
578
|
* @opts
|
|
575
579
|
* {
|
|
@@ -577,17 +581,18 @@ function _assertValidAt(cert, atMs) {
|
|
|
577
581
|
* hash: Buffer, // OR a pre-computed digest (with hashAlg)
|
|
578
582
|
* hashAlg: string, // default "SHA-512" — must match the imprint
|
|
579
583
|
* nonce: Buffer, // require the token nonce to match (from buildRequest)
|
|
580
|
-
* trustAnchorsPem: string|string[], // PEM root(s)
|
|
584
|
+
* trustAnchorsPem: string|string[], // PEM trust root(s) to authenticate the TSA — REQUIRED unless allowUntrustedIssuer
|
|
585
|
+
* allowUntrustedIssuer: boolean, // accept a token with no trust anchor (result carries issuerTrusted:false)
|
|
581
586
|
* at: Date, // validity instant for chain check (default: genTime); must be a valid Date
|
|
582
587
|
* }
|
|
583
588
|
*
|
|
584
589
|
* @example
|
|
585
|
-
* var out = b.tsa.verifyToken(resp.token, { data: tarball, hashAlg: "SHA-512", nonce: req.nonce });
|
|
586
|
-
* // → { genTime, policy, serialHex, accuracy, hashAlg, signerCertPem }
|
|
590
|
+
* var out = b.tsa.verifyToken(resp.token, { data: tarball, hashAlg: "SHA-512", nonce: req.nonce, trustAnchorsPem: caPem });
|
|
591
|
+
* // → { genTime, policy, serialHex, accuracy, hashAlg, signerCertPem, issuerTrusted: true }
|
|
587
592
|
*/
|
|
588
593
|
function verifyToken(token, opts) {
|
|
589
594
|
validateOpts.requireObject(opts, "tsa.verifyToken", TsaError);
|
|
590
|
-
validateOpts(opts, ["data", "hash", "hashAlg", "nonce", "trustAnchorsPem", "at"], "tsa.verifyToken");
|
|
595
|
+
validateOpts(opts, ["data", "hash", "hashAlg", "nonce", "trustAnchorsPem", "allowUntrustedIssuer", "at"], "tsa.verifyToken");
|
|
591
596
|
if (opts.data == null && opts.hash == null) {
|
|
592
597
|
throw new TsaError("tsa/no-data", "tsa.verifyToken: pass opts.data or opts.hash to bind the token");
|
|
593
598
|
}
|
|
@@ -654,10 +659,25 @@ function verifyToken(token, opts) {
|
|
|
654
659
|
"tsa.verifyToken: no certificate in the token both carries the timestamping EKU and verifies the signature");
|
|
655
660
|
}
|
|
656
661
|
|
|
657
|
-
// (7)
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
|
|
662
|
+
// (7) Trust anchors REQUIRED by default. The signer certificate is embedded
|
|
663
|
+
// in the token (sd.certificates) and attacker-controlled, so verifying only
|
|
664
|
+
// the self-contained CMS signature + the timestamping EKU proves the token is
|
|
665
|
+
// self-consistent — a forged timestamp (attacker keypair, self-signed leaf
|
|
666
|
+
// with the timeStamping EKU) passes unless the chain is anchored to a
|
|
667
|
+
// configured trust root (RFC 3161 §2.4.2). Require trustAnchorsPem by default;
|
|
668
|
+
// an operator who genuinely wants trust-anchor-free verification must opt in
|
|
669
|
+
// EXPLICITLY (and gets issuerTrusted:false so the unauthenticated posture is
|
|
670
|
+
// visible). Mirrors b.mdoc.verifyIssuerSigned; fail closed.
|
|
671
|
+
var issuerTrusted = opts.trustAnchorsPem !== undefined && opts.trustAnchorsPem !== null;
|
|
672
|
+
if (!issuerTrusted && opts.allowUntrustedIssuer !== true) {
|
|
673
|
+
throw new TsaError("tsa/trust-anchors-required",
|
|
674
|
+
"tsa.verifyToken: opts.trustAnchorsPem is required to authenticate the timestamping TSA " +
|
|
675
|
+
"(the signer certificate is embedded in the token and attacker-controlled); pass trustAnchorsPem, " +
|
|
676
|
+
"or set allowUntrustedIssuer:true to explicitly accept an unauthenticated timestamp (issuerTrusted:false)");
|
|
677
|
+
}
|
|
678
|
+
// Accept a single PEM string or an array — never silently skip chain
|
|
679
|
+
// verification when the caller supplied an anchor in an unexpected shape.
|
|
680
|
+
if (issuerTrusted) {
|
|
661
681
|
var anchors = typeof opts.trustAnchorsPem === "string" ? [opts.trustAnchorsPem] : opts.trustAnchorsPem;
|
|
662
682
|
if (!Array.isArray(anchors) || anchors.length === 0 ||
|
|
663
683
|
!anchors.every(function (a) { return typeof a === "string" && a.length > 0; })) {
|
|
@@ -678,6 +698,7 @@ function verifyToken(token, opts) {
|
|
|
678
698
|
accuracy: tst.accuracy,
|
|
679
699
|
hashAlg: imp.hashName,
|
|
680
700
|
signerCertPem: new nodeCrypto.X509Certificate(signerCertDer).toString(),
|
|
701
|
+
issuerTrusted: issuerTrusted,
|
|
681
702
|
};
|
|
682
703
|
}
|
|
683
704
|
|
|
@@ -159,7 +159,14 @@ function _expandExpr(expr, vars) {
|
|
|
159
159
|
var o = OPERATORS[expr.op];
|
|
160
160
|
var pieces = [];
|
|
161
161
|
expr.specs.forEach(function (spec) {
|
|
162
|
-
|
|
162
|
+
// Own-property only: a varspec name is parse-derived from the template, so
|
|
163
|
+
// it can be `constructor` / `toString` / `__proto__` / any prototype-
|
|
164
|
+
// polluted key. A bare `vars[spec.name]` would read the INHERITED member
|
|
165
|
+
// and expand a function source (or a planted prototype value) into the URI.
|
|
166
|
+
// RFC 6570 §3.2.1 treats an undefined variable as omitted, so an inherited
|
|
167
|
+
// name must be undefined here — never a prototype-chain read.
|
|
168
|
+
var value = Object.prototype.hasOwnProperty.call(vars, spec.name)
|
|
169
|
+
? vars[spec.name] : undefined;
|
|
163
170
|
if (!_isDefined(value)) return;
|
|
164
171
|
|
|
165
172
|
if (typeof value !== "object") {
|
|
@@ -193,6 +193,19 @@ function _readOrCreateDerivedHashMacKey() {
|
|
|
193
193
|
}
|
|
194
194
|
if (nodeFs.existsSync(paths.derivedHashMacKey)) {
|
|
195
195
|
var sealed = atomicFile.readSync(paths.derivedHashMacKey, { encoding: "utf8" }).trim();
|
|
196
|
+
// A genuine MAC key file is a vault-sealed value (seal() always emits
|
|
197
|
+
// the VAULT_PREFIX). unseal() returns a NON-prefixed value VERBATIM
|
|
198
|
+
// (idempotent read passthrough), so without this load-bearing prefix
|
|
199
|
+
// check a plaintext (or otherwise-unsealed) file substituted on disk
|
|
200
|
+
// would be accepted as the secret MAC key — defeating the sealed-at-
|
|
201
|
+
// rest guarantee a disk-write-only attacker (no vault passphrase, so
|
|
202
|
+
// unable to forge a genuine seal) otherwise cannot bypass (CWE-345).
|
|
203
|
+
// Same load-bearing prefix check db.js applies to db.key.enc.
|
|
204
|
+
if (sealed.indexOf(VAULT_PREFIX) !== 0) {
|
|
205
|
+
throw new VaultError("vault/derived-hash-mac-key-corrupted",
|
|
206
|
+
"vault.derived-hash-mac.sealed is not a sealed value (missing '" +
|
|
207
|
+
VAULT_PREFIX + "' prefix) — refusing to accept it as the MAC key");
|
|
208
|
+
}
|
|
196
209
|
var b64 = unseal(sealed);
|
|
197
210
|
var key = Buffer.from(b64, "base64");
|
|
198
211
|
if (key.length !== 32) { // 32-byte (256-bit) MAC key
|