@blamejs/blamejs-shop 0.5.12 → 0.5.13
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 +2 -0
- package/lib/asset-manifest.json +1 -1
- 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
|
@@ -211,6 +211,48 @@ function _validateLabelValue(value) {
|
|
|
211
211
|
return coerced;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
// Redact every value of a free-form label map through the credential
|
|
215
|
+
// scrubber. Exemplar labels (trace_id / span_id, or any operator-supplied
|
|
216
|
+
// pair passed to histogram.observe) are rendered verbatim into the
|
|
217
|
+
// OpenMetrics exposition — the SAME scrape surface regular labels reach — so
|
|
218
|
+
// they get the same scrub. Redacting at STORE time mirrors how _resolveLabels
|
|
219
|
+
// scrubs regular labels before they land in entry.labels, keeping
|
|
220
|
+
// _renderFamilyLines a verbatim renderer for every exposition path that shares
|
|
221
|
+
// it (CWE-532).
|
|
222
|
+
function _redactLabelMap(labelObj) {
|
|
223
|
+
var out = {};
|
|
224
|
+
if (!labelObj || typeof labelObj !== "object") return out;
|
|
225
|
+
var keys = Object.keys(labelObj);
|
|
226
|
+
for (var i = 0; i < keys.length; i++) {
|
|
227
|
+
var k = keys[i];
|
|
228
|
+
// Exemplar label NAMES are rendered verbatim into the OpenMetrics
|
|
229
|
+
// exposition by _renderLabels — and a label name (unlike a value) cannot
|
|
230
|
+
// be quoted or escaped in the Prometheus wire format. Regular label keys
|
|
231
|
+
// are gated (LABEL_NAME_RE at registration + _resolveLabels' undeclared
|
|
232
|
+
// refusal), but the exemplar path had no such gate, so a key carrying a
|
|
233
|
+
// newline / quote / brace forged a metric line into every scrape (CWE-93,
|
|
234
|
+
// the exemplar-KEY sibling of the already-fixed exemplar-VALUE injection).
|
|
235
|
+
// Drop any key that isn't a valid Prometheus label name; the length bound
|
|
236
|
+
// keeps a hostile multi-megabyte key from turning the regex test into a
|
|
237
|
+
// DoS, exactly as _validateLabelName caps the config-time path.
|
|
238
|
+
if (k.length > MAX_METRIC_NAME_LEN || !LABEL_NAME_RE.test(k)) continue;
|
|
239
|
+
out[k] = _validateLabelValue(labelObj[k]);
|
|
240
|
+
}
|
|
241
|
+
return out;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Coerce an exemplar's value / timestamp to a finite number. Per OpenMetrics
|
|
245
|
+
// 1.0 §6.2 both are numeric, but _renderFamilyLines appends them to the
|
|
246
|
+
// exposition line RAW (unlike labels, which _escapeLabelValue quotes). A
|
|
247
|
+
// non-numeric operator-supplied field — `exemplar.value = "1\n# forged 9"` —
|
|
248
|
+
// would otherwise inject a forged metric line into every scrape. Reject any
|
|
249
|
+
// non-finite value to the caller-supplied fallback so only a bare number ever
|
|
250
|
+
// reaches the wire.
|
|
251
|
+
function _numericExemplarField(value, fallback) {
|
|
252
|
+
var n = typeof value === "number" ? value : Number(value);
|
|
253
|
+
return isFinite(n) ? n : fallback;
|
|
254
|
+
}
|
|
255
|
+
|
|
214
256
|
// Serialize a labels object to a canonical Map key. Routed through
|
|
215
257
|
// canonical-json so the framework has one canonical-sort source of
|
|
216
258
|
// truth for sorted-keys serialization (avoiding the silent-data-loss
|
|
@@ -256,6 +298,88 @@ function _sortedLabelKeys(labelObj) {
|
|
|
256
298
|
return keys;
|
|
257
299
|
}
|
|
258
300
|
|
|
301
|
+
// Shared metric-family encoder for the Prometheus / OpenMetrics text
|
|
302
|
+
// formats. The live registry's exposition(), the shadow registry's
|
|
303
|
+
// prometheus render, and snapshot.render's labeled-registry path all
|
|
304
|
+
// route through here, so there is exactly one encoder for labeled /
|
|
305
|
+
// bucketed sample lines.
|
|
306
|
+
//
|
|
307
|
+
// family: { name, type, help, unit, buckets, entries }
|
|
308
|
+
// counter / gauge entries: [{ labels, value }]
|
|
309
|
+
// histogram entries: [{ labels, counts, sum, count, exemplars }]
|
|
310
|
+
function _renderFamilyLines(family, openMetrics, lines) {
|
|
311
|
+
// OpenMetrics §5.1.2 — counter sample lines MUST suffix with
|
|
312
|
+
// `_total`. The metadata `# HELP / # TYPE / # UNIT` lines MUST
|
|
313
|
+
// name the SAME family identifier the samples use, otherwise
|
|
314
|
+
// strict OpenMetrics parsers reject the family. Derive the
|
|
315
|
+
// exposition name once so metadata and sample lines agree.
|
|
316
|
+
var exposedName = family.name;
|
|
317
|
+
if (openMetrics && family.type === "counter" && !/_total$/.test(family.name)) { // allow:regex-no-length-cap — name-suffix check
|
|
318
|
+
exposedName = family.name + "_total";
|
|
319
|
+
}
|
|
320
|
+
if (family.help) lines.push("# HELP " + exposedName + " " + family.help);
|
|
321
|
+
lines.push("# TYPE " + exposedName + " " + family.type);
|
|
322
|
+
if (openMetrics && family.unit) lines.push("# UNIT " + exposedName + " " + family.unit);
|
|
323
|
+
var entries = family.entries;
|
|
324
|
+
if (family.type === "histogram") {
|
|
325
|
+
for (var k = 0; k < entries.length; k++) {
|
|
326
|
+
var entry = entries[k];
|
|
327
|
+
for (var bi = 0; bi < family.buckets.length; bi++) {
|
|
328
|
+
var bLabels = Object.assign(Object.create(null), entry.labels, { le: String(family.buckets[bi]) });
|
|
329
|
+
var bucketLine = family.name + "_bucket" + _renderLabels(bLabels) + " " + entry.counts[bi];
|
|
330
|
+
// OpenMetrics 1.0 §6.2 — exemplar trace + span IDs appended
|
|
331
|
+
// as `# {trace_id="...",span_id="..."} <value> <timestamp>`.
|
|
332
|
+
if (openMetrics && entry.exemplars && entry.exemplars[bi]) {
|
|
333
|
+
var ex = entry.exemplars[bi];
|
|
334
|
+
bucketLine += " # " + _renderLabels(ex.labels || {}) + " " + ex.value;
|
|
335
|
+
// Present-vs-missing on the coerced timestamp is `is a number`, not
|
|
336
|
+
// truthiness: _numericExemplarField stores a finite number or null,
|
|
337
|
+
// and the Unix epoch is a valid timestamp of 0 — a truthiness guard
|
|
338
|
+
// would silently drop it.
|
|
339
|
+
if (typeof ex.timestamp === "number") bucketLine += " " + ex.timestamp;
|
|
340
|
+
}
|
|
341
|
+
lines.push(bucketLine);
|
|
342
|
+
}
|
|
343
|
+
var infLabels = Object.assign(Object.create(null), entry.labels, { le: "+Inf" });
|
|
344
|
+
lines.push(family.name + "_bucket" + _renderLabels(infLabels) + " " + entry.counts[family.buckets.length]);
|
|
345
|
+
lines.push(family.name + "_sum" + _renderLabels(entry.labels) + " " + entry.sum);
|
|
346
|
+
lines.push(family.name + "_count" + _renderLabels(entry.labels) + " " + entry.count);
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
// exposedName only diverges from family.name for OpenMetrics
|
|
350
|
+
// counters (the `_total` suffix rule above), so using it
|
|
351
|
+
// unconditionally keeps Prometheus output byte-identical.
|
|
352
|
+
for (var v = 0; v < entries.length; v++) {
|
|
353
|
+
lines.push(exposedName + _renderLabels(entries[v].labels) + " " + entries[v].value);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Flatten one family into `{ key → value }` sample pairs (key = sample
|
|
359
|
+
// name + rendered labels). The text-format snapshot renderer consumes
|
|
360
|
+
// these as synthetic field rows; _renderFamilyLines renders the same
|
|
361
|
+
// samples as wire-format lines (plus metadata + exemplars, which have
|
|
362
|
+
// no key/value representation).
|
|
363
|
+
function _familySamples(family) {
|
|
364
|
+
var out = Object.create(null);
|
|
365
|
+
for (var i = 0; i < family.entries.length; i++) {
|
|
366
|
+
var entry = family.entries[i];
|
|
367
|
+
if (family.type === "histogram") {
|
|
368
|
+
for (var bi = 0; bi < family.buckets.length; bi++) {
|
|
369
|
+
var bLabels = Object.assign(Object.create(null), entry.labels, { le: String(family.buckets[bi]) });
|
|
370
|
+
out[family.name + "_bucket" + _renderLabels(bLabels)] = entry.counts[bi];
|
|
371
|
+
}
|
|
372
|
+
var infLabels = Object.assign(Object.create(null), entry.labels, { le: "+Inf" });
|
|
373
|
+
out[family.name + "_bucket" + _renderLabels(infLabels)] = entry.counts[family.buckets.length];
|
|
374
|
+
out[family.name + "_sum" + _renderLabels(entry.labels)] = entry.sum;
|
|
375
|
+
out[family.name + "_count" + _renderLabels(entry.labels)] = entry.count;
|
|
376
|
+
} else {
|
|
377
|
+
out[family.name + _renderLabels(entry.labels)] = entry.value;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return out;
|
|
381
|
+
}
|
|
382
|
+
|
|
259
383
|
// Combine default + per-call labels, validating against the metric's
|
|
260
384
|
// declared labelNames. Throws if a label name isn't declared.
|
|
261
385
|
function _resolveLabels(defaultLabels, declaredNames, callLabels) {
|
|
@@ -566,9 +690,9 @@ function create(opts) {
|
|
|
566
690
|
// arg; the registry only records what's passed in.
|
|
567
691
|
if (exemplar && typeof exemplar === "object") {
|
|
568
692
|
entry.exemplars[i] = {
|
|
569
|
-
labels: exemplar.labels
|
|
570
|
-
value: exemplar.value
|
|
571
|
-
timestamp: exemplar.timestamp
|
|
693
|
+
labels: _redactLabelMap(exemplar.labels),
|
|
694
|
+
value: _numericExemplarField(exemplar.value, arg.value),
|
|
695
|
+
timestamp: _numericExemplarField(exemplar.timestamp, null),
|
|
572
696
|
};
|
|
573
697
|
}
|
|
574
698
|
}
|
|
@@ -596,53 +720,17 @@ function create(opts) {
|
|
|
596
720
|
var sortedNames = Array.from(metrics.keys()).sort();
|
|
597
721
|
for (var i = 0; i < sortedNames.length; i++) {
|
|
598
722
|
var m = metrics.get(sortedNames[i]);
|
|
599
|
-
// OpenMetrics §5.1.2 — counter sample lines MUST suffix with
|
|
600
|
-
// `_total`. The metadata `# HELP / # TYPE / # UNIT` lines MUST
|
|
601
|
-
// name the SAME family identifier the samples use, otherwise
|
|
602
|
-
// strict OpenMetrics parsers reject the family. Derive the
|
|
603
|
-
// exposition name once at the top of the loop so both the
|
|
604
|
-
// metadata lines and the sample lines agree.
|
|
605
|
-
var exposedName = m.name;
|
|
606
|
-
if (openMetrics && m.type === "counter" && !/_total$/.test(m.name)) {
|
|
607
|
-
exposedName = m.name + "_total";
|
|
608
|
-
}
|
|
609
|
-
if (m.help) lines.push("# HELP " + exposedName + " " + m.help);
|
|
610
|
-
lines.push("# TYPE " + exposedName + " " + m.type);
|
|
611
|
-
if (openMetrics && m.unit) lines.push("# UNIT " + exposedName + " " + m.unit);
|
|
612
723
|
var keys = Array.from(m.values.keys()).sort();
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
bucketLine += " # " + _renderLabels(ex.labels || {}) + " " + ex.value;
|
|
624
|
-
if (ex.timestamp) bucketLine += " " + ex.timestamp;
|
|
625
|
-
}
|
|
626
|
-
lines.push(bucketLine);
|
|
627
|
-
}
|
|
628
|
-
var infLabels = Object.assign({}, entry.labels, { le: "+Inf" });
|
|
629
|
-
lines.push(m.name + "_bucket" + _renderLabels(infLabels) + " " + entry.counts[m.buckets.length]);
|
|
630
|
-
lines.push(m.name + "_sum" + _renderLabels(entry.labels) + " " + entry.sum);
|
|
631
|
-
lines.push(m.name + "_count" + _renderLabels(entry.labels) + " " + entry.count);
|
|
632
|
-
}
|
|
633
|
-
} else if (m.type === "counter" && openMetrics) {
|
|
634
|
-
// exposedName already carries the `_total` suffix when needed
|
|
635
|
-
// (derived at the top of the loop so metadata + samples agree).
|
|
636
|
-
for (var v = 0; v < keys.length; v++) {
|
|
637
|
-
var ent = m.values.get(keys[v]);
|
|
638
|
-
lines.push(exposedName + _renderLabels(ent.labels) + " " + ent.value);
|
|
639
|
-
}
|
|
640
|
-
} else {
|
|
641
|
-
for (var v2 = 0; v2 < keys.length; v2++) {
|
|
642
|
-
var ent2 = m.values.get(keys[v2]);
|
|
643
|
-
lines.push(m.name + _renderLabels(ent2.labels) + " " + ent2.value);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
724
|
+
var entries = [];
|
|
725
|
+
for (var k = 0; k < keys.length; k++) entries.push(m.values.get(keys[k]));
|
|
726
|
+
_renderFamilyLines({
|
|
727
|
+
name: m.name,
|
|
728
|
+
type: m.type,
|
|
729
|
+
help: m.help,
|
|
730
|
+
unit: m.unit,
|
|
731
|
+
buckets: m.buckets,
|
|
732
|
+
entries: entries,
|
|
733
|
+
}, openMetrics, lines);
|
|
646
734
|
lines.push("");
|
|
647
735
|
}
|
|
648
736
|
if (openMetrics) lines.push("# EOF");
|
|
@@ -1157,6 +1245,19 @@ function snapshotRead(p) {
|
|
|
1157
1245
|
* queries start returning the right answer once the new types reach
|
|
1158
1246
|
* the scrape target.
|
|
1159
1247
|
*
|
|
1248
|
+
* ## Labeled registry series
|
|
1249
|
+
*
|
|
1250
|
+
* A snapshot written with `startWriter`'s `registry` option carries the
|
|
1251
|
+
* registry's counters / gauges / histograms — label sets and histogram
|
|
1252
|
+
* bucket counts — in a structured `metrics` field. Both formats render
|
|
1253
|
+
* them: `prometheus` emits the same labeled / bucketed sample lines the
|
|
1254
|
+
* live `exposition()` endpoint serves, family names verbatim (NOT
|
|
1255
|
+
* `prefix`-qualified) so dashboards see one series name regardless of
|
|
1256
|
+
* scrape source; `text` lists each labeled sample as a
|
|
1257
|
+
* `name{label="value"}` row. A malformed family, metric / label name,
|
|
1258
|
+
* or non-numeric sample in a hand-edited snapshot file is dropped,
|
|
1259
|
+
* never rendered.
|
|
1260
|
+
*
|
|
1160
1261
|
* @opts
|
|
1161
1262
|
* format: "text" | "prometheus", // default: "text"
|
|
1162
1263
|
* prefix: string, // prometheus-only; default: "blamejs"
|
|
@@ -1233,6 +1334,84 @@ function _renderText(fields, snap, opts) {
|
|
|
1233
1334
|
return lines.join("\n") + "\n";
|
|
1234
1335
|
}
|
|
1235
1336
|
|
|
1337
|
+
// Validate + normalize one serialized registry family from a snapshot's
|
|
1338
|
+
// `metrics` field (written by startWriter's `registry` option) into the
|
|
1339
|
+
// _renderFamilyLines shape. Snapshot files are read back from disk, so
|
|
1340
|
+
// this is a defensive reader: a malformed family, a non-Prometheus
|
|
1341
|
+
// metric / label name, or a non-numeric sample is dropped rather than
|
|
1342
|
+
// rendered — a hand-edited snapshot file must not be able to forge
|
|
1343
|
+
// exposition lines. Returns null when the whole family is unusable.
|
|
1344
|
+
function _normalizeSnapshotFamily(name, fam) {
|
|
1345
|
+
if (!fam || typeof fam !== "object" || Array.isArray(fam)) return null;
|
|
1346
|
+
// Same name contracts as the live registry (METRIC_NAME_RE allows the
|
|
1347
|
+
// colon forms _validateMetricName accepts, LABEL_NAME_RE does not) —
|
|
1348
|
+
// a family the live exposition emits must never be dropped here. The
|
|
1349
|
+
// length cap bounds the anchored test on untrusted snapshot-file bytes.
|
|
1350
|
+
if (name.length > 1024 || !METRIC_NAME_RE.test(name)) return null;
|
|
1351
|
+
var type = fam.type;
|
|
1352
|
+
if (type !== "counter" && type !== "gauge" && type !== "histogram") return null;
|
|
1353
|
+
var buckets = null;
|
|
1354
|
+
if (type === "histogram") {
|
|
1355
|
+
if (!Array.isArray(fam.buckets)) return null;
|
|
1356
|
+
buckets = [];
|
|
1357
|
+
for (var bi = 0; bi < fam.buckets.length; bi += 1) {
|
|
1358
|
+
if (typeof fam.buckets[bi] !== "number" || !isFinite(fam.buckets[bi])) return null;
|
|
1359
|
+
buckets.push(fam.buckets[bi]);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
var observations = Array.isArray(fam.observations) ? fam.observations : [];
|
|
1363
|
+
var entries = [];
|
|
1364
|
+
for (var i = 0; i < observations.length; i += 1) {
|
|
1365
|
+
var obs = observations[i];
|
|
1366
|
+
if (!obs || typeof obs !== "object") continue;
|
|
1367
|
+
// null-proto so a label literally named `__proto__` / `constructor`
|
|
1368
|
+
// lands as an own property instead of being swallowed by the
|
|
1369
|
+
// plain-object prototype setter.
|
|
1370
|
+
var labels = Object.create(null);
|
|
1371
|
+
var rawLabels = obs.labels && typeof obs.labels === "object" ? obs.labels : {};
|
|
1372
|
+
var lnames = Object.keys(rawLabels);
|
|
1373
|
+
for (var li = 0; li < lnames.length; li += 1) {
|
|
1374
|
+
if (lnames[li].length > 1024 || !LABEL_NAME_RE.test(lnames[li])) continue; // drop forged / oversized label names
|
|
1375
|
+
labels[lnames[li]] = String(rawLabels[lnames[li]]);
|
|
1376
|
+
}
|
|
1377
|
+
if (type === "histogram") {
|
|
1378
|
+
if (!Array.isArray(obs.counts) || obs.counts.length !== buckets.length + 1) continue;
|
|
1379
|
+
var countsOk = true;
|
|
1380
|
+
for (var ci = 0; ci < obs.counts.length; ci += 1) {
|
|
1381
|
+
if (typeof obs.counts[ci] !== "number" || !isFinite(obs.counts[ci])) { countsOk = false; break; }
|
|
1382
|
+
}
|
|
1383
|
+
if (!countsOk) continue;
|
|
1384
|
+
if (typeof obs.sum !== "number" || !isFinite(obs.sum)) continue;
|
|
1385
|
+
if (typeof obs.count !== "number" || !isFinite(obs.count)) continue;
|
|
1386
|
+
entries.push({ labels: labels, counts: obs.counts, sum: obs.sum, count: obs.count });
|
|
1387
|
+
} else {
|
|
1388
|
+
if (typeof obs.value !== "number" || !isFinite(obs.value)) continue; // numeric samples only
|
|
1389
|
+
entries.push({ labels: labels, value: obs.value });
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
// Escape HELP text per the exposition format so a forged help string
|
|
1393
|
+
// can't inject metric lines (live registries carry operator-authored
|
|
1394
|
+
// help; snapshot files are untrusted bytes).
|
|
1395
|
+
var help = typeof fam.help === "string"
|
|
1396
|
+
? fam.help.replace(/\\/g, "\\\\").replace(/\n/g, "\\n").replace(/\r/g, "") // allow:regex-no-length-cap — fixed-char-set escape // allow:duplicate-regex — Prometheus help-text escape shape
|
|
1397
|
+
: "";
|
|
1398
|
+
return { name: name, type: type, help: help, buckets: buckets, entries: entries };
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
// Walk a snapshot's serialized `metrics` object into validated families,
|
|
1402
|
+
// sorted by name for stable exposition output.
|
|
1403
|
+
function _normalizeSnapshotFamilies(metricsObj) {
|
|
1404
|
+
if (!metricsObj || typeof metricsObj !== "object" || Array.isArray(metricsObj)) return [];
|
|
1405
|
+
var families = [];
|
|
1406
|
+
// allow:bare-canonicalize-walk — stable exposition output ordering
|
|
1407
|
+
var names = Object.keys(metricsObj).sort();
|
|
1408
|
+
for (var i = 0; i < names.length; i += 1) {
|
|
1409
|
+
var family = _normalizeSnapshotFamily(names[i], metricsObj[names[i]]);
|
|
1410
|
+
if (family) families.push(family);
|
|
1411
|
+
}
|
|
1412
|
+
return families;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1236
1415
|
function snapshotRender(snap, opts) {
|
|
1237
1416
|
opts = opts || {};
|
|
1238
1417
|
var format = opts.format || "text";
|
|
@@ -1241,8 +1420,25 @@ function snapshotRender(snap, opts) {
|
|
|
1241
1420
|
"metrics.snapshot.render: snap must be a startWriter-produced object (got " + typeof snap + ")");
|
|
1242
1421
|
}
|
|
1243
1422
|
var fields = snap.fields;
|
|
1423
|
+
// Labeled registry families (issue #430) — a snapshot written with
|
|
1424
|
+
// startWriter's `registry` option carries every registered counter /
|
|
1425
|
+
// gauge / histogram under `metrics`. Both formats render them so a
|
|
1426
|
+
// sidecar consuming a snapshot written by another process gets the
|
|
1427
|
+
// full labeled series, not just the flat numeric fields.
|
|
1428
|
+
var families = _normalizeSnapshotFamilies(snap.metrics);
|
|
1244
1429
|
if (format === "text") {
|
|
1245
|
-
|
|
1430
|
+
var textFields = fields;
|
|
1431
|
+
if (families.length > 0) {
|
|
1432
|
+
// Labeled series become synthetic `name{label="value"}` rows; an
|
|
1433
|
+
// operator-supplied flat field wins on a (pathological) name
|
|
1434
|
+
// collision.
|
|
1435
|
+
var synth = Object.create(null);
|
|
1436
|
+
for (var tf = 0; tf < families.length; tf += 1) {
|
|
1437
|
+
Object.assign(synth, _familySamples(families[tf]));
|
|
1438
|
+
}
|
|
1439
|
+
textFields = Object.assign(synth, fields);
|
|
1440
|
+
}
|
|
1441
|
+
return _renderText(textFields, snap, opts);
|
|
1246
1442
|
}
|
|
1247
1443
|
if (format === "prometheus") {
|
|
1248
1444
|
var prefix = opts.prefix || "blamejs";
|
|
@@ -1299,6 +1495,14 @@ function snapshotRender(snap, opts) {
|
|
|
1299
1495
|
out.push("# TYPE " + emName + " gauge");
|
|
1300
1496
|
out.push(emName + " " + ms);
|
|
1301
1497
|
}
|
|
1498
|
+
// Registry families render through the same encoder the live
|
|
1499
|
+
// exposition() endpoint uses, names verbatim (NOT prefix-qualified),
|
|
1500
|
+
// so a scraper switching between the live /metrics route and the
|
|
1501
|
+
// snapshot sidecar sees identical series names.
|
|
1502
|
+
for (var fj = 0; fj < families.length; fj += 1) {
|
|
1503
|
+
if (out.length > 0) out.push(""); // blank-line family separator, mirrors exposition()
|
|
1504
|
+
_renderFamilyLines(families[fj], false, out);
|
|
1505
|
+
}
|
|
1302
1506
|
return out.join("\n") + "\n";
|
|
1303
1507
|
}
|
|
1304
1508
|
throw new MetricsError("metrics-snapshot/bad-format",
|
|
@@ -1477,30 +1681,31 @@ function shadowRegistry(opts) {
|
|
|
1477
1681
|
function _emitLabeled(name, labelMap, kind) {
|
|
1478
1682
|
var metric = prefix + "_" + name;
|
|
1479
1683
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(metric)) return; // allow:regex-no-length-cap — Prometheus name-shape; metric length bounded by namespace + name caps
|
|
1480
|
-
|
|
1684
|
+
var entries = [];
|
|
1481
1685
|
var lks = Object.keys(labelMap);
|
|
1482
1686
|
for (var li = 0; li < lks.length; li += 1) {
|
|
1483
1687
|
var lk = lks[li];
|
|
1484
|
-
if (lk === "") { out.push(metric + " " + labelMap[lk]); continue; }
|
|
1485
1688
|
// Read the structured label set kept alongside the canonical key (see
|
|
1486
1689
|
// _coerceLabels) rather than re-parsing the key. No serialize-then-
|
|
1487
1690
|
// split round-trip, so a `,` or `=` in a label value stays inside the
|
|
1488
1691
|
// value and can never forge extra label pairs; and a label NAMED
|
|
1489
1692
|
// `constructor` / `prototype` / `__proto__` survives instead of being
|
|
1490
1693
|
// stripped by a prototype-pollution-hardened parse.
|
|
1491
|
-
var labelObj = labelSets[lk];
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1694
|
+
var labelObj = lk === "" ? null : labelSets[lk];
|
|
1695
|
+
// null-proto so a label literally named `__proto__` /
|
|
1696
|
+
// `constructor` lands as an own property instead of being
|
|
1697
|
+
// swallowed by the plain-object prototype setter.
|
|
1698
|
+
var labels = Object.create(null);
|
|
1699
|
+
if (labelObj && typeof labelObj === "object") {
|
|
1700
|
+
var lnames = Object.keys(labelObj);
|
|
1701
|
+
for (var pi = 0; pi < lnames.length; pi += 1) {
|
|
1702
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(lnames[pi])) continue; // allow:regex-no-length-cap — Prometheus label-name shape
|
|
1703
|
+
labels[lnames[pi]] = labelObj[lnames[pi]];
|
|
1704
|
+
}
|
|
1501
1705
|
}
|
|
1502
|
-
|
|
1706
|
+
entries.push({ labels: labels, value: labelMap[lk] });
|
|
1503
1707
|
}
|
|
1708
|
+
_renderFamilyLines({ name: metric, type: kind, help: "", entries: entries }, false, out);
|
|
1504
1709
|
}
|
|
1505
1710
|
var cn2 = Object.keys(counters);
|
|
1506
1711
|
for (var ci = 0; ci < cn2.length; ci += 1) {
|
|
@@ -140,7 +140,13 @@ function create(opts) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
var classification;
|
|
143
|
-
|
|
143
|
+
// A non-finite age (NaN from parseInt on a malformed birth field or
|
|
144
|
+
// date math, ±Infinity) is NOT a confirmed adult: typeof NaN === "number"
|
|
145
|
+
// and `NaN < consentRequired` is false, so without the isFinite guard the
|
|
146
|
+
// classifier fell through to "above-threshold" and dropped every privacy
|
|
147
|
+
// default for a user whose age simply failed to compute. Treat it as
|
|
148
|
+
// "unknown" (privacy headers applied), consistent with a null return.
|
|
149
|
+
if (age === null || typeof age !== "number" || !isFinite(age)) classification = "unknown";
|
|
144
150
|
else if (consentRequired !== null && age < consentRequired) classification = "below-threshold";
|
|
145
151
|
else classification = "above-threshold";
|
|
146
152
|
|
|
@@ -94,7 +94,7 @@ var audit = lazyRequire(function () { return require("../audit"); });
|
|
|
94
94
|
* @example
|
|
95
95
|
* var b = require("@blamejs/core");
|
|
96
96
|
* var app = b.router.create();
|
|
97
|
-
* var aapi = b.asyncapi.create({ title: "events", version: "1.0.0" });
|
|
97
|
+
* var aapi = b.asyncapi.create({ info: { title: "events", version: "1.0.0" } });
|
|
98
98
|
* app.use(b.middleware.asyncapiServe({
|
|
99
99
|
* document: aapi,
|
|
100
100
|
* pathJson: "/asyncapi.json",
|
|
@@ -1651,12 +1651,27 @@ function _resolveStandaloneMultipartOpts(opts, ct) {
|
|
|
1651
1651
|
null, { permanent: true, statusCode: HTTP_STATUS.BAD_REQUEST });
|
|
1652
1652
|
resolved.fileCount = mf;
|
|
1653
1653
|
}
|
|
1654
|
-
// Pass
|
|
1655
|
-
//
|
|
1656
|
-
|
|
1657
|
-
|
|
1654
|
+
// Pass through EVERY documented multipart knob the middleware honors —
|
|
1655
|
+
// parsers.multipart is a thin wrapper, not a feature subset. Derive the
|
|
1656
|
+
// passthrough from DEFAULTS.multipart rather than a hand-maintained list so a
|
|
1657
|
+
// knob added to the middleware can never silently vanish on the standalone
|
|
1658
|
+
// path (the drift that dropped `storage` + `filenameCharsets`). Only the keys
|
|
1659
|
+
// the standalone surfaces under a different name (totalSize←maxBytes,
|
|
1660
|
+
// fileCount←maxFiles) or that are dispatch-only (contentTypes — the standalone
|
|
1661
|
+
// requires multipart/form-data) are excluded.
|
|
1662
|
+
var STANDALONE_MULTIPART_EXCLUDE = { totalSize: true, fileCount: true, contentTypes: true };
|
|
1663
|
+
Object.keys(DEFAULTS.multipart).forEach(function (k) {
|
|
1664
|
+
if (STANDALONE_MULTIPART_EXCLUDE[k]) return;
|
|
1658
1665
|
if (opts[k] !== undefined) resolved[k] = opts[k];
|
|
1659
1666
|
});
|
|
1667
|
+
// storage is an operator-config enum — reject a typo at the call the same way
|
|
1668
|
+
// b.middleware.bodyParser does (a bad value must not silently fall back to
|
|
1669
|
+
// disk mode and then throw deep in the parser on a read-only FS).
|
|
1670
|
+
if (resolved.storage !== "disk" && resolved.storage !== "memory") {
|
|
1671
|
+
throw new TypeError(
|
|
1672
|
+
"parsers.multipart: storage must be \"disk\" or \"memory\" (got " +
|
|
1673
|
+
JSON.stringify(resolved.storage) + ")");
|
|
1674
|
+
}
|
|
1660
1675
|
// ct is the parsed Content-Type; required for the boundary parameter.
|
|
1661
1676
|
if (!ct || typeof ct.type !== "string" || ct.type !== "multipart/form-data") {
|
|
1662
1677
|
throw new BodyParserError("body-parser/standalone-not-multipart",
|
|
@@ -52,6 +52,7 @@ var DEFAULT_BLOCKED_AGENTS = [
|
|
|
52
52
|
|
|
53
53
|
var lazyRequire = require("../lazy-require");
|
|
54
54
|
var requestHelpers = require("../request-helpers");
|
|
55
|
+
var ssrfGuard = require("../ssrf-guard");
|
|
55
56
|
var validateOpts = require("../validate-opts");
|
|
56
57
|
var denyResponse = require("./deny-response").denyResponse;
|
|
57
58
|
var { defineClass } = require("../framework-error");
|
|
@@ -185,15 +186,10 @@ function create(opts) {
|
|
|
185
186
|
if (_proto.resolve(req) === "https") return true;
|
|
186
187
|
var host = (req.headers && req.headers.host) || "";
|
|
187
188
|
host = String(host).toLowerCase().replace(/:\d+$/, ""); // strip :port
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
host = host.replace(/\.$/, ""); // strip trailing root-zone dot (RFC 1034 §3.1) so "localhost." matches
|
|
193
|
-
if (host === "localhost" || /\.localhost$/.test(host)) return true;
|
|
194
|
-
if (host === "::1") return true;
|
|
195
|
-
if (/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host)) return true; // allow:regex-no-length-cap — bounded dotted-quad loopback
|
|
196
|
-
return false;
|
|
189
|
+
// Loopback HTTP is a secure context (can't be reached off-box). Compose the
|
|
190
|
+
// canonical hostname-aware classifier — 127/8, ::1 / [::1], localhost, and
|
|
191
|
+
// *.localhost (RFC 6761 §6.3) — instead of re-rolling the triad here.
|
|
192
|
+
return ssrfGuard.isLoopbackHost(host);
|
|
197
193
|
}
|
|
198
194
|
|
|
199
195
|
function _checkHeuristics(req) {
|
|
@@ -39,6 +39,15 @@ var audit = lazyRequire(function () { return require("../audit"); });
|
|
|
39
39
|
|
|
40
40
|
var DEFAULT_MAX_BYTES = C.BYTES.kib(64);
|
|
41
41
|
var SAMPLE_TRUNCATE = 200;
|
|
42
|
+
// A single POST may carry a batch of reports (Reporting API). The byte
|
|
43
|
+
// cap bounds the body, but NOT the number of reports inside it — a
|
|
44
|
+
// 64 KiB body of ~40-byte report objects is ~1600 reports, and each one
|
|
45
|
+
// drives a full audit-chain append (SHA3 hash + seal + DB insert) plus an
|
|
46
|
+
// onReport hook. On an unauthenticated endpoint that is a per-request
|
|
47
|
+
// amplification vector, so the batch length is capped independently. A
|
|
48
|
+
// real browser batch is a handful; 100 is generous headroom. Operators
|
|
49
|
+
// raise or lower it via opts.maxReports.
|
|
50
|
+
var DEFAULT_MAX_REPORTS = 100;
|
|
42
51
|
|
|
43
52
|
function _truncate(value) {
|
|
44
53
|
if (typeof value !== "string") return value;
|
|
@@ -108,16 +117,25 @@ function _normalizeOne(reportLike) {
|
|
|
108
117
|
* alerting use as `onReport`: a flood of 413s signals a misconfigured
|
|
109
118
|
* `Reporting-Endpoints` URL or a report-bomb. It receives
|
|
110
119
|
* `(req, res, { status, reason })` where `reason` is one of
|
|
111
|
-
* `method-not-allowed` / `payload-too-large` / `
|
|
112
|
-
* after the rejection response is written; a
|
|
113
|
-
* so a broken metrics sink can't crash the
|
|
120
|
+
* `method-not-allowed` / `payload-too-large` / `too-many-reports` /
|
|
121
|
+
* `invalid-json`. Invoked after the rejection response is written; a
|
|
122
|
+
* throwing hook is swallowed so a broken metrics sink can't crash the
|
|
123
|
+
* endpoint.
|
|
124
|
+
*
|
|
125
|
+
* A single POST may batch multiple reports; the batch length is capped
|
|
126
|
+
* at `maxReports` (default 100) independently of the byte cap so an
|
|
127
|
+
* unauthenticated caller can't force one audit-chain append + `onReport`
|
|
128
|
+
* hook per entry across a body packed with thousands of tiny reports. A
|
|
129
|
+
* batch over the cap is refused whole with HTTP 413 + `onReject`
|
|
130
|
+
* `too-many-reports`.
|
|
114
131
|
*
|
|
115
132
|
* @opts
|
|
116
133
|
* {
|
|
117
|
-
* onReport:
|
|
118
|
-
* onReject:
|
|
119
|
-
* maxBytes:
|
|
120
|
-
*
|
|
134
|
+
* onReport: function(report): void,
|
|
135
|
+
* onReject: function(req, res, { status, reason }): void,
|
|
136
|
+
* maxBytes: number, // default 64 KiB
|
|
137
|
+
* maxReports: number, // default 100 — batch length cap
|
|
138
|
+
* audit: boolean, // default true
|
|
121
139
|
* }
|
|
122
140
|
*
|
|
123
141
|
* @example
|
|
@@ -132,14 +150,17 @@ function _normalizeOne(reportLike) {
|
|
|
132
150
|
*/
|
|
133
151
|
function create(opts) {
|
|
134
152
|
opts = opts || {};
|
|
135
|
-
validateOpts(opts, ["audit", "onReport", "onReject", "maxBytes"], "middleware.cspReport");
|
|
153
|
+
validateOpts(opts, ["audit", "onReport", "onReject", "maxBytes", "maxReports"], "middleware.cspReport");
|
|
136
154
|
if (opts.onReject !== undefined && opts.onReject !== null &&
|
|
137
155
|
typeof opts.onReject !== "function") {
|
|
138
156
|
throw new TypeError("middleware.cspReport: opts.onReject must be a function");
|
|
139
157
|
}
|
|
140
158
|
validateOpts.optionalPositiveInt(opts.maxBytes, "middleware.cspReport: maxBytes");
|
|
159
|
+
validateOpts.optionalPositiveInt(opts.maxReports, "middleware.cspReport: maxReports");
|
|
141
160
|
var maxBytes = (opts.maxBytes === undefined || opts.maxBytes === null)
|
|
142
161
|
? DEFAULT_MAX_BYTES : opts.maxBytes;
|
|
162
|
+
var maxReports = (opts.maxReports === undefined || opts.maxReports === null)
|
|
163
|
+
? DEFAULT_MAX_REPORTS : opts.maxReports;
|
|
143
164
|
var auditOn = opts.audit !== false;
|
|
144
165
|
var onReport = (typeof opts.onReport === "function") ? opts.onReport : null;
|
|
145
166
|
var onReject = (typeof opts.onReject === "function") ? opts.onReject : null;
|
|
@@ -177,6 +198,17 @@ function create(opts) {
|
|
|
177
198
|
return;
|
|
178
199
|
}
|
|
179
200
|
var reports = Array.isArray(parsed) ? parsed : [parsed];
|
|
201
|
+
// Fail closed on a report-bomb: a batch whose length exceeds maxReports
|
|
202
|
+
// is refused whole (413) rather than driving one audit-chain append +
|
|
203
|
+
// onReport hook per entry. This bounds the per-request work an
|
|
204
|
+
// unauthenticated caller can force. A throwing/absent audit or hook is
|
|
205
|
+
// unaffected — nothing is processed on this path.
|
|
206
|
+
if (reports.length > maxReports) {
|
|
207
|
+
res.writeHead(413); // HTTP 413 status
|
|
208
|
+
res.end();
|
|
209
|
+
_emitReject(req, res, 413, "too-many-reports");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
180
212
|
for (var i = 0; i < reports.length; i++) {
|
|
181
213
|
var normalized = _normalizeOne(reports[i]);
|
|
182
214
|
if (!normalized) continue;
|
|
@@ -430,16 +430,30 @@ function create(opts) {
|
|
|
430
430
|
if (["Lax", "Strict", "None"].indexOf(cookieCfg.sameSite) === -1) {
|
|
431
431
|
throw new Error("middleware.csrfProtect: opts.cookie.sameSite must be Lax|Strict|None");
|
|
432
432
|
}
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
//
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
433
|
+
// Cookie name-prefix safety (RFC 6265bis §4.1.3). csrf-protect builds its
|
|
434
|
+
// own Set-Cookie header rather than routing through b.cookies.serialize, so
|
|
435
|
+
// this boot check is the only enforcement point. §5.4 requires user agents
|
|
436
|
+
// to apply the prefix test case-INSENSITIVELY (the server-side §4.1.3
|
|
437
|
+
// description reads "case-sensitive", but the UA is what drops the cookie),
|
|
438
|
+
// so `__host-`/`__SECURE-` get the same browser enforcement as
|
|
439
|
+
// `__Host-`/`__Secure-` -- case-sensitive matching was itself CVE-2024-5699.
|
|
440
|
+
// Compare a lowercased copy so a case-variant name can't dodge the invariant
|
|
441
|
+
// here and then be silently rejected by the browser. Catch typos at boot.
|
|
442
|
+
// __Host-* — Path must be "/", no Domain (we never set one), Secure.
|
|
443
|
+
// __Secure-* — Secure.
|
|
444
|
+
if (cookieCfg.name) {
|
|
445
|
+
var lowerCookieName = cookieCfg.name.toLowerCase();
|
|
446
|
+
if (lowerCookieName.indexOf("__host-") === 0) {
|
|
447
|
+
if (cookieCfg.path !== "/") {
|
|
448
|
+
throw new Error("middleware.csrfProtect: __Host-* cookie name requires path='/'");
|
|
449
|
+
}
|
|
450
|
+
if (cookieCfg.secure === false) {
|
|
451
|
+
throw new Error("middleware.csrfProtect: __Host-* cookie name requires secure (cannot be explicit false)");
|
|
452
|
+
}
|
|
453
|
+
} else if (lowerCookieName.indexOf("__secure-") === 0) {
|
|
454
|
+
if (cookieCfg.secure === false) {
|
|
455
|
+
throw new Error("middleware.csrfProtect: __Secure-* cookie name requires secure (cannot be explicit false)");
|
|
456
|
+
}
|
|
443
457
|
}
|
|
444
458
|
}
|
|
445
459
|
}
|