@blamejs/blamejs-shop 0.5.12 → 0.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/sales-tax-filings.js +143 -0
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -175,10 +175,20 @@ function _writeString(buf, value, offset, width) {
|
|
|
175
175
|
|
|
176
176
|
function _readOctal(buf, offset, width) {
|
|
177
177
|
// Read an octal-encoded field. Terminator may be space or NUL.
|
|
178
|
+
//
|
|
179
|
+
// POSIX permits numeric fields to be LEFT-padded with spaces (as well as
|
|
180
|
+
// zeros) — star, BSD tar, and several Java/Perl tar libraries emit them,
|
|
181
|
+
// and GNU tar / libarchive skip them. Treating a leading space as a
|
|
182
|
+
// terminator silently misreads such a field as 0 (a parser-differential:
|
|
183
|
+
// the reader would disagree with every other tar on the same bytes, and a
|
|
184
|
+
// misread size desyncs the block walker). Skip leading-space padding first;
|
|
185
|
+
// a space or NUL AFTER the digits still terminates the field.
|
|
186
|
+
var i = 0;
|
|
187
|
+
while (i < width && buf[offset + i] === 0x20) i += 1; // ASCII space (0x20) leading padding per POSIX numeric field
|
|
178
188
|
var s = "";
|
|
179
|
-
for (
|
|
189
|
+
for (; i < width; i += 1) {
|
|
180
190
|
var c = buf[offset + i];
|
|
181
|
-
if (c === 0x20 || c === 0) break; // ASCII space (0x20) + NUL (0x00) field terminators
|
|
191
|
+
if (c === 0x20 || c === 0) break; // ASCII space (0x20) + NUL (0x00) field terminators after digits
|
|
182
192
|
if (c < 0x30 || c > 0x37) { // ASCII '0' (0x30) .. '7' (0x37) octal digits
|
|
183
193
|
throw new TarError("archive-tar/bad-octal",
|
|
184
194
|
"non-octal byte 0x" + c.toString(16) + " at offset " + (offset + i)); // radix=16 for diagnostic hex format
|
|
@@ -625,7 +625,7 @@ function create(opts) {
|
|
|
625
625
|
|
|
626
626
|
/**
|
|
627
627
|
* @primitive b.argParser.parseRaw
|
|
628
|
-
* @signature b.argParser.parseRaw(argv)
|
|
628
|
+
* @signature b.argParser.parseRaw(argv, opts?)
|
|
629
629
|
* @since 0.8.48
|
|
630
630
|
* @status stable
|
|
631
631
|
* @related b.argParser.create
|
|
@@ -638,6 +638,21 @@ function create(opts) {
|
|
|
638
638
|
* value`, `--key=value`, and bare `--bool`. `--` terminates flag
|
|
639
639
|
* parsing.
|
|
640
640
|
*
|
|
641
|
+
* Pass `opts.booleanNames` (an array of long-flag names) to declare flags
|
|
642
|
+
* that never consume a following token as their value — a bare
|
|
643
|
+
* `--version` stays boolean instead of swallowing the next token, so
|
|
644
|
+
* `--version foo` yields `flags.version === true` with `foo` left as a
|
|
645
|
+
* positional. An inline `--version=x` still records the explicit value.
|
|
646
|
+
*
|
|
647
|
+
* A flag repeated on the command line accumulates every occurrence into
|
|
648
|
+
* an array, in order — `--watch a --watch b` yields `["a", "b"]`, not
|
|
649
|
+
* just the last value. A flag seen once stays a scalar. This keeps
|
|
650
|
+
* repeatable flags (the `dev` command's `--arg` / `--watch` / `--ignore`)
|
|
651
|
+
* from silently dropping all but the final occurrence.
|
|
652
|
+
*
|
|
653
|
+
* @opts
|
|
654
|
+
* booleanNames: string[], // long-flag names that never consume a following token as a value (default: none)
|
|
655
|
+
*
|
|
641
656
|
* @example
|
|
642
657
|
* var r = b.argParser.parseRaw(
|
|
643
658
|
* ["build", "--target=node", "-v", "--out", "dist", "--", "extra"]);
|
|
@@ -646,11 +661,39 @@ function create(opts) {
|
|
|
646
661
|
* r.flags.v; // → true
|
|
647
662
|
* r.flags.out; // → "dist"
|
|
648
663
|
*/
|
|
649
|
-
|
|
664
|
+
// Record a parsed flag, accumulating repeats. First occurrence stores the
|
|
665
|
+
// scalar as-is (so single-value flags keep their string/boolean shape);
|
|
666
|
+
// the second and later occurrences promote the entry to an array holding
|
|
667
|
+
// every value in argv order. Without this a repeated flag would overwrite
|
|
668
|
+
// the earlier value and a repeatable flag could never yield more than one.
|
|
669
|
+
function _assignFlag(flags, name, val) {
|
|
670
|
+
if (Object.prototype.hasOwnProperty.call(flags, name)) {
|
|
671
|
+
var prev = flags[name];
|
|
672
|
+
if (Array.isArray(prev)) {
|
|
673
|
+
prev.push(val);
|
|
674
|
+
} else {
|
|
675
|
+
flags[name] = [prev, val];
|
|
676
|
+
}
|
|
677
|
+
} else {
|
|
678
|
+
flags[name] = val;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
function parseRaw(argv, opts) {
|
|
650
683
|
if (!Array.isArray(argv)) {
|
|
651
684
|
throw new ArgParserError("arg-parser/argv-not-array",
|
|
652
685
|
"argv must be an array of strings");
|
|
653
686
|
}
|
|
687
|
+
opts = opts || {};
|
|
688
|
+
// Long-flag names declared boolean never consume a following token as a
|
|
689
|
+
// value (a bare `--version` stays true instead of swallowing the next
|
|
690
|
+
// token). Inline `--flag=value` still records the explicit value.
|
|
691
|
+
var booleanNames = Object.create(null);
|
|
692
|
+
if (Array.isArray(opts.booleanNames)) {
|
|
693
|
+
for (var bn = 0; bn < opts.booleanNames.length; bn++) {
|
|
694
|
+
booleanNames[opts.booleanNames[bn]] = true;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
654
697
|
var pos = [];
|
|
655
698
|
var flags = Object.create(null);
|
|
656
699
|
for (var i = 0; i < argv.length; i++) {
|
|
@@ -670,7 +713,8 @@ function parseRaw(argv) {
|
|
|
670
713
|
if (eq !== -1) {
|
|
671
714
|
val = name.slice(eq + 1);
|
|
672
715
|
name = name.slice(0, eq);
|
|
673
|
-
} else if (i + 1 < argv.length && argv[i + 1].indexOf("--") !== 0
|
|
716
|
+
} else if (i + 1 < argv.length && argv[i + 1].indexOf("--") !== 0 &&
|
|
717
|
+
booleanNames[name] !== true) {
|
|
674
718
|
val = argv[++i];
|
|
675
719
|
} else {
|
|
676
720
|
val = true;
|
|
@@ -679,14 +723,14 @@ function parseRaw(argv) {
|
|
|
679
723
|
throw new ArgParserError("arg-parser/argv-forbidden-name",
|
|
680
724
|
"flag '--" + name + "' is reserved");
|
|
681
725
|
}
|
|
682
|
-
flags
|
|
726
|
+
_assignFlag(flags, name, val);
|
|
683
727
|
} else if (tok.indexOf("-") === 0 && tok.length === 2) {
|
|
684
728
|
var s = tok.slice(1);
|
|
685
729
|
if (pick.isPoisonedKey(s)) {
|
|
686
730
|
throw new ArgParserError("arg-parser/argv-forbidden-name",
|
|
687
731
|
"flag '-" + s + "' is reserved");
|
|
688
732
|
}
|
|
689
|
-
flags
|
|
733
|
+
_assignFlag(flags, s, true);
|
|
690
734
|
} else {
|
|
691
735
|
pos.push(tok);
|
|
692
736
|
}
|
|
@@ -132,6 +132,18 @@ function readNode(buf, offset) {
|
|
|
132
132
|
for (var i = 0; i < lenOctets; i += 1) {
|
|
133
133
|
length = (length * 256) + buf[offset + headerLen + i]; // base-256 length bytes
|
|
134
134
|
}
|
|
135
|
+
// X.690 §10.1: DER requires the MINIMUM number of length octets. Long
|
|
136
|
+
// form is only permitted for lengths >= 128, and must carry no leading-
|
|
137
|
+
// zero octet — reject both non-minimal forms so an attacker-supplied
|
|
138
|
+
// certificate / CMS / OCSP response cannot smuggle a BER/DER parser-
|
|
139
|
+
// differential encoding through the shared walker. The decoder already
|
|
140
|
+
// refuses every other BER-ism (indefinite length, non-minimal OID
|
|
141
|
+
// subidentifiers, non-minimal high-tag-number tags); enforcing minimal
|
|
142
|
+
// lengths closes the remaining gap.
|
|
143
|
+
if (length < 128 || buf[offset + headerLen] === 0) { // X.690 §10.1 short-form boundary / no leading-zero octet
|
|
144
|
+
throw new Asn1Error("asn1/length-non-minimal",
|
|
145
|
+
"long-form length is not DER-minimal (length=" + length + ")");
|
|
146
|
+
}
|
|
135
147
|
headerLen += lenOctets;
|
|
136
148
|
}
|
|
137
149
|
|
|
@@ -204,6 +204,24 @@ function _computeFingerprint(publicKeyPem) {
|
|
|
204
204
|
// untouched). Changing this invalidates every prior anchor.
|
|
205
205
|
var ANCHOR_FORMAT = "blamejs-chain-anchor-v1";
|
|
206
206
|
|
|
207
|
+
// The anchor signed-bytes layout below is newline-delimited, so a literal
|
|
208
|
+
// newline inside any operator-influenced string field (format / tipHash /
|
|
209
|
+
// prevTipHash) would let content migrate across a field boundary WITHOUT
|
|
210
|
+
// changing the signed bytes: two different { tipHash, prevTipHash } splits
|
|
211
|
+
// collide on one signature, so a signature minted for one split verifies for a
|
|
212
|
+
// different split. That defeats the "prevTipHash is bound into the signature"
|
|
213
|
+
// linkage guarantee — an attacker could rewrite the apparent tip / linkage of a
|
|
214
|
+
// stored anchor while keeping verify() happy. counter + createdAt are numbers
|
|
215
|
+
// (String() of a finite number can never contain the delimiter), so only the
|
|
216
|
+
// three string fields need guarding. Reject the delimiter at BOTH sign time
|
|
217
|
+
// (so no ambiguous signature is ever minted) and verify time (so a pre-existing
|
|
218
|
+
// or hand-crafted ambiguous anchor is refused, not accepted). The wire format
|
|
219
|
+
// stays byte-identical for every legitimate (delimiter-free) anchor.
|
|
220
|
+
var ANCHOR_FIELD_DELIMITER = "\n";
|
|
221
|
+
function _containsAnchorDelimiter(s) {
|
|
222
|
+
return typeof s === "string" && s.indexOf(ANCHOR_FIELD_DELIMITER) !== -1;
|
|
223
|
+
}
|
|
224
|
+
|
|
207
225
|
// Build the canonical signed bytes for one anchor. Fixed multi-line layout (no
|
|
208
226
|
// JSON serializer quirks). prevTipHash IS part of the signed payload, so the
|
|
209
227
|
// link between consecutive anchors is tamper-evident — an attacker cannot
|
|
@@ -878,10 +896,20 @@ function _normalizeTip(tip, fnLabel) {
|
|
|
878
896
|
throw _err("ANCHOR_BAD_TIPHASH",
|
|
879
897
|
"auditSign." + fnLabel + ": tip.tipHash must be a non-empty string");
|
|
880
898
|
}
|
|
899
|
+
if (_containsAnchorDelimiter(tip.tipHash)) {
|
|
900
|
+
throw _err("ANCHOR_BAD_TIPHASH",
|
|
901
|
+
"auditSign." + fnLabel + ": tip.tipHash must not contain a newline (the anchor " +
|
|
902
|
+
"record delimiter — it would make the signed bytes ambiguous)");
|
|
903
|
+
}
|
|
881
904
|
if (tip.prevTipHash != null && typeof tip.prevTipHash !== "string") {
|
|
882
905
|
throw _err("ANCHOR_BAD_PREV",
|
|
883
906
|
"auditSign." + fnLabel + ": tip.prevTipHash, when present, must be a string");
|
|
884
907
|
}
|
|
908
|
+
if (_containsAnchorDelimiter(tip.prevTipHash)) {
|
|
909
|
+
throw _err("ANCHOR_BAD_PREV",
|
|
910
|
+
"auditSign." + fnLabel + ": tip.prevTipHash must not contain a newline (the anchor " +
|
|
911
|
+
"record delimiter — it would make the signed bytes ambiguous)");
|
|
912
|
+
}
|
|
885
913
|
return {
|
|
886
914
|
counter: counter,
|
|
887
915
|
tipHash: tip.tipHash,
|
|
@@ -916,7 +944,9 @@ function _normalizeTip(tip, fnLabel) {
|
|
|
916
944
|
* that key store (not fully store-free) — keep the history with the anchors.
|
|
917
945
|
*
|
|
918
946
|
* Throws `AuditSignError` (`ANCHOR_BAD_TIP` / `ANCHOR_BAD_COUNTER` /
|
|
919
|
-
* `ANCHOR_BAD_TIPHASH` / `ANCHOR_BAD_PREV`) on a malformed
|
|
947
|
+
* `ANCHOR_BAD_TIPHASH` / `ANCHOR_BAD_PREV` / `ANCHOR_BAD_FORMAT`) on a malformed
|
|
948
|
+
* tip — including any `format` / `tipHash` / `prevTipHash` that carries a
|
|
949
|
+
* newline, which would make the signed bytes ambiguous;
|
|
920
950
|
* `audit-sign/not-initialized` when `init()` has not been awaited.
|
|
921
951
|
*
|
|
922
952
|
* @opts
|
|
@@ -934,6 +964,11 @@ function anchor(tip, opts) {
|
|
|
934
964
|
_requireInit();
|
|
935
965
|
opts = opts || {};
|
|
936
966
|
var t = _normalizeTip(tip, "anchor");
|
|
967
|
+
if (_containsAnchorDelimiter(opts.format)) {
|
|
968
|
+
throw _err("ANCHOR_BAD_FORMAT",
|
|
969
|
+
"auditSign.anchor: opts.format must not contain a newline (the anchor " +
|
|
970
|
+
"record delimiter — it would make the signed bytes ambiguous)");
|
|
971
|
+
}
|
|
937
972
|
var format = (typeof opts.format === "string" && opts.format.length > 0) ? opts.format : ANCHOR_FORMAT;
|
|
938
973
|
var createdAt = (typeof opts.createdAt === "number" && isFinite(opts.createdAt)) ? opts.createdAt : Date.now();
|
|
939
974
|
var payload = anchorPayload(t.counter, t.tipHash, t.prevTipHash, createdAt, format);
|
|
@@ -962,6 +997,17 @@ function _verifyOneAnchor(a) {
|
|
|
962
997
|
if (typeof a.counter !== "number" || !isFinite(a.counter)) {
|
|
963
998
|
return { ok: false, reason: "anchor counter is not a finite number" };
|
|
964
999
|
}
|
|
1000
|
+
// Fail closed on a delimiter-bearing field: the newline-delimited signed
|
|
1001
|
+
// bytes are ambiguous when format / tipHash / prevTipHash carries the
|
|
1002
|
+
// delimiter, so ONE signature can be valid for several different logical
|
|
1003
|
+
// { tipHash, prevTipHash } splits. Refuse rather than accept the ambiguity —
|
|
1004
|
+
// a legitimate anchor is delimiter-free (anchor() rejects a newline field at
|
|
1005
|
+
// sign time), so this only ever rejects a hand-crafted / boundary-shifted one.
|
|
1006
|
+
if (_containsAnchorDelimiter(a.tipHash) ||
|
|
1007
|
+
_containsAnchorDelimiter(a.format) ||
|
|
1008
|
+
_containsAnchorDelimiter(a.prevTipHash)) {
|
|
1009
|
+
return { ok: false, reason: "anchor field contains the record delimiter (ambiguous canonicalization)" };
|
|
1010
|
+
}
|
|
965
1011
|
var pub = getPublicKeyByFingerprint(a.publicKeyFingerprint);
|
|
966
1012
|
if (!pub) {
|
|
967
1013
|
return { ok: false, reason: "no audit-signing key on record for this anchor's fingerprint" };
|
|
@@ -218,6 +218,45 @@ async function _insertCheckpoint(values) {
|
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
// A concurrent anchor of the SAME tip loses the race to INSERT the
|
|
222
|
+
// atMonotonicCounter (UNIQUE): two anchors of one tip sign the identical
|
|
223
|
+
// payload, so the collision means the counter is ALREADY anchored, not a
|
|
224
|
+
// corruption. Recognize it BACKEND-AGNOSTICALLY so the loser returns null like
|
|
225
|
+
// the skipIfUnchanged "already anchored" path instead of throwing. Each driver
|
|
226
|
+
// surfaces the violation differently: SQLite names the column in the message
|
|
227
|
+
// (`... audit_checkpoints.atMonotonicCounter`); Postgres carries the unique
|
|
228
|
+
// INDEX name (idx_chkpt_counter) in `constraint`/`detail` with SQLSTATE 23505;
|
|
229
|
+
// MySQL reports the key name in `sqlMessage` with errno 1062. Gather every such
|
|
230
|
+
// field, and require BOTH a reference to the counter column OR its unique index
|
|
231
|
+
// AND a uniqueness signal, so no unrelated error is ever swallowed (anything
|
|
232
|
+
// unrecognized rethrows — fail-closed).
|
|
233
|
+
// Tokens that name the counter column (sqlite) or its unique index (pg/mysql).
|
|
234
|
+
var _DUP_COUNTER_REFS = ["atmonotoniccounter", "chkpt_counter"];
|
|
235
|
+
// A uniqueness-violation signal on any backend: sqlite message/code, postgres
|
|
236
|
+
// text/SQLSTATE 23505, mysql text/code-name/errno 1062.
|
|
237
|
+
var _DUP_UNIQUE_SIGNALS = [
|
|
238
|
+
"unique constraint failed", "sqlite_constraint", "duplicate key",
|
|
239
|
+
"23505", "duplicate entry", "er_dup_entry", "1062",
|
|
240
|
+
];
|
|
241
|
+
function _errorTextContainsAny(text, needles) {
|
|
242
|
+
for (var i = 0; i < needles.length; i++) {
|
|
243
|
+
if (text.indexOf(needles[i]) !== -1) return true;
|
|
244
|
+
}
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
function _isDuplicateCheckpointCounter(e) {
|
|
248
|
+
if (!e) return false;
|
|
249
|
+
var parts = [e.message, e.detail, e.constraint, e.sqlMessage, e.table, e.code, e.errno];
|
|
250
|
+
var text = "";
|
|
251
|
+
for (var i = 0; i < parts.length; i++) {
|
|
252
|
+
if (parts[i] != null) text += " " + String(parts[i]);
|
|
253
|
+
}
|
|
254
|
+
if (typeof e.toString === "function") text += " " + e.toString();
|
|
255
|
+
text = text.toLowerCase();
|
|
256
|
+
return _errorTextContainsAny(text, _DUP_COUNTER_REFS) &&
|
|
257
|
+
_errorTextContainsAny(text, _DUP_UNIQUE_SIGNALS);
|
|
258
|
+
}
|
|
259
|
+
|
|
221
260
|
async function _upsertAuditTip(counter, rowHash, signedAt, fencingToken) {
|
|
222
261
|
// Cluster-mode only. Single atomic INSERT … ON CONFLICT … DO UPDATE
|
|
223
262
|
// … WHERE … RETURNING. The WHERE clause is the canonical
|
|
@@ -1001,9 +1040,30 @@ async function checkpoint(opts) {
|
|
|
1001
1040
|
|
|
1002
1041
|
var ckptId = generateToken(TRACE_ID_BYTES);
|
|
1003
1042
|
var fencingToken = cluster.fencingToken();
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1043
|
+
try {
|
|
1044
|
+
await _insertCheckpoint(
|
|
1045
|
+
[ckptId, createdAt, counter, tip.rowHash, signature, pubFp, fencingToken]
|
|
1046
|
+
);
|
|
1047
|
+
} catch (e) {
|
|
1048
|
+
// Lost the INSERT race to another anchor of this same tip counter: the
|
|
1049
|
+
// counter is already anchored (both anchors sign the identical payload).
|
|
1050
|
+
// In SINGLE-NODE mode that is purely idempotent — return null like the
|
|
1051
|
+
// skipIfUnchanged "already anchored" path and let the winner own the
|
|
1052
|
+
// sidecar write below. In CLUSTER mode the duplicate can instead mean a
|
|
1053
|
+
// NEWER LEADER anchored this tip while we still hold an OLDER fencingToken,
|
|
1054
|
+
// so we must NOT silently swallow it: run the audit-tip fence first, whose
|
|
1055
|
+
// fencing-token WHERE guard throws FENCED_OUT when a higher token has been
|
|
1056
|
+
// stored — surfacing the leadership-loss step-down instead of a benign
|
|
1057
|
+
// null. If the fence passes (a same-node concurrent race), it is idempotent.
|
|
1058
|
+
// Any non-duplicate error rethrows.
|
|
1059
|
+
if (_isDuplicateCheckpointCounter(e)) {
|
|
1060
|
+
if (cluster.isClusterMode()) {
|
|
1061
|
+
await _upsertAuditTip(counter, tip.rowHash, String(createdAt), fencingToken);
|
|
1062
|
+
}
|
|
1063
|
+
return null;
|
|
1064
|
+
}
|
|
1065
|
+
throw e;
|
|
1066
|
+
}
|
|
1007
1067
|
|
|
1008
1068
|
// Update rollback-detection sidecar (single-node) or audit-tip row
|
|
1009
1069
|
// (cluster mode).
|
|
@@ -1739,12 +1799,14 @@ function generateActorBindingTriggerSql(opts) {
|
|
|
1739
1799
|
// so operator-supplied opts.column / opts.tableName / opts.roleMappingFn
|
|
1740
1800
|
// can't reach raw concatenation. PostgreSQL + SQLite both use the
|
|
1741
1801
|
// double-quote dialect.
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
var
|
|
1745
|
-
var
|
|
1802
|
+
// allowReserved: parity with b.db.from() — an operator column/table/function
|
|
1803
|
+
// named as a SQL keyword must quote here too (safe once quoted).
|
|
1804
|
+
var qColumn = safeSql.quoteIdentifier(columnRaw, "postgres", { allowReserved: true });
|
|
1805
|
+
var qTable = safeSql.quoteIdentifier(tableNameRaw, "postgres", { allowReserved: true });
|
|
1806
|
+
var qFn = safeSql.quoteIdentifier(fnNameRaw, "postgres", { allowReserved: true });
|
|
1807
|
+
var qTrig = safeSql.quoteIdentifier(trigNameRaw, "postgres", { allowReserved: true });
|
|
1746
1808
|
var qRoleMapFn = opts.roleMappingFn
|
|
1747
|
-
? safeSql.quoteIdentifier(opts.roleMappingFn, "postgres")
|
|
1809
|
+
? safeSql.quoteIdentifier(opts.roleMappingFn, "postgres", { allowReserved: true })
|
|
1748
1810
|
: null;
|
|
1749
1811
|
var allowList = allowRoles.length === 0 ? "" :
|
|
1750
1812
|
" IF current_user IN (" +
|
|
@@ -1919,4 +1981,5 @@ module.exports = {
|
|
|
1919
1981
|
CHECKPOINT_FORMAT: CHECKPOINT_FORMAT,
|
|
1920
1982
|
FRAMEWORK_NAMESPACES: FRAMEWORK_NAMESPACES,
|
|
1921
1983
|
_resetForTest: _resetForTest,
|
|
1984
|
+
_isDuplicateCheckpointCounter: _isDuplicateCheckpointCounter, // test seam: cross-backend dup-counter recognition
|
|
1922
1985
|
};
|
|
@@ -278,6 +278,13 @@ function create(opts) {
|
|
|
278
278
|
};
|
|
279
279
|
Object.assign(req, opts.httpClientOpts || {});
|
|
280
280
|
if (opts.allowHttp === true) req.allowedProtocols = safeUrl.ALLOW_HTTP_ALL;
|
|
281
|
+
// Thread the operator's explicit SSRF waiver onto the backchannel-auth
|
|
282
|
+
// and token POSTs too — create() already hands allowInternal to the
|
|
283
|
+
// inner OAuth client for discovery / JWKS, so an internal-network IdP
|
|
284
|
+
// whose discovery resolves would still have its /bc-auth and /token
|
|
285
|
+
// requests blocked here without this. Matches oauth's per-request
|
|
286
|
+
// threading; the SSRF guard stays on unless allowInternal is set.
|
|
287
|
+
if (opts.allowInternal != null) req.allowInternal = opts.allowInternal;
|
|
281
288
|
var res = await hc.request(req);
|
|
282
289
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
283
290
|
var bodyText = res.body ? res.body.toString("utf8") : "";
|
|
@@ -625,11 +632,16 @@ function create(opts) {
|
|
|
625
632
|
// node:http's normalization could re-introduce the unreachable
|
|
626
633
|
// branch). Read lowercase only.
|
|
627
634
|
var authzHeader = req.headers["authorization"];
|
|
628
|
-
|
|
635
|
+
// RFC 7235 §2.1 — the auth-scheme token ("Bearer") is ASCII
|
|
636
|
+
// case-insensitive; match it case-insensitively so a spec-compliant
|
|
637
|
+
// `bearer <token>` sender isn't wrongly refused. The token that follows
|
|
638
|
+
// keeps its case (it is compared verbatim below).
|
|
639
|
+
var BEARER_PREFIX = "bearer ";
|
|
640
|
+
if (!authzHeader || authzHeader.slice(0, BEARER_PREFIX.length).toLowerCase() !== BEARER_PREFIX) {
|
|
629
641
|
throw new AuthError("auth-ciba/missing-bearer",
|
|
630
642
|
"ciba.parseNotification: Authorization: Bearer header missing");
|
|
631
643
|
}
|
|
632
|
-
var presented = authzHeader.
|
|
644
|
+
var presented = authzHeader.slice(BEARER_PREFIX.length).trim();
|
|
633
645
|
if (presented.length === 0 || !clientNotificationToken) {
|
|
634
646
|
throw new AuthError("auth-ciba/bad-bearer",
|
|
635
647
|
"ciba.parseNotification: empty bearer or no expected token configured");
|
|
@@ -344,12 +344,16 @@ function _parseNextUpdate(s) {
|
|
|
344
344
|
return d;
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
//
|
|
348
|
-
//
|
|
349
|
-
//
|
|
350
|
-
|
|
347
|
+
// Single source of truth for the BLOB-trust decision: JWS + x5c-chain verify
|
|
348
|
+
// against the supplied trust roots, payload-shape validation, AND the
|
|
349
|
+
// stale-BLOB refusal. fetch() (operator-supplied roots via caCertificate) and
|
|
350
|
+
// _verifyAndParseBlob (default vendored roots) BOTH route here so no check can
|
|
351
|
+
// ever be present on one path but missing on the other. The stale-refusal used
|
|
352
|
+
// to live only in this helper's caller-inlined twin, so the operator-facing
|
|
353
|
+
// fetch path silently accepted (and cached) a signed-but-expired BLOB; keeping
|
|
354
|
+
// one body closes that class.
|
|
355
|
+
function _verifyBlobWithRoots(token, rootPems) {
|
|
351
356
|
var jws = _parseJws(token);
|
|
352
|
-
var rootPems = _resolveRoots(undefined);
|
|
353
357
|
var chain = _validateChain(jws.header.x5c, rootPems);
|
|
354
358
|
_verifyJws(jws, chain[0]);
|
|
355
359
|
var payload = jws.payload;
|
|
@@ -366,19 +370,19 @@ function _verifyAndParseBlob(token) {
|
|
|
366
370
|
throw new FidoMds3Error("fido-mds3/bad-payload",
|
|
367
371
|
"BLOB payload 'nextUpdate' missing or not YYYY-MM-DD: " + payload.nextUpdate);
|
|
368
372
|
}
|
|
369
|
-
// Stale-BLOB refusal
|
|
370
|
-
//
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
//
|
|
373
|
+
// Stale-BLOB refusal (FIDO MDS3 section 3.1.7): clients SHOULD refresh by
|
|
374
|
+
// nextUpdate; a BLOB whose nextUpdate is already in the past is not safe to
|
|
375
|
+
// trust even though its cert chain still validates. Flooring the staleness to
|
|
376
|
+
// MIN_CACHE_TTL_MS in _ttlFromNextUpdate is not enough on its own -- the BLOB
|
|
377
|
+
// itself must be refused, or an attacker serving an ancient signed-but-
|
|
378
|
+
// expired BLOB keeps operators pinned to a revoked-authenticator list frozen
|
|
379
|
+
// at that time. Refuse at parse time so neither fetch nor a cache lookup ever
|
|
380
|
+
// honors it.
|
|
377
381
|
if (nextUpdate.getTime() < Date.now()) {
|
|
378
382
|
throw new FidoMds3Error("fido-mds3/blob-stale",
|
|
379
383
|
"BLOB payload nextUpdate \"" + payload.nextUpdate +
|
|
380
|
-
"\" is in the past
|
|
381
|
-
"(FIDO MDS3
|
|
384
|
+
"\" is in the past -- refusing to trust a stale metadata BLOB " +
|
|
385
|
+
"(FIDO MDS3 section 3.1.7)");
|
|
382
386
|
}
|
|
383
387
|
return {
|
|
384
388
|
entries: payload.entries,
|
|
@@ -388,6 +392,13 @@ function _verifyAndParseBlob(token) {
|
|
|
388
392
|
};
|
|
389
393
|
}
|
|
390
394
|
|
|
395
|
+
// Internal verify-blob helper used by tests to exercise the verifier against
|
|
396
|
+
// the DEFAULT vendored MDS3 trust roots without standing up a real HTTPS
|
|
397
|
+
// endpoint. Operator-facing surface goes through fetch().
|
|
398
|
+
function _verifyAndParseBlob(token) {
|
|
399
|
+
return _verifyBlobWithRoots(token, _resolveRoots(undefined));
|
|
400
|
+
}
|
|
401
|
+
|
|
391
402
|
// ---- public surface ----
|
|
392
403
|
|
|
393
404
|
/**
|
|
@@ -481,39 +492,22 @@ async function fetch(opts) { // allow:raw-outbound-http-framework-internal —
|
|
|
481
492
|
}
|
|
482
493
|
var token = rsp.body.toString("ascii").trim();
|
|
483
494
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
if (typeof payload.no !== "number" || !isFinite(payload.no)) {
|
|
493
|
-
throw new FidoMds3Error("fido-mds3/bad-payload",
|
|
494
|
-
"BLOB payload missing or non-numeric 'no'");
|
|
495
|
-
}
|
|
496
|
-
var nextUpdate = _parseNextUpdate(payload.nextUpdate);
|
|
497
|
-
if (!nextUpdate) {
|
|
498
|
-
throw new FidoMds3Error("fido-mds3/bad-payload",
|
|
499
|
-
"BLOB payload 'nextUpdate' missing or not YYYY-MM-DD: " + payload.nextUpdate);
|
|
500
|
-
}
|
|
501
|
-
var record = {
|
|
502
|
-
entries: payload.entries,
|
|
503
|
-
no: payload.no,
|
|
504
|
-
nextUpdate: nextUpdate,
|
|
505
|
-
url: url,
|
|
506
|
-
legalHeader: payload.legalHeader,
|
|
507
|
-
};
|
|
495
|
+
// Route the trust decision through the shared verifier so this operator-
|
|
496
|
+
// facing path enforces the identical checks (chain verify, payload shape,
|
|
497
|
+
// AND the stale-BLOB refusal) as the internal helper -- fetch previously
|
|
498
|
+
// reimplemented the parse inline and omitted the stale check, silently
|
|
499
|
+
// accepting and caching an ancient signed-but-expired BLOB.
|
|
500
|
+
var record = _verifyBlobWithRoots(token, rootPems);
|
|
501
|
+
record.url = url;
|
|
508
502
|
// Re-assert TTL based on the BLOB's nextUpdate (overrides the
|
|
509
503
|
// wrap-call's safe-minimum seed).
|
|
510
|
-
try { await c.set(cacheKey, record, _ttlFromNextUpdate(nextUpdate)); }
|
|
504
|
+
try { await c.set(cacheKey, record, _ttlFromNextUpdate(record.nextUpdate)); }
|
|
511
505
|
catch (_e) { /* cache.set best-effort */ }
|
|
512
506
|
try { audit().safeEmit({
|
|
513
507
|
action: "auth.fido_mds3.fetch",
|
|
514
508
|
outcome: "success",
|
|
515
|
-
metadata: { url: url, no:
|
|
516
|
-
nextUpdate:
|
|
509
|
+
metadata: { url: url, no: record.no, entries: record.entries.length,
|
|
510
|
+
nextUpdate: record.nextUpdate.toISOString().slice(0, 10) },
|
|
517
511
|
}); } catch (_e) { /* audit best-effort */ }
|
|
518
512
|
return record;
|
|
519
513
|
}, MIN_CACHE_TTL_MS);
|
|
@@ -577,18 +571,35 @@ function lookupAaguid(blob, aaguid) {
|
|
|
577
571
|
function _certifiedLevel(statusReports) {
|
|
578
572
|
if (!Array.isArray(statusReports)) return { level: 0, plus: false };
|
|
579
573
|
var latest = null;
|
|
580
|
-
var latestDate = null;
|
|
574
|
+
var latestDate = null; // null == no comparable date (missing / malformed)
|
|
581
575
|
for (var i = 0; i < statusReports.length; i++) {
|
|
582
576
|
var sr = statusReports[i];
|
|
583
577
|
// Only certification-status reports move the level: a level grant, or its
|
|
584
578
|
// explicit revocation (NOT_FIDO_CERTIFIED). Other statuses (UPDATE_AVAILABLE,
|
|
585
|
-
// REVOKED,
|
|
586
|
-
// status length is bounded before the regex test below
|
|
579
|
+
// REVOKED, etc.) are handled elsewhere and must not be read as a level. The
|
|
580
|
+
// status length is bounded before the regex test below -- FIDO status tokens
|
|
587
581
|
// are short enums; bounding input before any .test() is the convention.
|
|
588
582
|
if (!sr || typeof sr.status !== "string" || sr.status.length > 64) continue;
|
|
589
583
|
if (!CERT_LEVEL_RE.test(sr.status) && sr.status !== "NOT_FIDO_CERTIFIED") continue;
|
|
590
|
-
|
|
591
|
-
|
|
584
|
+
// Only a well-formed calendar date is comparable. Reuse _parseNextUpdate
|
|
585
|
+
// (which already validates YYYY-MM-DD AND rejects impossible dates such as
|
|
586
|
+
// 2026-02-31) and compare epoch ms. A missing / malformed effectiveDate is
|
|
587
|
+
// "no comparable date" (null) and falls back to array order (append order,
|
|
588
|
+
// which the spec defines as chronological): the report later in the array
|
|
589
|
+
// is the more recent one. Coercing a missing date to "" and running it
|
|
590
|
+
// through a lexical compare made an undated report lose to EVERY earlier
|
|
591
|
+
// dated report, so a later decertification / downgrade / upgrade whose
|
|
592
|
+
// effectiveDate was absent never superseded the earlier grant -- freezing
|
|
593
|
+
// certifiedLevel at a stale value (an authenticator-assurance bypass: a
|
|
594
|
+
// decertified or downgraded authenticator kept reporting its prior level to
|
|
595
|
+
// step-up / risk policy).
|
|
596
|
+
var parsed = typeof sr.effectiveDate === "string" ? _parseNextUpdate(sr.effectiveDate) : null;
|
|
597
|
+
var d = parsed ? parsed.getTime() : null;
|
|
598
|
+
if (latest === null) { latest = sr; latestDate = d; continue; }
|
|
599
|
+
// sr is later in array order than the current latest. A missing/malformed
|
|
600
|
+
// date on EITHER side means array order decides -> sr (later) wins. Both
|
|
601
|
+
// dated -> the newer-or-equal date wins (sr, being later, takes ties).
|
|
602
|
+
if (d === null || latestDate === null || d >= latestDate) {
|
|
592
603
|
latest = sr; latestDate = d;
|
|
593
604
|
}
|
|
594
605
|
}
|
|
@@ -126,6 +126,27 @@ function _resolveAlgorithm(alg) {
|
|
|
126
126
|
return ALGORITHM_TO_NODE[alg];
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
// Bind the declared `alg` to the key that will actually produce/verify the
|
|
130
|
+
// signature. node:crypto.sign/verify with a null digest select the algorithm
|
|
131
|
+
// from the KeyObject's intrinsic type — NOT from the JWS `alg` header — so the
|
|
132
|
+
// header value is only an unauthenticated label unless we cross-check it here.
|
|
133
|
+
// Without this, verify()'s algorithm allowlist gates on that label while the
|
|
134
|
+
// crypto runs against whatever the key is: an ML-DSA-signed token can declare
|
|
135
|
+
// alg="SLH-DSA-SHAKE-256f" and pass an SLH-only allowlist (CWE-347 algorithm
|
|
136
|
+
// confusion / allowlist bypass), and sign() can emit a token whose header
|
|
137
|
+
// misstates its own signature algorithm. `alg` MUST already be a registry key
|
|
138
|
+
// (callers validate via _resolveAlgorithm or the verify allowlist gate).
|
|
139
|
+
function _assertAlgMatchesKey(alg, key, kind) {
|
|
140
|
+
var expectedNodeType = ALGORITHM_TO_NODE[alg];
|
|
141
|
+
var actual = key && typeof key.asymmetricKeyType === "string" ? key.asymmetricKeyType : null;
|
|
142
|
+
if (actual !== expectedNodeType) {
|
|
143
|
+
throw new AuthError("auth-jwt/alg-key-mismatch",
|
|
144
|
+
"declared alg '" + alg + "' requires a '" + expectedNodeType + "' key but the " +
|
|
145
|
+
kind + " key is '" + (actual || "unknown") + "' — the JWS alg header must be bound to " +
|
|
146
|
+
"the key's actual algorithm (CWE-347 algorithm confusion)");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
129
150
|
// ---- sign ----
|
|
130
151
|
|
|
131
152
|
async function sign(claims, opts) {
|
|
@@ -136,6 +157,10 @@ async function sign(claims, opts) {
|
|
|
136
157
|
var alg = opts.algorithm || DEFAULT_ALGORITHM;
|
|
137
158
|
_resolveAlgorithm(alg);
|
|
138
159
|
var key = _toKeyObject(opts.privateKey, "private");
|
|
160
|
+
// Refuse to emit a token whose header alg misstates the signing key's real
|
|
161
|
+
// algorithm — that mislabeled token is exactly what the verify-side
|
|
162
|
+
// allowlist bypass consumes. Config-time throw (operator catches the typo).
|
|
163
|
+
_assertAlgMatchesKey(alg, key, "private");
|
|
139
164
|
|
|
140
165
|
var nowMs = opts.now || Date.now();
|
|
141
166
|
var nowSec = Math.floor(nowMs / C.TIME.seconds(1));
|
|
@@ -306,6 +331,15 @@ async function verify(token, opts) {
|
|
|
306
331
|
"token alg='" + decoded.header.alg + "' is not in the allowed list [" + allowed.join(", ") + "]");
|
|
307
332
|
}
|
|
308
333
|
|
|
334
|
+
// The allowlist gate above only constrains the SELF-DECLARED header.alg — a
|
|
335
|
+
// label the issuer controls. node:crypto.verify(null, ...) selects the real
|
|
336
|
+
// algorithm from the KeyObject, so a token can pass an SLH-only allowlist
|
|
337
|
+
// while being verified with an ML-DSA key (or vice versa). Bind the declared
|
|
338
|
+
// alg to the resolved key's actual algorithm before verifying, so the
|
|
339
|
+
// allowlist genuinely constrains which algorithm authenticated the token
|
|
340
|
+
// (CWE-347). decoded.header.alg is a registry key here (it passed the gate).
|
|
341
|
+
_assertAlgMatchesKey(decoded.header.alg, key, "public");
|
|
342
|
+
|
|
309
343
|
var verified = false;
|
|
310
344
|
try {
|
|
311
345
|
verified = nodeCrypto.verify(null, Buffer.from(decoded.signingInput, "ascii"), key, decoded.signature);
|