@blamejs/blamejs-shop 0.5.12 → 0.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -543,6 +543,628 @@ function testRequiredComponentsCoverage() {
|
|
|
543
543
|
rightParam.valid === true);
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
// Shared fixtures for the branch-coverage suite below. Every test drives the
|
|
547
|
+
// exported b.crypto.httpSig.{sign,verify,contentDigest} consumer path; nothing
|
|
548
|
+
// reaches for a private function.
|
|
549
|
+
function _reqBase(extra) {
|
|
550
|
+
return Object.assign({
|
|
551
|
+
method: "GET",
|
|
552
|
+
url: "https://api.example.com/x",
|
|
553
|
+
headers: { host: "api.example.com" },
|
|
554
|
+
}, extra || {});
|
|
555
|
+
}
|
|
556
|
+
function _withSig(msg, signed) {
|
|
557
|
+
return Object.assign({}, msg, { headers: Object.assign({}, msg.headers, signed.headers) });
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// _sfQuotedString refuses any parameter byte outside printable-ASCII
|
|
561
|
+
// (RFC 8941 §3.3.3): a control byte in a signature parameter (here `nonce`)
|
|
562
|
+
// makes sign() throw BAD_PARAM rather than emit a header that would mis-parse
|
|
563
|
+
// on the wire. Constructed via fromCharCode so no literal control byte lands
|
|
564
|
+
// in the test source.
|
|
565
|
+
function testNonPrintableParamRejected() {
|
|
566
|
+
var keys = _genEd25519();
|
|
567
|
+
var ctl = String.fromCharCode(1);
|
|
568
|
+
var err = null;
|
|
569
|
+
try {
|
|
570
|
+
b.crypto.httpSig.sign(_reqBase(), {
|
|
571
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
572
|
+
covered: ["@method", "@target-uri"], nonce: "bad" + ctl + "nonce",
|
|
573
|
+
});
|
|
574
|
+
} catch (e) { err = e; }
|
|
575
|
+
check("sign refuses a control byte in a signature parameter (BAD_PARAM)",
|
|
576
|
+
err && err.code === "BAD_PARAM");
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// RFC 9421 §2.2 derived components — @scheme / @request-target / @path /
|
|
580
|
+
// @query / @authority all resolve into the signature base and round-trip.
|
|
581
|
+
// @status (a response component) resolves from a numeric status; covering it
|
|
582
|
+
// with no status throws MISSING_STATUS; an unknown @-component throws
|
|
583
|
+
// UNKNOWN_DERIVED.
|
|
584
|
+
function testDerivedComponents() {
|
|
585
|
+
var keys = _genEd25519();
|
|
586
|
+
var msg = {
|
|
587
|
+
method: "GET",
|
|
588
|
+
url: "https://api.example.com/a/b?q=1",
|
|
589
|
+
headers: { host: "api.example.com" },
|
|
590
|
+
};
|
|
591
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
592
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
593
|
+
covered: ["@scheme", "@authority", "@request-target", "@path", "@query"],
|
|
594
|
+
});
|
|
595
|
+
var verified = b.crypto.httpSig.verify(_withSig(msg, signed),
|
|
596
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
597
|
+
check("all §2.2 derived components (@scheme/@authority/@request-target/@path/@query) round-trip",
|
|
598
|
+
verified.valid === true);
|
|
599
|
+
|
|
600
|
+
// @status resolves from a numeric status (response-style message).
|
|
601
|
+
var respMsg = {
|
|
602
|
+
method: "GET",
|
|
603
|
+
url: "https://api.example.com/a",
|
|
604
|
+
headers: { host: "api.example.com" },
|
|
605
|
+
status: 200,
|
|
606
|
+
};
|
|
607
|
+
var respSigned = b.crypto.httpSig.sign(respMsg, {
|
|
608
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
609
|
+
covered: ["@method", "@target-uri", "@status"],
|
|
610
|
+
});
|
|
611
|
+
var respVerified = b.crypto.httpSig.verify(_withSig(respMsg, respSigned),
|
|
612
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
613
|
+
check("@status resolves from a numeric status and round-trips", respVerified.valid === true);
|
|
614
|
+
|
|
615
|
+
// A URL with NO query exercises the empty-query branches: @request-target
|
|
616
|
+
// omits the (absent) query, and @query defaults to "?".
|
|
617
|
+
var noQueryMsg = _reqBase({ url: "https://api.example.com/x" });
|
|
618
|
+
var noQuerySigned = b.crypto.httpSig.sign(noQueryMsg, {
|
|
619
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
620
|
+
covered: ["@method", "@request-target", "@query"],
|
|
621
|
+
});
|
|
622
|
+
var noQueryVerified = b.crypto.httpSig.verify(_withSig(noQueryMsg, noQuerySigned),
|
|
623
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
624
|
+
check("@request-target/@query on a query-less URL round-trip (@query → '?')",
|
|
625
|
+
noQueryVerified.valid === true);
|
|
626
|
+
|
|
627
|
+
// @status covered but message carries no status → MISSING_STATUS.
|
|
628
|
+
var statusErr = null;
|
|
629
|
+
try {
|
|
630
|
+
b.crypto.httpSig.sign(_reqBase(), {
|
|
631
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@status"],
|
|
632
|
+
});
|
|
633
|
+
} catch (e) { statusErr = e; }
|
|
634
|
+
check("@status without a numeric status throws MISSING_STATUS",
|
|
635
|
+
statusErr && statusErr.code === "MISSING_STATUS");
|
|
636
|
+
|
|
637
|
+
// Unknown @-component → UNKNOWN_DERIVED.
|
|
638
|
+
var derivedErr = null;
|
|
639
|
+
try {
|
|
640
|
+
b.crypto.httpSig.sign(_reqBase(), {
|
|
641
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
642
|
+
covered: ["@method", "@bogus-derived"],
|
|
643
|
+
});
|
|
644
|
+
} catch (e) { derivedErr = e; }
|
|
645
|
+
check("an unknown @-derived component throws UNKNOWN_DERIVED",
|
|
646
|
+
derivedErr && derivedErr.code === "UNKNOWN_DERIVED");
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// RFC 9421 §2.3 signature parameters — nonce / tag / expires / explicit label
|
|
650
|
+
// all serialize into Signature-Input, and an explicit `now` feeds `created`.
|
|
651
|
+
// verify surfaces created / expires / nonce on the valid result.
|
|
652
|
+
function testSignatureParameters() {
|
|
653
|
+
var keys = _genEd25519();
|
|
654
|
+
var nowMs = Date.now();
|
|
655
|
+
var nowSec = Math.floor(nowMs / 1000);
|
|
656
|
+
var msg = _reqBase();
|
|
657
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
658
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
659
|
+
covered: ["@method", "@target-uri"],
|
|
660
|
+
label: "custom-label",
|
|
661
|
+
nonce: "n-0123",
|
|
662
|
+
tag: "app-a",
|
|
663
|
+
expires: nowSec + 300,
|
|
664
|
+
now: function () { return nowMs; },
|
|
665
|
+
});
|
|
666
|
+
var si = signed.headers["Signature-Input"];
|
|
667
|
+
check("Signature-Input carries the custom label", si.indexOf("custom-label=") === 0);
|
|
668
|
+
check("Signature-Input serializes nonce + tag + expires + created",
|
|
669
|
+
/;created=/.test(si) && /;expires=/.test(si) &&
|
|
670
|
+
/;nonce="n-0123"/.test(si) && /;tag="app-a"/.test(si));
|
|
671
|
+
var verified = b.crypto.httpSig.verify(_withSig(msg, signed),
|
|
672
|
+
{ keyResolver: function () { return keys.publicKey; },
|
|
673
|
+
now: function () { return nowMs; } });
|
|
674
|
+
check("parameterized signature round-trips + surfaces nonce/expires/created",
|
|
675
|
+
verified.valid === true && verified.label === "custom-label" &&
|
|
676
|
+
verified.nonce === "n-0123" && verified.expires === nowSec + 300 &&
|
|
677
|
+
verified.created === nowSec);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// @query-param sign-time failure modes (defensive resolution throws at base
|
|
681
|
+
// build): no query string at all, the named param absent, and a bare
|
|
682
|
+
// @query-param with no ;name parameter.
|
|
683
|
+
function testQueryParamSignFailures() {
|
|
684
|
+
var keys = _genEd25519();
|
|
685
|
+
var noQueryErr = null;
|
|
686
|
+
try {
|
|
687
|
+
b.crypto.httpSig.sign(_reqBase(), {
|
|
688
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
689
|
+
covered: ["@query-param;name=\"x\""],
|
|
690
|
+
});
|
|
691
|
+
} catch (e) { noQueryErr = e; }
|
|
692
|
+
check("@query-param on a URL with no query throws MISSING_QUERY",
|
|
693
|
+
noQueryErr && noQueryErr.code === "MISSING_QUERY");
|
|
694
|
+
|
|
695
|
+
var absentErr = null;
|
|
696
|
+
try {
|
|
697
|
+
b.crypto.httpSig.sign(_reqBase({ url: "https://api.example.com/x?present=1" }), {
|
|
698
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
699
|
+
covered: ["@query-param;name=\"absent\""],
|
|
700
|
+
});
|
|
701
|
+
} catch (e) { absentErr = e; }
|
|
702
|
+
check("@query-param naming an absent param throws MISSING_QUERY_PARAM",
|
|
703
|
+
absentErr && absentErr.code === "MISSING_QUERY_PARAM");
|
|
704
|
+
|
|
705
|
+
var bareErr = null;
|
|
706
|
+
try {
|
|
707
|
+
b.crypto.httpSig.sign(_reqBase({ url: "https://api.example.com/x?present=1" }), {
|
|
708
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
709
|
+
covered: ["@query-param"],
|
|
710
|
+
});
|
|
711
|
+
} catch (e) { bareErr = e; }
|
|
712
|
+
check("a bare @query-param with no ;name parameter throws BAD_QUERY_PARAM",
|
|
713
|
+
bareErr && bareErr.code === "BAD_QUERY_PARAM");
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// RFC 9421 §2.2.8 — a valueless query member (`?flag&ref=1`) resolves to the
|
|
717
|
+
// empty string for its value, matching on the name only (the `eq === -1`
|
|
718
|
+
// branches for both the wire name and the returned value).
|
|
719
|
+
function testQueryParamValuelessFlag() {
|
|
720
|
+
var keys = _genEd25519();
|
|
721
|
+
var msg = _reqBase({ url: "https://api.example.com/x?flag&ref=1" });
|
|
722
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
723
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
724
|
+
covered: ["@method", "@query-param;name=\"flag\""],
|
|
725
|
+
});
|
|
726
|
+
var verified = b.crypto.httpSig.verify(_withSig(msg, signed),
|
|
727
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
728
|
+
check("a valueless @query-param flag (name only, empty value) round-trips",
|
|
729
|
+
verified.valid === true);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// A covered header that is not present in the message throws MISSING_HEADER at
|
|
733
|
+
// base build (sign side).
|
|
734
|
+
function testMissingCoveredHeader() {
|
|
735
|
+
var keys = _genEd25519();
|
|
736
|
+
var err = null;
|
|
737
|
+
try {
|
|
738
|
+
b.crypto.httpSig.sign(_reqBase(), {
|
|
739
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
740
|
+
covered: ["@method", "x-absent-header"],
|
|
741
|
+
});
|
|
742
|
+
} catch (e) { err = e; }
|
|
743
|
+
check("covering a header absent from the message throws MISSING_HEADER",
|
|
744
|
+
err && err.code === "MISSING_HEADER");
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// RFC 9421 §2.1 — a multi-valued header (array) is obs-folded into one
|
|
748
|
+
// ", "-joined value in the base, and round-trips on both sides.
|
|
749
|
+
function testArrayHeaderValue() {
|
|
750
|
+
var keys = _genEd25519();
|
|
751
|
+
var msg = _reqBase({ headers: { host: "api.example.com", "x-multi": ["a", "b"] } });
|
|
752
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
753
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
754
|
+
covered: ["@method", "x-multi"],
|
|
755
|
+
});
|
|
756
|
+
var verified = b.crypto.httpSig.verify(_withSig(msg, signed),
|
|
757
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
758
|
+
check("a multi-valued (array) header obs-folds and round-trips", verified.valid === true);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// contentDigest accepts a string or Buffer and refuses any other body type.
|
|
762
|
+
function testContentDigestFunction() {
|
|
763
|
+
check("contentDigest(string) returns the sha3-512 structured field",
|
|
764
|
+
/^sha3-512=:.+:$/.test(b.crypto.httpSig.contentDigest("abc")));
|
|
765
|
+
check("contentDigest(Buffer) returns the sha3-512 structured field",
|
|
766
|
+
/^sha3-512=:.+:$/.test(b.crypto.httpSig.contentDigest(Buffer.from("abc"))));
|
|
767
|
+
check("contentDigest of a Buffer equals contentDigest of the equivalent string",
|
|
768
|
+
b.crypto.httpSig.contentDigest(Buffer.from("abc")) ===
|
|
769
|
+
b.crypto.httpSig.contentDigest("abc"));
|
|
770
|
+
var err = null;
|
|
771
|
+
try { b.crypto.httpSig.contentDigest(12345); } catch (e) { err = e; }
|
|
772
|
+
check("contentDigest of a non-string/Buffer body throws BAD_BODY",
|
|
773
|
+
err && err.code === "BAD_BODY");
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// sign()-side option / message failures: a message with no headers, a covered
|
|
777
|
+
// content-digest with no body, and an unparseable private key (SIGN_FAILED).
|
|
778
|
+
function testSignFailures() {
|
|
779
|
+
var keys = _genEd25519();
|
|
780
|
+
var headersErr = null;
|
|
781
|
+
try {
|
|
782
|
+
b.crypto.httpSig.sign({ method: "GET", url: "https://api.example.com/x" }, {
|
|
783
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method"],
|
|
784
|
+
});
|
|
785
|
+
} catch (e) { headersErr = e; }
|
|
786
|
+
check("a message with no headers throws BAD_OPT", headersErr && headersErr.code === "BAD_OPT");
|
|
787
|
+
|
|
788
|
+
var bodyErr = null;
|
|
789
|
+
try {
|
|
790
|
+
b.crypto.httpSig.sign(_reqBase({ method: "POST", url: "https://api.example.com/o" }), {
|
|
791
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
792
|
+
covered: ["@method", "content-digest"],
|
|
793
|
+
});
|
|
794
|
+
} catch (e) { bodyErr = e; }
|
|
795
|
+
check("covering content-digest with no body throws BAD_OPT",
|
|
796
|
+
bodyErr && bodyErr.code === "BAD_OPT");
|
|
797
|
+
|
|
798
|
+
var signErr = null;
|
|
799
|
+
try {
|
|
800
|
+
b.crypto.httpSig.sign(_reqBase(), {
|
|
801
|
+
keyid: "k1", alg: "ed25519", privateKey: "-----BEGIN PRIVATE KEY-----\nnot-real\n-----END PRIVATE KEY-----\n",
|
|
802
|
+
covered: ["@method", "@target-uri"],
|
|
803
|
+
});
|
|
804
|
+
} catch (e) { signErr = e; }
|
|
805
|
+
check("an unparseable private key throws SIGN_FAILED", signErr && signErr.code === "SIGN_FAILED");
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// verify()-side option / presence gates that return a verdict (never throw,
|
|
809
|
+
// except the keyResolver contract): no keyResolver, no Signature-Input, no
|
|
810
|
+
// Signature.
|
|
811
|
+
function testVerifyPresenceGates() {
|
|
812
|
+
var keys = _genEd25519();
|
|
813
|
+
var signed = b.crypto.httpSig.sign(_reqBase(), {
|
|
814
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method", "@target-uri"],
|
|
815
|
+
});
|
|
816
|
+
var resolverErr = null;
|
|
817
|
+
try { b.crypto.httpSig.verify(_reqBase(), {}); } catch (e) { resolverErr = e; }
|
|
818
|
+
check("verify without a keyResolver throws BAD_OPT", resolverErr && resolverErr.code === "BAD_OPT");
|
|
819
|
+
|
|
820
|
+
// verify with no opts argument at all defaults opts to {} then hits the same
|
|
821
|
+
// keyResolver contract.
|
|
822
|
+
var noOptsErr = null;
|
|
823
|
+
try { b.crypto.httpSig.verify(_reqBase()); } catch (e) { noOptsErr = e; }
|
|
824
|
+
check("verify with no opts argument throws BAD_OPT (opts defaults to {})",
|
|
825
|
+
noOptsErr && noOptsErr.code === "BAD_OPT");
|
|
826
|
+
|
|
827
|
+
var noInput = b.crypto.httpSig.verify(_reqBase(),
|
|
828
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
829
|
+
check("verify with no Signature-Input returns missing-signature-input",
|
|
830
|
+
noInput.valid === false && noInput.reason === "missing-signature-input");
|
|
831
|
+
|
|
832
|
+
var onlyInput = b.crypto.httpSig.verify(
|
|
833
|
+
_reqBase({ headers: { host: "api.example.com", "Signature-Input": signed.headers["Signature-Input"] } }),
|
|
834
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
835
|
+
check("verify with Signature-Input but no Signature returns missing-signature",
|
|
836
|
+
onlyInput.valid === false && onlyInput.reason === "missing-signature");
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// Malformed Signature-Input header shapes all return the bad-signature-input
|
|
840
|
+
// verdict (the _parseSignatureInput throw is caught): missing '=', a covered
|
|
841
|
+
// list not starting with '(', a covered list missing ')', and an unterminated
|
|
842
|
+
// quoted token.
|
|
843
|
+
function testMalformedSignatureInput() {
|
|
844
|
+
var keys = _genEd25519();
|
|
845
|
+
var cases = [
|
|
846
|
+
["missing '='", "no-equals-here"],
|
|
847
|
+
["covered not '('", "sig1=notparen"],
|
|
848
|
+
["covered missing ')'", "sig1=(no-close"],
|
|
849
|
+
["unterminated quote", "sig1=(\"@method);alg=\"ed25519\""],
|
|
850
|
+
];
|
|
851
|
+
for (var i = 0; i < cases.length; i++) {
|
|
852
|
+
var v = b.crypto.httpSig.verify(
|
|
853
|
+
_reqBase({ headers: {
|
|
854
|
+
host: "api.example.com",
|
|
855
|
+
"Signature-Input": cases[i][1],
|
|
856
|
+
"Signature": "sig1=:AAAA:",
|
|
857
|
+
} }),
|
|
858
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
859
|
+
check("malformed Signature-Input (" + cases[i][0] + ") → bad-signature-input",
|
|
860
|
+
v.valid === false && v.reason === "bad-signature-input");
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// A forward-compat peer MAY transmit bare (unquoted) covered tokens; the parser
|
|
865
|
+
// tolerates them and — because the base re-quotes each bare name — the
|
|
866
|
+
// signature still verifies.
|
|
867
|
+
function testBareUnquotedCoveredTokens() {
|
|
868
|
+
var keys = _genEd25519();
|
|
869
|
+
var msg = _reqBase();
|
|
870
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
871
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method", "@target-uri"],
|
|
872
|
+
});
|
|
873
|
+
var bareInput = signed.headers["Signature-Input"]
|
|
874
|
+
.replace("(\"@method\" \"@target-uri\")", "(@method @target-uri)");
|
|
875
|
+
check("the rewrite produced bare unquoted covered tokens",
|
|
876
|
+
/\(@method @target-uri\)/.test(bareInput));
|
|
877
|
+
var verified = b.crypto.httpSig.verify(
|
|
878
|
+
_withSig(msg, { headers: Object.assign({}, signed.headers, { "Signature-Input": bareInput }) }),
|
|
879
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
880
|
+
check("bare (unquoted) covered tokens still verify (base re-quotes them)",
|
|
881
|
+
verified.valid === true);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// parsed-parameter gates: an unsupported alg and a missing/empty keyid each
|
|
885
|
+
// return a verdict before any crypto runs.
|
|
886
|
+
function testParsedParamGates() {
|
|
887
|
+
var keys = _genEd25519();
|
|
888
|
+
var badAlg = b.crypto.httpSig.verify(
|
|
889
|
+
_reqBase({ headers: {
|
|
890
|
+
host: "api.example.com",
|
|
891
|
+
"Signature-Input": "sig1=(\"@method\");created=1;keyid=\"k1\";alg=\"rsa-pss-sha512\"",
|
|
892
|
+
"Signature": "sig1=:AAAA:",
|
|
893
|
+
} }),
|
|
894
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
895
|
+
check("an unsupported alg in Signature-Input → unsupported-alg",
|
|
896
|
+
badAlg.valid === false && badAlg.reason === "unsupported-alg");
|
|
897
|
+
|
|
898
|
+
var noKeyid = b.crypto.httpSig.verify(
|
|
899
|
+
_reqBase({ headers: {
|
|
900
|
+
host: "api.example.com",
|
|
901
|
+
"Signature-Input": "sig1=(\"@method\");created=1;alg=\"ed25519\"",
|
|
902
|
+
"Signature": "sig1=:AAAA:",
|
|
903
|
+
} }),
|
|
904
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
905
|
+
check("a Signature-Input with no keyid → missing-keyid",
|
|
906
|
+
noKeyid.valid === false && noKeyid.reason === "missing-keyid");
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// RFC 9421 §3.2.4 — a future-dated `created` beyond the clock-skew window is
|
|
910
|
+
// refused (`future`), and an already-passed `expires` is refused
|
|
911
|
+
// (`expires-passed`); a malformed clockSkewMs falls back to the default window.
|
|
912
|
+
function testTimeGates() {
|
|
913
|
+
var keys = _genEd25519();
|
|
914
|
+
var nowSec = Math.floor(Date.now() / 1000);
|
|
915
|
+
|
|
916
|
+
var futureSigned = b.crypto.httpSig.sign(_reqBase(), {
|
|
917
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
918
|
+
covered: ["@method", "@target-uri"], created: nowSec + 3600,
|
|
919
|
+
});
|
|
920
|
+
var future = b.crypto.httpSig.verify(_withSig(_reqBase(), futureSigned),
|
|
921
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
922
|
+
check("a far-future created is refused (future)",
|
|
923
|
+
future.valid === false && future.reason === "future");
|
|
924
|
+
|
|
925
|
+
var expiredSigned = b.crypto.httpSig.sign(_reqBase(), {
|
|
926
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
927
|
+
covered: ["@method", "@target-uri"], created: nowSec, expires: nowSec - 10,
|
|
928
|
+
});
|
|
929
|
+
var expires = b.crypto.httpSig.verify(_withSig(_reqBase(), expiredSigned),
|
|
930
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
931
|
+
check("an already-passed expires is refused (expires-passed)",
|
|
932
|
+
expires.valid === false && expires.reason === "expires-passed");
|
|
933
|
+
|
|
934
|
+
// A near-future created (within the default skew) verifies even when a
|
|
935
|
+
// malformed clockSkewMs is supplied (it falls back to the default window).
|
|
936
|
+
var nearSigned = b.crypto.httpSig.sign(_reqBase(), {
|
|
937
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
938
|
+
covered: ["@method", "@target-uri"], created: nowSec + 2,
|
|
939
|
+
});
|
|
940
|
+
var near = b.crypto.httpSig.verify(_withSig(_reqBase(), nearSigned),
|
|
941
|
+
{ keyResolver: function () { return keys.publicKey; }, clockSkewMs: NaN });
|
|
942
|
+
check("a malformed clockSkewMs falls back to the default skew (near-future accepted)",
|
|
943
|
+
near.valid === true);
|
|
944
|
+
|
|
945
|
+
// An explicit, valid clockSkewMs is honored: a signature ~5 minutes in the
|
|
946
|
+
// future is refused under a tight 1-minute skew but accepted under a 10-minute
|
|
947
|
+
// skew.
|
|
948
|
+
var aheadSigned = b.crypto.httpSig.sign(_reqBase(), {
|
|
949
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
950
|
+
covered: ["@method", "@target-uri"], created: nowSec + 300,
|
|
951
|
+
});
|
|
952
|
+
var tightSkew = b.crypto.httpSig.verify(_withSig(_reqBase(), aheadSigned),
|
|
953
|
+
{ keyResolver: function () { return keys.publicKey; },
|
|
954
|
+
clockSkewMs: b.constants.TIME.minutes(1) });
|
|
955
|
+
check("a 5-min-future signature is refused under a tight explicit clockSkewMs",
|
|
956
|
+
tightSkew.valid === false && tightSkew.reason === "future");
|
|
957
|
+
var wideSkew = b.crypto.httpSig.verify(_withSig(_reqBase(), aheadSigned),
|
|
958
|
+
{ keyResolver: function () { return keys.publicKey; },
|
|
959
|
+
clockSkewMs: b.constants.TIME.minutes(10) });
|
|
960
|
+
check("the same 5-min-future signature is accepted under a wide explicit clockSkewMs",
|
|
961
|
+
wideSkew.valid === true);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// A keyResolver that throws is caught and reported (key-resolver-threw), never
|
|
965
|
+
// propagated out of verify.
|
|
966
|
+
function testKeyResolverThrows() {
|
|
967
|
+
var keys = _genEd25519();
|
|
968
|
+
var signed = b.crypto.httpSig.sign(_reqBase(), {
|
|
969
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method", "@target-uri"],
|
|
970
|
+
});
|
|
971
|
+
var v = b.crypto.httpSig.verify(_withSig(_reqBase(), signed),
|
|
972
|
+
{ keyResolver: function () { throw new Error("resolver down"); } });
|
|
973
|
+
check("a throwing keyResolver is caught and reported (key-resolver-threw)",
|
|
974
|
+
v.valid === false && v.reason === "key-resolver-threw");
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// verify-side content-digest branches: covered but no body
|
|
978
|
+
// (content-digest-no-body), covered with body but the header stripped
|
|
979
|
+
// (content-digest-header-missing), and a multi-member Content-Digest whose
|
|
980
|
+
// sha3-512 member matches after skipping a malformed and a non-sha3-512 member.
|
|
981
|
+
function testContentDigestVerifyBranches() {
|
|
982
|
+
var keys = _genEd25519();
|
|
983
|
+
var wb = {
|
|
984
|
+
method: "POST", url: "https://api.example.com/o",
|
|
985
|
+
headers: { host: "api.example.com" }, body: "B",
|
|
986
|
+
};
|
|
987
|
+
var cdSigned = b.crypto.httpSig.sign(wb, {
|
|
988
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
989
|
+
covered: ["@method", "@target-uri", "content-digest"],
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
// Body dropped at verify → content-digest-no-body (covered set still names it).
|
|
993
|
+
var noBody = b.crypto.httpSig.verify(
|
|
994
|
+
{ method: "POST", url: "https://api.example.com/o",
|
|
995
|
+
headers: Object.assign({}, wb.headers, cdSigned.headers) },
|
|
996
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
997
|
+
check("content-digest covered but the verified message has no body → content-digest-no-body",
|
|
998
|
+
noBody.valid === false && noBody.reason === "content-digest-no-body");
|
|
999
|
+
|
|
1000
|
+
// Body present but the Content-Digest header stripped → header-missing.
|
|
1001
|
+
var strippedHeaders = Object.assign({}, wb.headers, cdSigned.headers);
|
|
1002
|
+
delete strippedHeaders["Content-Digest"];
|
|
1003
|
+
var headerMissing = b.crypto.httpSig.verify(
|
|
1004
|
+
{ method: "POST", url: "https://api.example.com/o", headers: strippedHeaders, body: "B" },
|
|
1005
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
1006
|
+
check("content-digest covered, body present, header stripped → content-digest-header-missing",
|
|
1007
|
+
headerMissing.valid === false && headerMissing.reason === "content-digest-header-missing");
|
|
1008
|
+
|
|
1009
|
+
// A multi-member Content-Digest (malformed member + a non-sha3-512 member +
|
|
1010
|
+
// the real sha3-512 member) supplied at BOTH sign and verify verifies: the
|
|
1011
|
+
// parser skips the first two members and matches the sha3-512 one.
|
|
1012
|
+
var realDigest = b.crypto.httpSig.contentDigest("B");
|
|
1013
|
+
var multiHeader = "malformedmember, sha-256=:AAAA:, " + realDigest;
|
|
1014
|
+
var multiMsg = {
|
|
1015
|
+
method: "POST", url: "https://api.example.com/o",
|
|
1016
|
+
headers: { host: "api.example.com", "content-digest": multiHeader }, body: "B",
|
|
1017
|
+
};
|
|
1018
|
+
var multiSigned = b.crypto.httpSig.sign(multiMsg, {
|
|
1019
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
1020
|
+
covered: ["@method", "@target-uri", "content-digest"],
|
|
1021
|
+
});
|
|
1022
|
+
var multi = b.crypto.httpSig.verify(_withSig(multiMsg, multiSigned),
|
|
1023
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
1024
|
+
check("a multi-member Content-Digest matches its sha3-512 member (skipping malformed + non-sha3-512)",
|
|
1025
|
+
multi.valid === true);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
// The Signature header may carry multiple comma-separated labels; verify picks
|
|
1029
|
+
// the one named by Signature-Input's label. A decoy-prefixed header still
|
|
1030
|
+
// verifies; a header with no matching label returns bad-signature-header.
|
|
1031
|
+
function testMultiLabelSignature() {
|
|
1032
|
+
var keys = _genEd25519();
|
|
1033
|
+
var msg = _reqBase();
|
|
1034
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
1035
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method", "@target-uri"],
|
|
1036
|
+
});
|
|
1037
|
+
var decoyHeaders = Object.assign({}, signed.headers,
|
|
1038
|
+
{ "Signature": "decoy=:AAAA:, " + signed.headers["Signature"] });
|
|
1039
|
+
var found = b.crypto.httpSig.verify(_withSig(msg, { headers: decoyHeaders }),
|
|
1040
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
1041
|
+
check("verify finds the correct label among comma-separated Signature entries",
|
|
1042
|
+
found.valid === true);
|
|
1043
|
+
|
|
1044
|
+
var wrongHeaders = Object.assign({}, signed.headers, { "Signature": "other=:AAAA:" });
|
|
1045
|
+
var missing = b.crypto.httpSig.verify(_withSig(msg, { headers: wrongHeaders }),
|
|
1046
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
1047
|
+
check("a Signature header with no entry for the label → bad-signature-header",
|
|
1048
|
+
missing.valid === false && missing.reason === "bad-signature-header");
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// The final crypto verdict: a cryptographically-wrong signature (valid key,
|
|
1052
|
+
// wrong signer) returns bad-signature; a resolver returning a non-key string
|
|
1053
|
+
// makes node's verify throw, caught as verify-threw.
|
|
1054
|
+
function testCryptoVerdicts() {
|
|
1055
|
+
var keys = _genEd25519();
|
|
1056
|
+
var other = _genEd25519();
|
|
1057
|
+
var msg = _reqBase();
|
|
1058
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
1059
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method", "@target-uri"],
|
|
1060
|
+
});
|
|
1061
|
+
var wrongKey = b.crypto.httpSig.verify(_withSig(msg, signed),
|
|
1062
|
+
{ keyResolver: function () { return other.publicKey; } });
|
|
1063
|
+
check("a signature checked against the wrong (valid) public key → bad-signature",
|
|
1064
|
+
wrongKey.valid === false && wrongKey.reason === "bad-signature");
|
|
1065
|
+
|
|
1066
|
+
var garbageKey = b.crypto.httpSig.verify(_withSig(msg, signed),
|
|
1067
|
+
{ keyResolver: function () { return "not-a-real-key-pem"; } });
|
|
1068
|
+
check("a resolver returning a non-key string makes node's verify throw → verify-threw",
|
|
1069
|
+
garbageKey.valid === false && garbageKey.reason === "verify-threw");
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// If base construction fails at verify (a covered header present at sign but
|
|
1073
|
+
// stripped before verify), verify returns build-base-failed rather than
|
|
1074
|
+
// throwing.
|
|
1075
|
+
function testBuildBaseFailed() {
|
|
1076
|
+
var keys = _genEd25519();
|
|
1077
|
+
var msg = _reqBase({ headers: { host: "api.example.com", "x-custom": "v" } });
|
|
1078
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
1079
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey,
|
|
1080
|
+
covered: ["@method", "@target-uri", "x-custom"],
|
|
1081
|
+
});
|
|
1082
|
+
var strippedHeaders = Object.assign({}, msg.headers, signed.headers);
|
|
1083
|
+
delete strippedHeaders["x-custom"];
|
|
1084
|
+
var v = b.crypto.httpSig.verify(
|
|
1085
|
+
{ method: "GET", url: "https://api.example.com/x", headers: strippedHeaders },
|
|
1086
|
+
{ keyResolver: function () { return keys.publicKey; }, requiredComponents: [] });
|
|
1087
|
+
check("a covered header stripped before verify → build-base-failed",
|
|
1088
|
+
v.valid === false && v.reason === "build-base-failed");
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// RFC 8941 §3.1.2 parameter parsing tolerance: verify rebuilds the canonical
|
|
1092
|
+
// @signature-params terminator from the parsed values, so a transmitted
|
|
1093
|
+
// Signature-Input with a trailing ';' (empty parameter) or an unquoted string
|
|
1094
|
+
// parameter (a conformant peer's serialization variant) still verifies.
|
|
1095
|
+
function testSignatureInputParamTolerance() {
|
|
1096
|
+
var keys = _genEd25519();
|
|
1097
|
+
var msg = _reqBase();
|
|
1098
|
+
|
|
1099
|
+
var signed = b.crypto.httpSig.sign(msg, {
|
|
1100
|
+
keyid: "k1", alg: "ed25519", privateKey: keys.privateKey, covered: ["@method", "@target-uri"],
|
|
1101
|
+
});
|
|
1102
|
+
var trailingInput = signed.headers["Signature-Input"] + ";";
|
|
1103
|
+
var trailing = b.crypto.httpSig.verify(
|
|
1104
|
+
_withSig(msg, { headers: Object.assign({}, signed.headers, { "Signature-Input": trailingInput }) }),
|
|
1105
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
1106
|
+
check("a trailing ';' (empty parameter) in Signature-Input is tolerated and still verifies",
|
|
1107
|
+
trailing.valid === true);
|
|
1108
|
+
|
|
1109
|
+
// A conformant peer signs the canonical base (quoted tag) but transmits the
|
|
1110
|
+
// tag parameter unquoted — verify parses it as a plain string, rebuilds the
|
|
1111
|
+
// canonical (quoted) terminator, and the signature matches.
|
|
1112
|
+
var created = Math.floor(Date.now() / 1000);
|
|
1113
|
+
var coveredSf = "(\"@method\" \"@target-uri\")";
|
|
1114
|
+
var canonicalBase =
|
|
1115
|
+
"\"@method\": GET\n" +
|
|
1116
|
+
"\"@target-uri\": https://api.example.com/x\n" +
|
|
1117
|
+
"\"@signature-params\": " + coveredSf +
|
|
1118
|
+
";created=" + created + ";alg=\"ed25519\";keyid=\"k1\";tag=\"mytag\"";
|
|
1119
|
+
var sig = nodeCrypto.sign(null, Buffer.from(canonicalBase, "utf8"), keys.privateKey);
|
|
1120
|
+
var unquotedInput = "sig1=" + coveredSf +
|
|
1121
|
+
";created=" + created + ";alg=\"ed25519\";keyid=\"k1\";tag=mytag"; // tag unquoted
|
|
1122
|
+
var unquoted = b.crypto.httpSig.verify(
|
|
1123
|
+
_withSig(msg, { headers: {
|
|
1124
|
+
"Signature-Input": unquotedInput,
|
|
1125
|
+
"Signature": "sig1=:" + sig.toString("base64") + ":",
|
|
1126
|
+
} }),
|
|
1127
|
+
{ keyResolver: function () { return keys.publicKey; } });
|
|
1128
|
+
check("an unquoted string parameter (tag=mytag) parses as a string and verifies",
|
|
1129
|
+
unquoted.valid === true);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
function testAlgKeyBinding() {
|
|
1133
|
+
// Alg-confusion (CWE-347): the declared alg is only an authenticated label
|
|
1134
|
+
// unless it is bound to the key's real type. SUPPORTED_ALGS names ARE the
|
|
1135
|
+
// node asymmetricKeyType values, so sign() must refuse to emit a mislabeled
|
|
1136
|
+
// token and verify() must refuse a key whose type differs from the declared
|
|
1137
|
+
// alg -- a classical ed25519 key must never pass under a declared PQC alg.
|
|
1138
|
+
var e = _genEd25519();
|
|
1139
|
+
var m = _genMlDsa65();
|
|
1140
|
+
var msg = {
|
|
1141
|
+
method: "POST",
|
|
1142
|
+
url: "https://api.example.com/x",
|
|
1143
|
+
headers: { host: "api.example.com" },
|
|
1144
|
+
body: "{}",
|
|
1145
|
+
};
|
|
1146
|
+
var cov = ["@method", "@target-uri", "@authority", "content-digest"];
|
|
1147
|
+
|
|
1148
|
+
var signThrew = false;
|
|
1149
|
+
try {
|
|
1150
|
+
b.crypto.httpSig.sign(msg, { keyid: "k", alg: "ml-dsa-65", privateKey: e.privateKey, covered: cov });
|
|
1151
|
+
} catch (err) { signThrew = (err && err.code === "BAD_OPT"); }
|
|
1152
|
+
check("httpSig.sign: ed25519 key declared alg=ml-dsa-65 refused (BAD_OPT)", signThrew);
|
|
1153
|
+
|
|
1154
|
+
var signed = b.crypto.httpSig.sign(msg, { keyid: "k", alg: "ed25519", privateKey: e.privateKey, covered: cov });
|
|
1155
|
+
var full = Object.assign({}, msg, { headers: Object.assign({}, msg.headers, signed.headers) });
|
|
1156
|
+
var mismatch = b.crypto.httpSig.verify(full, { keyResolver: function () { return m.publicKey; } });
|
|
1157
|
+
check("httpSig.verify: declared alg != resolved key type refused (alg-key-mismatch)",
|
|
1158
|
+
mismatch.valid === false && mismatch.reason === "alg-key-mismatch");
|
|
1159
|
+
|
|
1160
|
+
var okEd = b.crypto.httpSig.verify(full, { keyResolver: function () { return e.publicKey; } });
|
|
1161
|
+
check("httpSig: legit ed25519 round-trip still verifies", okEd.valid === true);
|
|
1162
|
+
var s2 = b.crypto.httpSig.sign(msg, { keyid: "k2", alg: "ml-dsa-65", privateKey: m.privateKey, covered: cov });
|
|
1163
|
+
var f2 = Object.assign({}, msg, { headers: Object.assign({}, msg.headers, s2.headers) });
|
|
1164
|
+
var okMl = b.crypto.httpSig.verify(f2, { keyResolver: function () { return m.publicKey; } });
|
|
1165
|
+
check("httpSig: legit ml-dsa-65 round-trip still verifies", okMl.valid === true);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
546
1168
|
async function run() {
|
|
547
1169
|
testSurface();
|
|
548
1170
|
testRoundTripEd25519();
|
|
@@ -560,6 +1182,27 @@ async function run() {
|
|
|
560
1182
|
testQueryParamRfc9421PublishedVectors();
|
|
561
1183
|
testQueryParamDecodedNameWithDelimiter();
|
|
562
1184
|
testRequiredComponentsCoverage();
|
|
1185
|
+
testNonPrintableParamRejected();
|
|
1186
|
+
testDerivedComponents();
|
|
1187
|
+
testSignatureParameters();
|
|
1188
|
+
testQueryParamSignFailures();
|
|
1189
|
+
testQueryParamValuelessFlag();
|
|
1190
|
+
testMissingCoveredHeader();
|
|
1191
|
+
testArrayHeaderValue();
|
|
1192
|
+
testContentDigestFunction();
|
|
1193
|
+
testSignFailures();
|
|
1194
|
+
testVerifyPresenceGates();
|
|
1195
|
+
testMalformedSignatureInput();
|
|
1196
|
+
testBareUnquotedCoveredTokens();
|
|
1197
|
+
testParsedParamGates();
|
|
1198
|
+
testTimeGates();
|
|
1199
|
+
testKeyResolverThrows();
|
|
1200
|
+
testAlgKeyBinding();
|
|
1201
|
+
testContentDigestVerifyBranches();
|
|
1202
|
+
testMultiLabelSignature();
|
|
1203
|
+
testCryptoVerdicts();
|
|
1204
|
+
testBuildBaseFailed();
|
|
1205
|
+
testSignatureInputParamTolerance();
|
|
563
1206
|
}
|
|
564
1207
|
|
|
565
1208
|
module.exports = { run: run };
|