@blamejs/blamejs-shop 0.4.30 → 0.4.32
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/checkout.js +8 -0
- package/lib/order.js +71 -11
- package/lib/vendor/MANIFEST.json +392 -278
- package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
- package/lib/vendor/blamejs/.gitignore +6 -0
- package/lib/vendor/blamejs/CHANGELOG.md +26 -0
- package/lib/vendor/blamejs/MIGRATING.md +43 -0
- package/lib/vendor/blamejs/README.md +8 -6
- package/lib/vendor/blamejs/SECURITY.md +19 -3
- package/lib/vendor/blamejs/api-snapshot.json +2190 -664
- package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
- package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
- package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
- package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
- package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
- package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
- package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
- package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
- package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
- package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
- package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
- package/lib/vendor/blamejs/index.js +4 -0
- package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
- package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
- package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
- package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
- package/lib/vendor/blamejs/lib/api-key.js +158 -77
- package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
- package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
- package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
- package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
- package/lib/vendor/blamejs/lib/audit.js +259 -123
- package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
- package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
- package/lib/vendor/blamejs/lib/backup/index.js +45 -10
- package/lib/vendor/blamejs/lib/break-glass.js +355 -147
- package/lib/vendor/blamejs/lib/cache.js +174 -105
- package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
- package/lib/vendor/blamejs/lib/cli.js +19 -14
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
- package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
- package/lib/vendor/blamejs/lib/cluster.js +119 -71
- package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
- package/lib/vendor/blamejs/lib/compliance.js +206 -4
- package/lib/vendor/blamejs/lib/consent.js +82 -29
- package/lib/vendor/blamejs/lib/constants.js +27 -11
- package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
- package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
- package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
- package/lib/vendor/blamejs/lib/db-query.js +882 -260
- package/lib/vendor/blamejs/lib/db-schema.js +228 -44
- package/lib/vendor/blamejs/lib/db.js +249 -99
- package/lib/vendor/blamejs/lib/dsr.js +385 -55
- package/lib/vendor/blamejs/lib/error-page.js +14 -1
- package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
- package/lib/vendor/blamejs/lib/external-db.js +549 -34
- package/lib/vendor/blamejs/lib/file-upload.js +52 -7
- package/lib/vendor/blamejs/lib/framework-error.js +20 -1
- package/lib/vendor/blamejs/lib/framework-files.js +73 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
- package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
- package/lib/vendor/blamejs/lib/guard-all.js +1 -0
- package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
- package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
- package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
- package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
- package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
- package/lib/vendor/blamejs/lib/guard-email.js +47 -69
- package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
- package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
- package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
- package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
- package/lib/vendor/blamejs/lib/guard-html.js +53 -108
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
- package/lib/vendor/blamejs/lib/guard-image.js +46 -103
- package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
- package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
- package/lib/vendor/blamejs/lib/guard-json.js +38 -108
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
- package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
- package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
- package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
- package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
- package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
- package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
- package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
- package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
- package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
- package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
- package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
- package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
- package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
- package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
- package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
- package/lib/vendor/blamejs/lib/guard-template.js +35 -172
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-time.js +32 -154
- package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
- package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
- package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
- package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
- package/lib/vendor/blamejs/lib/http-client.js +37 -9
- package/lib/vendor/blamejs/lib/inbox.js +120 -107
- package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
- package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
- package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
- package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
- package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
- package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
- package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
- package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
- package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
- package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
- package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
- package/lib/vendor/blamejs/lib/mail-store.js +293 -154
- package/lib/vendor/blamejs/lib/mail.js +8 -4
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
- package/lib/vendor/blamejs/lib/migrations.js +108 -66
- package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
- package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
- package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
- package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
- package/lib/vendor/blamejs/lib/observability.js +124 -0
- package/lib/vendor/blamejs/lib/otel-export.js +12 -3
- package/lib/vendor/blamejs/lib/outbox.js +184 -83
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
- package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
- package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
- package/lib/vendor/blamejs/lib/queue-local.js +225 -140
- package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
- package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
- package/lib/vendor/blamejs/lib/queue.js +7 -0
- package/lib/vendor/blamejs/lib/redact.js +68 -11
- package/lib/vendor/blamejs/lib/redis-client.js +160 -31
- package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
- package/lib/vendor/blamejs/lib/retention.js +101 -40
- package/lib/vendor/blamejs/lib/router.js +212 -5
- package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
- package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
- package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
- package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
- package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
- package/lib/vendor/blamejs/lib/safe-url.js +170 -3
- package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
- package/lib/vendor/blamejs/lib/scheduler.js +35 -12
- package/lib/vendor/blamejs/lib/seeders.js +122 -74
- package/lib/vendor/blamejs/lib/session-stores.js +42 -14
- package/lib/vendor/blamejs/lib/session.js +175 -77
- package/lib/vendor/blamejs/lib/sql.js +3842 -0
- package/lib/vendor/blamejs/lib/sse.js +26 -0
- package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
- package/lib/vendor/blamejs/lib/static.js +177 -34
- package/lib/vendor/blamejs/lib/subject.js +96 -49
- package/lib/vendor/blamejs/lib/vault/index.js +3 -2
- package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
- package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
- package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
- package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
- package/lib/vendor/blamejs/lib/websocket.js +35 -5
- package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
- package/lib/vendor/blamejs/package.json +2 -2
- package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
- package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
- package/lib/vendor/blamejs/scripts/check-services.js +21 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
- package/lib/vendor/blamejs/scripts/release.js +398 -38
- package/lib/vendor/blamejs/test/00-primitives.js +117 -0
- package/lib/vendor/blamejs/test/10-state.js +140 -14
- package/lib/vendor/blamejs/test/20-db.js +65 -2
- package/lib/vendor/blamejs/test/helpers/db.js +9 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
- package/lib/vendor/blamejs/test/helpers/services.js +21 -0
- package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
- package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
- package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
- package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
- package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
- package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
- package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
- package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
- package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
- package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
- package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
- package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
- package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
- package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
- package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
- package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
- package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
- package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
- package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
- package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
- package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
- package/lib/vendor/blamejs/test/smoke.js +79 -21
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
- package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
- package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
- package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
- package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
- package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
- package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
- package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
- package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
- package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
- package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
- package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
- package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
- package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
- package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
- package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
|
@@ -214,6 +214,11 @@ function create(config) {
|
|
|
214
214
|
var timeoutMs = config.timeoutMs;
|
|
215
215
|
var allowedProtocols = config.allowedProtocols || safeUrl.ALLOW_HTTP_TLS;
|
|
216
216
|
var allowInternal = config.allowInternal != null ? config.allowInternal : null;
|
|
217
|
+
// Account placement — see azure-blob.js create(). Default host-based; opt
|
|
218
|
+
// into path-style (Azurite / Azure Stack / private) with config.pathStyle:
|
|
219
|
+
// true. Default false keeps the host-based wire shape unchanged.
|
|
220
|
+
var pathStyle = config.pathStyle === true;
|
|
221
|
+
var pathPrefix = pathStyle ? ("/" + config.accountName) : "";
|
|
217
222
|
|
|
218
223
|
function _sign(method, url, headers) {
|
|
219
224
|
return azureBlob.signRequest({
|
|
@@ -260,7 +265,7 @@ function create(config) {
|
|
|
260
265
|
async function createContainer(name, opts) {
|
|
261
266
|
_validateContainerName(name);
|
|
262
267
|
opts = opts || {};
|
|
263
|
-
var url = _internalUrl(endpoint + "/" + name + "?restype=container", allowedProtocols);
|
|
268
|
+
var url = _internalUrl(endpoint + pathPrefix + "/" + name + "?restype=container", allowedProtocols);
|
|
264
269
|
var headers = { "Content-Length": "0" };
|
|
265
270
|
if (opts.publicAccess) {
|
|
266
271
|
if (opts.publicAccess !== "blob" && opts.publicAccess !== "container") {
|
|
@@ -282,7 +287,7 @@ function create(config) {
|
|
|
282
287
|
|
|
283
288
|
async function deleteContainer(name) {
|
|
284
289
|
_validateContainerName(name);
|
|
285
|
-
var url = _internalUrl(endpoint + "/" + name + "?restype=container", allowedProtocols);
|
|
290
|
+
var url = _internalUrl(endpoint + pathPrefix + "/" + name + "?restype=container", allowedProtocols);
|
|
286
291
|
var signed = _sign("DELETE", url, {});
|
|
287
292
|
var res = await _request("DELETE", url, signed, null, [HTTP_ACCEPTED, HTTP_NOT_FOUND]);
|
|
288
293
|
return res.statusCode === HTTP_ACCEPTED;
|
|
@@ -290,7 +295,7 @@ function create(config) {
|
|
|
290
295
|
|
|
291
296
|
async function listContainers(opts) {
|
|
292
297
|
opts = opts || {};
|
|
293
|
-
var url = _internalUrl(endpoint + "/?comp=list", allowedProtocols);
|
|
298
|
+
var url = _internalUrl(endpoint + pathPrefix + "/?comp=list", allowedProtocols);
|
|
294
299
|
if (opts.prefix) url.searchParams.set("prefix", opts.prefix);
|
|
295
300
|
if (opts.maxResults != null) url.searchParams.set("maxresults", String(opts.maxResults));
|
|
296
301
|
var signed = _sign("GET", url, {});
|
|
@@ -319,7 +324,7 @@ function create(config) {
|
|
|
319
324
|
rules.forEach(_validateCorsRule);
|
|
320
325
|
var xml = _buildCorsXml(rules);
|
|
321
326
|
var bodyBuf = Buffer.from(xml, "utf8");
|
|
322
|
-
var url = _internalUrl(endpoint + "/?restype=service&comp=properties", allowedProtocols);
|
|
327
|
+
var url = _internalUrl(endpoint + pathPrefix + "/?restype=service&comp=properties", allowedProtocols);
|
|
323
328
|
var headers = {
|
|
324
329
|
"Content-Type": "application/xml",
|
|
325
330
|
"Content-Length": String(bodyBuf.length),
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
* accountKey: '<base64 storage key>' // required (REST shared key)
|
|
16
16
|
* container: 'my-container' // required
|
|
17
17
|
* endpoint: 'https://...' // optional override
|
|
18
|
+
* pathStyle: true // optional; account as the first
|
|
19
|
+
* // URL path segment (Azurite / Azure
|
|
20
|
+
* // Stack / private endpoints).
|
|
21
|
+
* // Default false = host-based
|
|
22
|
+
* // (<account>.blob.core.windows.net).
|
|
18
23
|
* apiVersion: '2024-08-04' // x-ms-version header
|
|
19
24
|
* timeoutMs: C.TIME.seconds(30)
|
|
20
25
|
* }
|
|
@@ -35,6 +40,7 @@ var { URL } = require("node:url");
|
|
|
35
40
|
var { Readable } = require("node:stream");
|
|
36
41
|
var safeXml = require("../parsers/safe-xml");
|
|
37
42
|
var sharedRequest = require("./http-request");
|
|
43
|
+
var sigv4 = require("./sigv4");
|
|
38
44
|
var C = require("../constants");
|
|
39
45
|
var requestHelpers = require("../request-helpers");
|
|
40
46
|
var { ObjectStoreError } = require("../framework-error");
|
|
@@ -65,6 +71,26 @@ function _arrayify(value) {
|
|
|
65
71
|
return Array.isArray(value) ? value : [value];
|
|
66
72
|
}
|
|
67
73
|
|
|
74
|
+
// Percent-encode a hierarchical blob name for use in a URL path. Azure
|
|
75
|
+
// blob names are `/`-delimited virtual directories, so each segment is
|
|
76
|
+
// RFC 3986 percent-encoded (via the family-shared encoder used by the
|
|
77
|
+
// S3 / GCS backends) while the `/` separators are preserved. Without
|
|
78
|
+
// this, a key containing `?`, `#`, a space, or other reserved chars is
|
|
79
|
+
// interpolated raw into the request URL — `?`/`#` start the query /
|
|
80
|
+
// fragment (so the blob path is truncated, hitting the wrong object or
|
|
81
|
+
// the container root), and spaces / control bytes corrupt the request
|
|
82
|
+
// line (CWE-20 improper input → request-smuggling-adjacent). A null
|
|
83
|
+
// byte is refused outright (it can't appear in a valid blob name and
|
|
84
|
+
// indicates a malformed / hostile key), matching the S3 / GCS guards.
|
|
85
|
+
function _encodeBlobKey(key) {
|
|
86
|
+
if (key.indexOf("\0") !== -1) {
|
|
87
|
+
throw _err("INVALID_KEY", "null byte in blob key", true);
|
|
88
|
+
}
|
|
89
|
+
return key.split("/").map(function (s) {
|
|
90
|
+
return sigv4.awsUriEncode(s, true);
|
|
91
|
+
}).join("/");
|
|
92
|
+
}
|
|
93
|
+
|
|
68
94
|
var DEFAULT_API_VERSION = "2024-08-04";
|
|
69
95
|
|
|
70
96
|
// Service SAS expiry bounds. Azure doesn't enforce a hard max, but
|
|
@@ -120,6 +146,17 @@ function buildStringToSign(opts) {
|
|
|
120
146
|
var canonicalResource = (function () {
|
|
121
147
|
// /<account>/<rest of path>
|
|
122
148
|
// Plus sorted query params, each "name:value\n"
|
|
149
|
+
// Canonicalized resource per the Shared Key spec: "/" + account + the
|
|
150
|
+
// request's absolute path + sorted query. Host-based endpoints
|
|
151
|
+
// (production <account>.blob.core.windows.net) have url.pathname
|
|
152
|
+
// "/<container>/<blob>", giving "/<account>/<container>/<blob>".
|
|
153
|
+
// Path-style endpoints (Azurite / Azure Stack / private) already carry
|
|
154
|
+
// "/<account>" as the first path segment, so the account appears twice
|
|
155
|
+
// ("/<account>/<account>/<container>/<blob>") — which is exactly what a
|
|
156
|
+
// path-style server expects: it prepends the account to the full request
|
|
157
|
+
// path it received. Verified against Azurite — the doubled form is the
|
|
158
|
+
// one that authenticates; the URL itself must carry the account in its
|
|
159
|
+
// path (see pathPrefix in create()).
|
|
123
160
|
var resourcePath = "/" + opts.accountName + url.pathname;
|
|
124
161
|
var paramPairs = [];
|
|
125
162
|
url.searchParams.forEach(function (v, k) {
|
|
@@ -204,11 +241,24 @@ function create(config) {
|
|
|
204
241
|
var allowedProtocols = config.allowedProtocols || safeUrl.ALLOW_HTTP_TLS;
|
|
205
242
|
var allowInternal = config.allowInternal != null ? config.allowInternal : null;
|
|
206
243
|
safeUrl.parse(endpoint, { allowedProtocols: allowedProtocols, errorClass: ObjectStoreError });
|
|
244
|
+
// Account placement. Default host-based — production Azure is
|
|
245
|
+
// https://<account>.blob.core.windows.net/<container>/<blob> (account in the
|
|
246
|
+
// host). Path-style endpoints (Azurite / Azure Stack / private) carry the
|
|
247
|
+
// account as the first PATH segment instead —
|
|
248
|
+
// https://<host>/<account>/<container>/<blob> — opt in with
|
|
249
|
+
// config.pathStyle:true. Default false keeps the host-based wire shape
|
|
250
|
+
// unchanged for existing deployments (no silent breaking change). The signed
|
|
251
|
+
// canonicalized resource is always "/" + account + url.pathname, so for a
|
|
252
|
+
// path-style URL the account appears twice — which is exactly what a
|
|
253
|
+
// path-style server expects (see buildStringToSign).
|
|
254
|
+
var pathStyle = config.pathStyle === true;
|
|
255
|
+
var pathPrefix = pathStyle ? ("/" + config.accountName) : "";
|
|
207
256
|
var reqOpts = { timeoutMs: timeoutMs, allowedProtocols: allowedProtocols };
|
|
208
257
|
if (allowInternal !== null) reqOpts.allowInternal = allowInternal;
|
|
209
258
|
|
|
210
259
|
function _blobUrl(key, params) {
|
|
211
|
-
var u = _internalUrl(endpoint + "/" + config.container + "/" + key,
|
|
260
|
+
var u = _internalUrl(endpoint + pathPrefix + "/" + config.container + "/" + _encodeBlobKey(key),
|
|
261
|
+
allowedProtocols);
|
|
212
262
|
if (params) {
|
|
213
263
|
Object.keys(params).forEach(function (k) { u.searchParams.set(k, params[k]); });
|
|
214
264
|
}
|
|
@@ -216,7 +266,7 @@ function create(config) {
|
|
|
216
266
|
}
|
|
217
267
|
|
|
218
268
|
function _containerUrl(params) {
|
|
219
|
-
var u = _internalUrl(endpoint + "/" + config.container, allowedProtocols);
|
|
269
|
+
var u = _internalUrl(endpoint + pathPrefix + "/" + config.container, allowedProtocols);
|
|
220
270
|
if (params) {
|
|
221
271
|
Object.keys(params).forEach(function (k) { u.searchParams.set(k, params[k]); });
|
|
222
272
|
}
|
|
@@ -425,8 +475,12 @@ function create(config) {
|
|
|
425
475
|
throw _err("INVALID_KEY", "null byte in key", true);
|
|
426
476
|
}
|
|
427
477
|
|
|
478
|
+
// _buildSasToken signs the canonicalized resource with the RAW
|
|
479
|
+
// (decoded) blob name per the Azure SAS spec; the URL PATH carries the
|
|
480
|
+
// percent-encoded key so a key with reserved chars (`?` / `#` / space)
|
|
481
|
+
// doesn't truncate the path or corrupt the request line.
|
|
428
482
|
var token = _buildSasToken(permissions, opts);
|
|
429
|
-
var url = _internalUrl(endpoint + "/" + config.container + "/" + opts.key + "?" + token.sas, allowedProtocols);
|
|
483
|
+
var url = _internalUrl(endpoint + pathPrefix + "/" + config.container + "/" + _encodeBlobKey(opts.key) + "?" + token.sas, allowedProtocols);
|
|
430
484
|
|
|
431
485
|
var clientHeaders = {};
|
|
432
486
|
if (opts.contentType) clientHeaders["Content-Type"] = opts.contentType;
|
|
@@ -364,7 +364,10 @@ function create(config) {
|
|
|
364
364
|
// Build the canonical request — identical shape to SigV4. The
|
|
365
365
|
// sigv4 export gives us the formatter so this stays in lockstep
|
|
366
366
|
// with the AWS implementation.
|
|
367
|
-
|
|
367
|
+
// GCS's V4 signature, like S3, URI-encodes the canonical path ONCE; the key
|
|
368
|
+
// is already single-encoded into url.pathname above, so pass doubleEncodePath
|
|
369
|
+
// = false (a second encode would 403 any key with a space/+/&/unicode).
|
|
370
|
+
var canon = sigv4.canonicalRequest(method, url, headers, "UNSIGNED-PAYLOAD", false);
|
|
368
371
|
var stringToSign = [
|
|
369
372
|
GCS_V4_ALGORITHM,
|
|
370
373
|
amzDate,
|
|
@@ -514,8 +514,11 @@ function create(config) {
|
|
|
514
514
|
function _objectUrl(name, key, query) {
|
|
515
515
|
// Each key segment is encoded individually so that legitimate "/"
|
|
516
516
|
// separators in the key are preserved (S3 treats keys with slashes
|
|
517
|
-
// as flat names, not directories).
|
|
518
|
-
|
|
517
|
+
// as flat names, not directories). Use sigv4.awsUriEncode (not
|
|
518
|
+
// encodeURIComponent, which leaves !*'() unescaped) so the wire path
|
|
519
|
+
// matches the bytes S3 canonicalizes the signature over — same encoder
|
|
520
|
+
// _keyToUrl uses for the put/get path.
|
|
521
|
+
var encKey = key.split("/").map(function (s) { return sigv4.awsUriEncode(s, true); }).join("/");
|
|
519
522
|
var uo = _internalUrl(endpoint, allowedProtocols);
|
|
520
523
|
if (pathStyle) {
|
|
521
524
|
uo.pathname = "/" + name + "/" + encKey;
|
|
@@ -86,9 +86,16 @@ function hmacSha256(key, data) {
|
|
|
86
86
|
// AWS-style URI encoding: same as RFC 3986 except path '/' may be preserved.
|
|
87
87
|
function awsUriEncode(str, encodeSlash) {
|
|
88
88
|
var out = "";
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
// Iterate by Unicode code point, not UTF-16 code unit. Array.from() keeps a
|
|
90
|
+
// non-BMP character's surrogate pair together (one element), so a key like
|
|
91
|
+
// "photo-<U+1F600>.jpg" encodes as a single UTF-8 sequence. Iterating by
|
|
92
|
+
// index would hand encodeURIComponent a lone surrogate, which throws
|
|
93
|
+
// "URIError: URI malformed". Output is byte-for-byte identical for the
|
|
94
|
+
// BMP/ASCII keys that are the overwhelming common case.
|
|
95
|
+
var cps = Array.from(str);
|
|
96
|
+
for (var i = 0; i < cps.length; i++) {
|
|
97
|
+
var ch = cps[i];
|
|
98
|
+
var c = ch.codePointAt(0);
|
|
92
99
|
if ((c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A) ||
|
|
93
100
|
(c >= 0x30 && c <= 0x39) ||
|
|
94
101
|
ch === "-" || ch === "_" || ch === "." || ch === "~") {
|
|
@@ -137,13 +144,24 @@ function canonicalHeaders(headers) {
|
|
|
137
144
|
return { canonical: canon, signed: signed.join(";") };
|
|
138
145
|
}
|
|
139
146
|
|
|
140
|
-
|
|
147
|
+
// AWS SigV4 canonical URI. Per the SigV4 spec, S3 (and S3-compatible stores +
|
|
148
|
+
// GCS's V4) URI-encode the path EXACTLY ONCE; every other AWS service (sqs,
|
|
149
|
+
// logs, sns, ...) encodes it TWICE. Callers build urlObj through the WHATWG URL
|
|
150
|
+
// parser, so urlObj.pathname is ALREADY the single-encoded wire form (a key
|
|
151
|
+
// "a b.txt" is "/a%20b.txt") and the request sends that pathname verbatim. So
|
|
152
|
+
// for S3/GCS the canonical path MUST equal the pathname as-is: a second
|
|
153
|
+
// awsUriEncode would sign "/a%2520b.txt", a path the wire never carries, giving
|
|
154
|
+
// SignatureDoesNotMatch (403) for any key with a space/+/&/unicode. For the
|
|
155
|
+
// double-encode services the second pass is the spec requirement. signRequest
|
|
156
|
+
// derives doubleEncodePath from the service; GCS's V4 signer passes false.
|
|
157
|
+
function canonicalRequest(method, urlObj, headers, payloadHash, doubleEncodePath) {
|
|
141
158
|
var canonHeaders = canonicalHeaders(headers);
|
|
142
159
|
var path = urlObj.pathname;
|
|
143
160
|
if (!path) path = "/";
|
|
161
|
+
var canonicalPath = doubleEncodePath ? awsUriEncode(path, false) : path;
|
|
144
162
|
return [
|
|
145
163
|
method.toUpperCase(),
|
|
146
|
-
|
|
164
|
+
canonicalPath,
|
|
147
165
|
canonicalQueryString(urlObj.searchParams),
|
|
148
166
|
canonHeaders.canonical,
|
|
149
167
|
canonHeaders.signed,
|
|
@@ -204,7 +222,11 @@ function signRequest(opts) {
|
|
|
204
222
|
headers["x-amz-security-token"] = opts.sessionToken;
|
|
205
223
|
}
|
|
206
224
|
|
|
207
|
-
|
|
225
|
+
// S3 single-encodes the canonical path; every other AWS service double-encodes
|
|
226
|
+
// it (see canonicalRequest). The path itself is "/" for the non-S3 callers
|
|
227
|
+
// (cloudwatch/sqs put params in the query or body), so this only changes the
|
|
228
|
+
// wire result for S3, where it fixes the long-standing double-encode 403.
|
|
229
|
+
var canon = canonicalRequest(opts.method, url, headers, opts.payloadHash, service !== "s3");
|
|
208
230
|
var credentialScope = dateStamp + "/" + opts.region + "/" + service + "/aws4_request";
|
|
209
231
|
var sts = stringToSign(amzDate, credentialScope, canon);
|
|
210
232
|
var signingKey = deriveSigningKey(opts.secretAccessKey, dateStamp, opts.region, service);
|
|
@@ -661,6 +683,16 @@ function create(config) {
|
|
|
661
683
|
etag: res.headers.etag,
|
|
662
684
|
lastModified: res.headers["last-modified"] ? Date.parse(res.headers["last-modified"]) : null,
|
|
663
685
|
};
|
|
686
|
+
}, function (e) {
|
|
687
|
+
// A missing key surfaces as the framework NOT_FOUND code — the same
|
|
688
|
+
// contract local.js head() exposes and that deleteKey already maps 404
|
|
689
|
+
// to — so existence probes via head() (e.g. the backup objectStore
|
|
690
|
+
// adapter's hasKey / statKey) get the uniform missing-key signal instead
|
|
691
|
+
// of a raw HTTP 404 they don't recognize.
|
|
692
|
+
if (e && e.statusCode === 404) {
|
|
693
|
+
throw _err("NOT_FOUND", "key not found: " + key, true);
|
|
694
|
+
}
|
|
695
|
+
throw e;
|
|
664
696
|
});
|
|
665
697
|
}
|
|
666
698
|
|
|
@@ -98,6 +98,11 @@ var KIND_TO_OTLP = Object.freeze({
|
|
|
98
98
|
function _attrToOtlp(attrs) {
|
|
99
99
|
// OTLP attribute shape: [{ key, value: { stringValue | intValue |
|
|
100
100
|
// doubleValue | boolValue | arrayValue: { values: [...] } } }, ...]
|
|
101
|
+
// Telemetry is a first-class EGRESS sink — scrub every value through the
|
|
102
|
+
// active redactor BEFORE serialization so a secret/PII attribute never
|
|
103
|
+
// reaches the collector (CWE-532). Redaction is baked into the encoder, not
|
|
104
|
+
// the call site, so no span/event/resource path can forget it.
|
|
105
|
+
attrs = observability().redactAttrs(attrs);
|
|
101
106
|
var out = [];
|
|
102
107
|
if (!attrs || typeof attrs !== "object") return out;
|
|
103
108
|
var keys = Object.keys(attrs);
|
|
@@ -316,7 +321,10 @@ function _keyValueToProto(kvObj) {
|
|
|
316
321
|
function _attrsToProto(attrs) {
|
|
317
322
|
// attrs is the raw `{ key: value }` operator attribute object; OTLP
|
|
318
323
|
// KeyValue gets emitted per entry with field 9 (attributes) on Span,
|
|
319
|
-
// field 1 (attributes) on Resource, etc.
|
|
324
|
+
// field 1 (attributes) on Resource, etc. Scrub every value through the
|
|
325
|
+
// active redactor BEFORE building the wire intermediate — the protobuf path
|
|
326
|
+
// is the same EGRESS sink as the JSON path and must not leak (CWE-532).
|
|
327
|
+
attrs = observability().redactAttrs(attrs);
|
|
320
328
|
if (!attrs || typeof attrs !== "object") return [];
|
|
321
329
|
var keys = Object.keys(attrs);
|
|
322
330
|
var out = new Array(keys.length);
|
|
@@ -55,6 +55,14 @@ var safeBuffer = lazyRequire(function () { return require("./safe-buffer"); });
|
|
|
55
55
|
var tracing = lazyRequire(function () { return require("./tracing"); });
|
|
56
56
|
var metrics = lazyRequire(function () { return require("./metrics"); });
|
|
57
57
|
|
|
58
|
+
// redact is the framework's central PII/secret scrubber. Lazy-loaded so
|
|
59
|
+
// the require graph stays acyclic at boot (redact lazy-pulls audit, which
|
|
60
|
+
// pulls observability back). Composed by the default telemetry redactor
|
|
61
|
+
// below so span/metric attribute VALUES are scrubbed before the OTLP
|
|
62
|
+
// exporter serializes them — CWE-532 (insertion of sensitive information
|
|
63
|
+
// into a telemetry/log egress sink).
|
|
64
|
+
var redact = lazyRequire(function () { return require("./redact"); });
|
|
65
|
+
|
|
58
66
|
// Operator-installed tap handler — wired via setTap(). When non-null,
|
|
59
67
|
// every observability event/tap dispatch routes here in addition to
|
|
60
68
|
// the framework's metrics module. Used by b.otelExport.create() so an
|
|
@@ -62,6 +70,26 @@ var metrics = lazyRequire(function () { return require("./metrics"); });
|
|
|
62
70
|
// emits internally.
|
|
63
71
|
var _externalTap = null;
|
|
64
72
|
|
|
73
|
+
// Telemetry-attribute redactor seam. Span / metric attribute VALUES are
|
|
74
|
+
// a first-class egress surface: a span attribute holding a user email,
|
|
75
|
+
// bearer token, or vault-sealed ciphertext is shipped verbatim to the
|
|
76
|
+
// OTLP collector unless it is scrubbed at the assembly boundary, the same
|
|
77
|
+
// way log-stream redacts every record before any sink sees it. Defaults
|
|
78
|
+
// ON — the default redactor composes b.redact.redact, passing the
|
|
79
|
+
// attribute key as the parent-key context so both field-name rules
|
|
80
|
+
// (authorization / token / session / password) and value-shape detectors
|
|
81
|
+
// (JWT / PEM / credit-card / SSN / connection-string) fire. CWE-532.
|
|
82
|
+
//
|
|
83
|
+
// The redactor is (value, key) → redactedValue. The exporter calls it for
|
|
84
|
+
// every attribute value; a thrown redactor drops the attribute rather
|
|
85
|
+
// than leaking it (the exporter enforces fail-toward-dropping), so a
|
|
86
|
+
// misbehaving custom redactor can never widen the egress surface.
|
|
87
|
+
function _defaultTelemetryRedactor(value, key) {
|
|
88
|
+
return redact().redact(value, { parentKey: typeof key === "string" ? key : null });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
var _telemetryRedactor = _defaultTelemetryRedactor;
|
|
92
|
+
|
|
65
93
|
function _safeMetricsTap(name, value, labels) {
|
|
66
94
|
try { metrics().tap(name, value, labels); }
|
|
67
95
|
catch (_e) { /* boot-order tolerance — metrics may not be loaded */ }
|
|
@@ -106,6 +134,99 @@ function setTap(handler) {
|
|
|
106
134
|
_externalTap = handler;
|
|
107
135
|
}
|
|
108
136
|
|
|
137
|
+
/**
|
|
138
|
+
* @primitive b.observability.setRedactor
|
|
139
|
+
* @signature b.observability.setRedactor(redactor)
|
|
140
|
+
* @since 0.14.27
|
|
141
|
+
* @related b.observability.getRedactor, b.redact.redact
|
|
142
|
+
*
|
|
143
|
+
* Override the redactor applied to every span / metric attribute VALUE
|
|
144
|
+
* before the OTLP exporter serializes it onto the wire. Telemetry is a
|
|
145
|
+
* first-class egress sink: an attribute holding a user email, bearer
|
|
146
|
+
* token, or secret would otherwise reach the collector in plaintext
|
|
147
|
+
* (CWE-532). Redaction is ON by default — the default redactor composes
|
|
148
|
+
* `b.redact.redact` and fires both field-name and value-shape rules; this
|
|
149
|
+
* setter only lets an operator swap in a stricter or domain-specific
|
|
150
|
+
* scrubber.
|
|
151
|
+
*
|
|
152
|
+
* The redactor is `redactor(value, key)` and returns the value to export.
|
|
153
|
+
* It runs on the export hot path, so a throw is caught and the attribute
|
|
154
|
+
* is dropped (never exported raw) — a redactor that throws can only
|
|
155
|
+
* shrink the egress surface, never widen it. Pass `null` to restore the
|
|
156
|
+
* default `b.redact.redact`-backed redactor.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* b.observability.setRedactor(function (value, key) {
|
|
160
|
+
* if (key === "enduser.id") return "[REDACTED]";
|
|
161
|
+
* return b.redact.redact(value, { parentKey: key });
|
|
162
|
+
* });
|
|
163
|
+
* b.observability.setRedactor(null); // restore the default
|
|
164
|
+
*/
|
|
165
|
+
function setRedactor(redactor) {
|
|
166
|
+
if (redactor !== null && typeof redactor !== "function") {
|
|
167
|
+
throw new TypeError("observability.setRedactor: redactor must be a function or null, got " +
|
|
168
|
+
typeof redactor);
|
|
169
|
+
}
|
|
170
|
+
_telemetryRedactor = redactor === null ? _defaultTelemetryRedactor : redactor;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @primitive b.observability.getRedactor
|
|
175
|
+
* @signature b.observability.getRedactor()
|
|
176
|
+
* @since 0.14.27
|
|
177
|
+
* @related b.observability.setRedactor, b.redact.redact
|
|
178
|
+
*
|
|
179
|
+
* Return the redactor currently applied to span / metric attribute
|
|
180
|
+
* values on the OTLP egress path. The OTLP exporter calls this to scrub
|
|
181
|
+
* every attribute value before serialization; operators rarely need it
|
|
182
|
+
* directly. When no override has been installed it returns the default
|
|
183
|
+
* `b.redact.redact`-backed redactor.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* var redactor = b.observability.getRedactor();
|
|
187
|
+
* redactor("Bearer eyJabc.eyJdef.sig", "authorization");
|
|
188
|
+
* // → "[REDACTED]" (field-name rule on the "authorization" key)
|
|
189
|
+
*/
|
|
190
|
+
function getRedactor() {
|
|
191
|
+
return _telemetryRedactor;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @primitive b.observability.redactAttrs
|
|
196
|
+
* @signature b.observability.redactAttrs(attrs)
|
|
197
|
+
* @since 0.15.4
|
|
198
|
+
* @related b.observability.getRedactor, b.observability.setRedactor
|
|
199
|
+
*
|
|
200
|
+
* Run every value of a telemetry attribute map through the active redactor and
|
|
201
|
+
* return a NEW `{ key: redactedValue }` object. The OTLP exporters call this on
|
|
202
|
+
* span, span-event, metric, and resource attributes before serialization so no
|
|
203
|
+
* attribute value crosses the egress boundary unscrubbed (CWE-532: insertion of
|
|
204
|
+
* sensitive information into an externally-shipped sink). A key whose redactor
|
|
205
|
+
* throws is DROPPED — failing toward dropping, never exporting the raw value;
|
|
206
|
+
* `null` / `undefined` values pass through for the type-encoder to handle.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* b.observability.redactAttrs({ "http.method": "GET", authorization: "Bearer x" });
|
|
210
|
+
* // → { "http.method": "GET", authorization: "[REDACTED]" }
|
|
211
|
+
*/
|
|
212
|
+
function redactAttrs(attrs) {
|
|
213
|
+
var out = {};
|
|
214
|
+
if (!attrs || typeof attrs !== "object") return out;
|
|
215
|
+
var redactor = getRedactor();
|
|
216
|
+
var keys = Object.keys(attrs);
|
|
217
|
+
for (var i = 0; i < keys.length; i++) {
|
|
218
|
+
var k = keys[i];
|
|
219
|
+
try {
|
|
220
|
+
out[k] = redactor(attrs[k], k);
|
|
221
|
+
} catch (_e) {
|
|
222
|
+
// redactor threw on the export hot path — drop the attribute rather than
|
|
223
|
+
// fall through to the raw value. A throwing redactor must never widen the
|
|
224
|
+
// egress surface, and must never crash the request that produced the span.
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
|
|
109
230
|
/**
|
|
110
231
|
* @primitive b.observability.tap
|
|
111
232
|
* @signature b.observability.tap(name, attrs, fn)
|
|
@@ -750,6 +871,9 @@ module.exports = {
|
|
|
750
871
|
safeEvent: safeEvent,
|
|
751
872
|
timed: timed,
|
|
752
873
|
setTap: setTap,
|
|
874
|
+
setRedactor: setRedactor,
|
|
875
|
+
getRedactor: getRedactor,
|
|
876
|
+
redactAttrs: redactAttrs,
|
|
753
877
|
SEMCONV: SEMCONV,
|
|
754
878
|
traceContext: traceContext,
|
|
755
879
|
baggage: baggage,
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
var C = require("./constants");
|
|
43
43
|
var canonicalJson = require("./canonical-json");
|
|
44
44
|
var httpClient = require("./http-client");
|
|
45
|
+
var observability = require("./observability");
|
|
45
46
|
var safeAsync = require("./safe-async");
|
|
46
47
|
var validateOpts = require("./validate-opts");
|
|
47
48
|
var { defineClass } = require("./framework-error");
|
|
@@ -67,11 +68,19 @@ var TEMPORALITY_DELTA = 1;
|
|
|
67
68
|
// ---- attribute encoding ----
|
|
68
69
|
// OTLP attributes are KeyValue with typed `value` fields:
|
|
69
70
|
// { key, value: { stringValue | intValue | doubleValue | boolValue } }
|
|
71
|
+
// Telemetry is a first-class EGRESS sink — an attribute value holding a user
|
|
72
|
+
// email, bearer token, or vault-sealed ciphertext would otherwise be serialized
|
|
73
|
+
// verbatim onto the OTLP wire (CWE-532). observability.redactAttrs scrubs every
|
|
74
|
+
// value through the active redactor (operator overrides via setRedactor take
|
|
75
|
+
// effect without re-creating the exporter) and drops any key whose redactor
|
|
76
|
+
// throws — failing toward dropping, never leaking, on the export hot path.
|
|
70
77
|
function _attrsToOtlp(attrs) {
|
|
71
|
-
|
|
78
|
+
attrs = observability.redactAttrs(attrs);
|
|
72
79
|
var out = [];
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
if (!attrs || typeof attrs !== "object") return out;
|
|
81
|
+
var keys = Object.keys(attrs);
|
|
82
|
+
for (var i = 0; i < keys.length; i++) {
|
|
83
|
+
var k = keys[i];
|
|
75
84
|
var v = attrs[k];
|
|
76
85
|
var kv;
|
|
77
86
|
if (typeof v === "string") kv = { stringValue: v };
|