@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
|
@@ -511,11 +511,523 @@ function testDbRoleFor() {
|
|
|
511
511
|
/BAD_ROLE/);
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
+
// ---- Role-table validation: uncovered adversarial branches ----
|
|
515
|
+
|
|
516
|
+
function testRoleTableValidationEdgeCases() {
|
|
517
|
+
function expect(label, fn, code) {
|
|
518
|
+
var threw = null;
|
|
519
|
+
try { fn(); } catch (e) { threw = e; }
|
|
520
|
+
check(label, threw && threw.code === code);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// permissions must be an array (lib line 137-138)
|
|
524
|
+
expect("create: permissions not an array → BAD_ROLE",
|
|
525
|
+
function () { b.permissions.create({ roles: { admin: { permissions: "users:read" } } }); },
|
|
526
|
+
"BAD_ROLE");
|
|
527
|
+
|
|
528
|
+
// null entry short-circuits the `entry && typeof === object` guard →
|
|
529
|
+
// falls to the catch-all throw (lib line 169; left-operand false branch)
|
|
530
|
+
expect("create: null role entry → BAD_ROLE",
|
|
531
|
+
function () { b.permissions.create({ roles: { admin: null } }); },
|
|
532
|
+
"BAD_ROLE");
|
|
533
|
+
expect("create: boolean role entry → BAD_ROLE",
|
|
534
|
+
function () { b.permissions.create({ roles: { admin: true } }); },
|
|
535
|
+
"BAD_ROLE");
|
|
536
|
+
|
|
537
|
+
// mfaWindowMs must be a positive finite number (lib line 160-163)
|
|
538
|
+
expect("create: negative role mfaWindowMs → BAD_ROLE",
|
|
539
|
+
function () { b.permissions.create({ roles: { a: { permissions: ["x:y"], mfaWindowMs: -1 } } }); },
|
|
540
|
+
"BAD_ROLE");
|
|
541
|
+
expect("create: zero role mfaWindowMs → BAD_ROLE",
|
|
542
|
+
function () { b.permissions.create({ roles: { a: { permissions: ["x:y"], mfaWindowMs: 0 } } }); },
|
|
543
|
+
"BAD_ROLE");
|
|
544
|
+
expect("create: NaN role mfaWindowMs → BAD_ROLE",
|
|
545
|
+
function () { b.permissions.create({ roles: { a: { permissions: ["x:y"], mfaWindowMs: NaN } } }); },
|
|
546
|
+
"BAD_ROLE");
|
|
547
|
+
expect("create: Infinity role mfaWindowMs → BAD_ROLE",
|
|
548
|
+
function () { b.permissions.create({ roles: { a: { permissions: ["x:y"], mfaWindowMs: Infinity } } }); },
|
|
549
|
+
"BAD_ROLE");
|
|
550
|
+
expect("create: string role mfaWindowMs → BAD_ROLE",
|
|
551
|
+
function () { b.permissions.create({ roles: { a: { permissions: ["x:y"], mfaWindowMs: "600000" } } }); },
|
|
552
|
+
"BAD_ROLE");
|
|
553
|
+
|
|
554
|
+
// valid mfaWindowMs is accepted + a role with extends but NO permissions
|
|
555
|
+
// key exercises the `entry.permissions || []` default (lib line 136, 164-165)
|
|
556
|
+
var ok = b.permissions.create({
|
|
557
|
+
roles: {
|
|
558
|
+
base: ["reports:read"],
|
|
559
|
+
admin: { extends: ["base"], requireMfa: true, mfaWindowMs: 600000 },
|
|
560
|
+
},
|
|
561
|
+
});
|
|
562
|
+
check("create: role with valid mfaWindowMs + no own permissions builds",
|
|
563
|
+
ok.expand(["admin"]).indexOf("reports:read") !== -1);
|
|
564
|
+
|
|
565
|
+
// empty-string role name (Object.keys yields "") (lib line 184-185)
|
|
566
|
+
expect("create: empty-string role name → BAD_ROLE",
|
|
567
|
+
function () { b.permissions.create({ roles: { "": ["a:b"] } }); },
|
|
568
|
+
"BAD_ROLE");
|
|
569
|
+
|
|
570
|
+
// extends entries must be non-empty strings (lib line 191-193)
|
|
571
|
+
expect("create: empty-string extends entry → BAD_ROLE",
|
|
572
|
+
function () { b.permissions.create({ roles: { a: { extends: [""], permissions: [] } } }); },
|
|
573
|
+
"BAD_ROLE");
|
|
574
|
+
expect("create: non-string extends entry → BAD_ROLE",
|
|
575
|
+
function () { b.permissions.create({ roles: { a: { extends: [42], permissions: [] } } }); },
|
|
576
|
+
"BAD_ROLE");
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Per-segment wildcard where required has fewer segments (lib line 99)
|
|
580
|
+
function testMatchPerSegmentWildcardShortRequired() {
|
|
581
|
+
var m = b.permissions.match;
|
|
582
|
+
check("users:*:read vs users → false (required too short at wildcard)",
|
|
583
|
+
m("users:*:read", "users") === false);
|
|
584
|
+
check("a:*:c vs a → false", m("a:*:c", "a") === false);
|
|
585
|
+
check("*:read vs empty-segmentless still handled",
|
|
586
|
+
m("a:*:c", "a:x") === false); // required exhausted after non-wildcard match at index 2
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// ---- Middleware registration-time opt validation (lib 465-469, 476-477) ----
|
|
590
|
+
|
|
591
|
+
function testMiddlewareOptValidation() {
|
|
592
|
+
var p = b.permissions.create({ roles: { admin: ["*"] } });
|
|
593
|
+
function expect(label, fn, code) {
|
|
594
|
+
var threw = null;
|
|
595
|
+
try { fn(); } catch (e) { threw = e; }
|
|
596
|
+
check(label, threw && threw.code === code);
|
|
597
|
+
}
|
|
598
|
+
expect("require: negative mfaWindowMs → BAD_OPT",
|
|
599
|
+
function () { p.require("users:read", { mfaWindowMs: -5 }); }, "BAD_OPT");
|
|
600
|
+
expect("require: zero mfaWindowMs → BAD_OPT",
|
|
601
|
+
function () { p.require("users:read", { mfaWindowMs: 0 }); }, "BAD_OPT");
|
|
602
|
+
expect("require: NaN mfaWindowMs → BAD_OPT",
|
|
603
|
+
function () { p.require("users:read", { mfaWindowMs: NaN }); }, "BAD_OPT");
|
|
604
|
+
expect("require: Infinity mfaWindowMs → BAD_OPT",
|
|
605
|
+
function () { p.require("users:read", { mfaWindowMs: Infinity }); }, "BAD_OPT");
|
|
606
|
+
expect("require: string mfaWindowMs → BAD_OPT",
|
|
607
|
+
function () { p.require("users:read", { mfaWindowMs: "1000" }); }, "BAD_OPT");
|
|
608
|
+
expect("require: non-function context → BAD_OPT",
|
|
609
|
+
function () { p.require("users:read", { context: "not-a-fn" }); }, "BAD_OPT");
|
|
610
|
+
expect("require: object context → BAD_OPT",
|
|
611
|
+
function () { p.require("users:read", { context: {} }); }, "BAD_OPT");
|
|
612
|
+
|
|
613
|
+
// A valid, explicit mfaWindowMs opt is accepted at registration.
|
|
614
|
+
var mw = p.require("users:read", { mfaWindowMs: 600000, context: function (req) { return req; } });
|
|
615
|
+
check("require: valid mfaWindowMs + context opts accepted", typeof mw === "function");
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// ---- policy() registration (lib 350-382) ----
|
|
619
|
+
|
|
620
|
+
function testPolicyRegistration() {
|
|
621
|
+
var p = b.permissions.create({ roles: { svc: ["orders:read", "orders:write"] } });
|
|
622
|
+
function expect(label, fn, code) {
|
|
623
|
+
var threw = null;
|
|
624
|
+
try { fn(); } catch (e) { threw = e; }
|
|
625
|
+
check(label, threw && threw.code === code);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Bad scope shape rejected (lib 351)
|
|
629
|
+
expect("policy: bad scope shape → BAD_SCOPE",
|
|
630
|
+
function () { p.policy("Bad:Scope", function (a, c) { return true; }); }, "BAD_SCOPE");
|
|
631
|
+
// Non-function predicate (lib 352-353)
|
|
632
|
+
expect("policy: non-function predicate → BAD_OPT",
|
|
633
|
+
function () { p.policy("orders:read", "nope"); }, "BAD_OPT");
|
|
634
|
+
|
|
635
|
+
// First registration succeeds; second on same scope is refused (lib 355-357)
|
|
636
|
+
p.policy("orders:read", function (a, c) { return true; });
|
|
637
|
+
expect("policy: duplicate scope → DUPLICATE_POLICY",
|
|
638
|
+
function () { p.policy("orders:read", function (a, c) { return true; }); }, "DUPLICATE_POLICY");
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
function testPolicyPredicateArityWarning() {
|
|
642
|
+
var audit = b.testing.captureAudit();
|
|
643
|
+
var p = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
644
|
+
|
|
645
|
+
// Arity-1 predicate (forgot the context param) → one-time register-time
|
|
646
|
+
// audit warning (lib 365-380).
|
|
647
|
+
p.policy("orders:write", function (actor) { return true; });
|
|
648
|
+
var warns = audit.byAction("permissions.policy_predicate_shape_warning");
|
|
649
|
+
check("policy: arity<2 predicate emits shape warning", warns.length === 1);
|
|
650
|
+
check("policy: shape warning carries the scope + arity",
|
|
651
|
+
warns[0].metadata && warns[0].metadata.scope === "orders:write" && warns[0].metadata.arity === 1);
|
|
652
|
+
|
|
653
|
+
// Arity-0 predicate also warns.
|
|
654
|
+
p.policy("orders:read", function () { return true; });
|
|
655
|
+
check("policy: arity-0 predicate warns too",
|
|
656
|
+
audit.byAction("permissions.policy_predicate_shape_warning").length === 2);
|
|
657
|
+
|
|
658
|
+
// A correct arity-2 predicate does NOT warn.
|
|
659
|
+
audit.clear();
|
|
660
|
+
var p2 = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
661
|
+
p2.policy("orders:write", function (actor, ctx) { return true; });
|
|
662
|
+
check("policy: arity-2 predicate does not warn",
|
|
663
|
+
audit.byAction("permissions.policy_predicate_shape_warning").length === 0);
|
|
664
|
+
|
|
665
|
+
// Arity<2 with NO audit sink must not throw (drop-silent guard, lib 366-379).
|
|
666
|
+
var p3 = b.permissions.create({ roles: { svc: ["orders:write"] } });
|
|
667
|
+
var threw = null;
|
|
668
|
+
try { p3.policy("orders:write", function (a) { return true; }); } catch (e) { threw = e; }
|
|
669
|
+
check("policy: arity<2 without audit sink does not throw", threw === null);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// ---- MFA enforcement gate (lib 526-604) ----
|
|
673
|
+
|
|
674
|
+
function testMfaPerRouteEnforcement() {
|
|
675
|
+
var minutes = b.constants.TIME.minutes;
|
|
676
|
+
var p = b.permissions.create({
|
|
677
|
+
roles: { editor: ["users:read", "users:write"] },
|
|
678
|
+
// Default resolver drops mfaAuthenticated/mfaAt; MFA-aware operators
|
|
679
|
+
// return the full user object.
|
|
680
|
+
resolver: function (req) { return req.user || null; },
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
// Route requires MFA; actor never stepped up → mfa_required deny.
|
|
684
|
+
return (async function () {
|
|
685
|
+
var mw = p.require("users:write", { requireMfa: true });
|
|
686
|
+
|
|
687
|
+
var noMfa = await _runMiddleware(mw, Object.assign(_mockReq(), { user: { roles: ["editor"] } }));
|
|
688
|
+
check("mfa route: un-stepped-up actor denied", noMfa.res._endedStatus === 403);
|
|
689
|
+
check("mfa route: mfa_required in body", /mfa_required/.test(noMfa.res._captured));
|
|
690
|
+
check("mfa route: next() not called", noMfa.nextCalled === false);
|
|
691
|
+
|
|
692
|
+
// Fresh MFA stamp → passes (window floor 15m, mfaAt = now).
|
|
693
|
+
var fresh = await _runMiddleware(mw, Object.assign(_mockReq(), {
|
|
694
|
+
user: { roles: ["editor"], mfaAuthenticated: true, mfaAt: Date.now() },
|
|
695
|
+
}));
|
|
696
|
+
check("mfa route: fresh step-up passes", fresh.nextCalled === true);
|
|
697
|
+
|
|
698
|
+
// Stale MFA stamp beyond the 15m default window floor → denied (lib 578-586).
|
|
699
|
+
var stale = await _runMiddleware(mw, Object.assign(_mockReq(), {
|
|
700
|
+
user: { roles: ["editor"], mfaAuthenticated: true, mfaAt: Date.now() - minutes(20) },
|
|
701
|
+
}));
|
|
702
|
+
check("mfa route: stale step-up beyond default window denied", stale.res._endedStatus === 403);
|
|
703
|
+
|
|
704
|
+
// Explicit larger window lets the same stale stamp through (lib 464-468 valid path).
|
|
705
|
+
var wide = p.require("users:write", { requireMfa: true, mfaWindowMs: minutes(30) });
|
|
706
|
+
var wideR = await _runMiddleware(wide, Object.assign(_mockReq(), {
|
|
707
|
+
user: { roles: ["editor"], mfaAuthenticated: true, mfaAt: Date.now() - minutes(20) },
|
|
708
|
+
}));
|
|
709
|
+
check("mfa route: explicit 30m window admits a 20m-old step-up", wideR.nextCalled === true);
|
|
710
|
+
})();
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
async function testMfaPerRoleEnforcement() {
|
|
714
|
+
var minutes = b.constants.TIME.minutes;
|
|
715
|
+
var cap = b.testing.captureMetricsTap();
|
|
716
|
+
var audit = b.testing.captureAudit();
|
|
717
|
+
try {
|
|
718
|
+
var p = b.permissions.create({
|
|
719
|
+
roles: {
|
|
720
|
+
admin: { permissions: ["users:delete"], requireMfa: true, mfaWindowMs: minutes(10) },
|
|
721
|
+
billing: { permissions: ["billing:read"], requireMfa: true },
|
|
722
|
+
reader: ["users:read"],
|
|
723
|
+
},
|
|
724
|
+
audit: audit,
|
|
725
|
+
resolver: function (req) { return req.user || null; },
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
// Route has NO requireMfa; the admin role's requireMfa forces the gate
|
|
729
|
+
// because admin grants the requested users:delete (lib 536-568).
|
|
730
|
+
var mw = p.require("users:delete");
|
|
731
|
+
var denied = await _runMiddleware(mw, Object.assign(_mockReq(), { user: { roles: ["admin"] } }));
|
|
732
|
+
check("mfa role: role-level requireMfa forces gate → deny", denied.res._endedStatus === 403);
|
|
733
|
+
check("mfa role: mfa.required audit emitted",
|
|
734
|
+
audit.byAction("permissions.mfa.required").length > 0);
|
|
735
|
+
check("mfa role: mfa_required metric emitted",
|
|
736
|
+
cap.byName("permissions.mfa_required").length > 0);
|
|
737
|
+
|
|
738
|
+
// With a fresh step-up (within the role's 10m window) → passes.
|
|
739
|
+
var okr = await _runMiddleware(mw, Object.assign(_mockReq(), {
|
|
740
|
+
user: { roles: ["admin"], mfaAuthenticated: true, mfaAt: Date.now() },
|
|
741
|
+
}));
|
|
742
|
+
check("mfa role: fresh step-up within role window passes", okr.nextCalled === true);
|
|
743
|
+
|
|
744
|
+
// Stale beyond the role's 10m window → denied (lib 564-566 window propagation).
|
|
745
|
+
var staleR = await _runMiddleware(mw, Object.assign(_mockReq(), {
|
|
746
|
+
user: { roles: ["admin"], mfaAuthenticated: true, mfaAt: Date.now() - minutes(15) },
|
|
747
|
+
}));
|
|
748
|
+
check("mfa role: stale beyond role's own window denied", staleR.res._endedStatus === 403);
|
|
749
|
+
|
|
750
|
+
// A requireMfa role whose scopes DON'T match the request does NOT force
|
|
751
|
+
// the gate; a second non-mfa role satisfies RBAC (lib 554-555 no-match,
|
|
752
|
+
// 547 non-mfa-role continue). billing.requireMfa but grants billing:read,
|
|
753
|
+
// reader grants users:read — request users:read → no MFA.
|
|
754
|
+
var mwRead = p.require("users:read");
|
|
755
|
+
var noGate = await _runMiddleware(mwRead, Object.assign(_mockReq(), {
|
|
756
|
+
user: { roles: ["billing", "reader"] },
|
|
757
|
+
}));
|
|
758
|
+
check("mfa role: non-matching requireMfa role does not force gate", noGate.nextCalled === true);
|
|
759
|
+
|
|
760
|
+
// Non-string entry in actor.roles is skipped during the MFA walk (lib 544).
|
|
761
|
+
var mixed = await _runMiddleware(mwRead, Object.assign(_mockReq(), {
|
|
762
|
+
user: { roles: [42, "reader"] },
|
|
763
|
+
}));
|
|
764
|
+
check("mfa role: non-string role entry skipped in MFA walk", mixed.nextCalled === true);
|
|
765
|
+
} finally {
|
|
766
|
+
cap.restore();
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// ---- ABAC policy evaluation in the request lifecycle (lib 606-684) ----
|
|
771
|
+
|
|
772
|
+
async function testPolicyAbacSingleMode() {
|
|
773
|
+
var audit = b.testing.captureAudit();
|
|
774
|
+
var cap = b.testing.captureMetricsTap();
|
|
775
|
+
try {
|
|
776
|
+
// Policy passes → request proceeds (lib 615, 647-652, 668 true, 686 success).
|
|
777
|
+
var pass = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
778
|
+
pass.policy("orders:write", function (actor, ctx) { return true; });
|
|
779
|
+
var passR = await _runMiddleware(pass.require("orders:write"),
|
|
780
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:write"] } }));
|
|
781
|
+
check("abac single: passing policy proceeds", passR.nextCalled === true);
|
|
782
|
+
|
|
783
|
+
// Policy returns falsy → 403 policy_denied + policy.deny audit (lib 668-682).
|
|
784
|
+
var deny = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
785
|
+
deny.policy("orders:write", function (actor, ctx) { return false; });
|
|
786
|
+
var denyR = await _runMiddleware(deny.require("orders:write"),
|
|
787
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:write"] } }));
|
|
788
|
+
check("abac single: failing policy → 403", denyR.res._endedStatus === 403);
|
|
789
|
+
check("abac single: policy_denied in body", /policy_denied/.test(denyR.res._captured));
|
|
790
|
+
check("abac single: policy.deny audit emitted",
|
|
791
|
+
audit.byAction("permissions.policy.deny").length > 0);
|
|
792
|
+
|
|
793
|
+
// Predicate throws → 403 policy_error + policy.error audit (lib 653-667).
|
|
794
|
+
var thrower = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
795
|
+
thrower.policy("orders:write", function (actor, ctx) { throw new Error("boom-predicate"); });
|
|
796
|
+
var throwR = await _runMiddleware(thrower.require("orders:write"),
|
|
797
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:write"] } }));
|
|
798
|
+
check("abac single: throwing predicate → 403", throwR.res._endedStatus === 403);
|
|
799
|
+
check("abac single: policy_error in body", /policy_error/.test(throwR.res._captured));
|
|
800
|
+
var perr = audit.byAction("permissions.policy.error");
|
|
801
|
+
check("abac single: policy.error audit with predicate-threw reason",
|
|
802
|
+
perr.some(function (e) { return e.reason === "predicate-threw"; }));
|
|
803
|
+
check("abac single: policy_error metric emitted",
|
|
804
|
+
cap.byName("permissions.policy_error").length > 0);
|
|
805
|
+
} finally {
|
|
806
|
+
cap.restore();
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
async function testPolicyAbacContextProvider() {
|
|
811
|
+
var audit = b.testing.captureAudit();
|
|
812
|
+
var cap = b.testing.captureMetricsTap();
|
|
813
|
+
try {
|
|
814
|
+
// Context provider result is threaded into the predicate (lib 626-629).
|
|
815
|
+
var p = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
816
|
+
p.policy("orders:write", function (actor, ctx) { return ctx && ctx.tenant === "acme"; });
|
|
817
|
+
var mw = p.require("orders:write", {
|
|
818
|
+
context: async function (req) { return { tenant: req.tenant }; },
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
var okReq = Object.assign(_mockReq(), { user: { scopes: ["orders:write"] }, tenant: "acme" });
|
|
822
|
+
var okR = await _runMiddleware(mw, okReq);
|
|
823
|
+
check("abac context: matching context admits request", okR.nextCalled === true);
|
|
824
|
+
|
|
825
|
+
var badReq = Object.assign(_mockReq(), { user: { scopes: ["orders:write"] }, tenant: "evil" });
|
|
826
|
+
var badR = await _runMiddleware(mw, badReq);
|
|
827
|
+
check("abac context: non-matching context → 403", badR.res._endedStatus === 403);
|
|
828
|
+
|
|
829
|
+
// Context provider throws → policy_context_error + context-provider-threw
|
|
830
|
+
// audit (lib 628-645), BEFORE the predicate runs.
|
|
831
|
+
var predicateRan = false;
|
|
832
|
+
var p2 = b.permissions.create({ roles: { svc: ["orders:write"] }, audit: audit });
|
|
833
|
+
p2.policy("orders:write", function (actor, ctx) { predicateRan = true; return true; });
|
|
834
|
+
var mw2 = p2.require("orders:write", {
|
|
835
|
+
context: function (req) { throw new Error("ctx-boom"); },
|
|
836
|
+
});
|
|
837
|
+
var ctxErr = await _runMiddleware(mw2,
|
|
838
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:write"] } }));
|
|
839
|
+
check("abac context: provider throw → 403", ctxErr.res._endedStatus === 403);
|
|
840
|
+
check("abac context: policy_context_error in body",
|
|
841
|
+
/policy_context_error/.test(ctxErr.res._captured));
|
|
842
|
+
check("abac context: predicate NOT reached when provider throws", predicateRan === false);
|
|
843
|
+
check("abac context: context-provider-threw audit reason",
|
|
844
|
+
audit.byAction("permissions.policy.error").some(function (e) {
|
|
845
|
+
return e.reason === "context-provider-threw";
|
|
846
|
+
}));
|
|
847
|
+
check("abac context: policy_context_error metric emitted",
|
|
848
|
+
cap.byName("permissions.policy_context_error").length > 0);
|
|
849
|
+
} finally {
|
|
850
|
+
cap.restore();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
async function testPolicyAbacAllAndAnyModes() {
|
|
855
|
+
// requireAll: every requested scope's policy must pass (lib 617-623 all branch).
|
|
856
|
+
var pAll = b.permissions.create({ roles: { svc: ["orders:read", "orders:write"] } });
|
|
857
|
+
pAll.policy("orders:read", function (a, c) { return true; });
|
|
858
|
+
pAll.policy("orders:write", function (a, c) { return true; });
|
|
859
|
+
var allR = await _runMiddleware(
|
|
860
|
+
pAll.requireAll(["orders:read", "orders:write"]),
|
|
861
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:read", "orders:write"] } }));
|
|
862
|
+
check("abac all: both policies pass → proceed", allR.nextCalled === true);
|
|
863
|
+
|
|
864
|
+
// requireAll: a single failing policy short-circuits to deny.
|
|
865
|
+
var pAllDeny = b.permissions.create({ roles: { svc: ["orders:read", "orders:write"] } });
|
|
866
|
+
pAllDeny.policy("orders:read", function (a, c) { return true; });
|
|
867
|
+
pAllDeny.policy("orders:write", function (a, c) { return false; });
|
|
868
|
+
var allDenyR = await _runMiddleware(
|
|
869
|
+
pAllDeny.requireAll(["orders:read", "orders:write"]),
|
|
870
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:read", "orders:write"] } }));
|
|
871
|
+
check("abac all: one failing policy → 403", allDenyR.res._endedStatus === 403);
|
|
872
|
+
|
|
873
|
+
// requireAny: a policy on a scope the actor does NOT hold is skipped so its
|
|
874
|
+
// existence never leaks (lib 619-622, the `!check → continue` path). The
|
|
875
|
+
// held scope's passing policy admits the request even though the unheld
|
|
876
|
+
// scope carries a would-deny policy.
|
|
877
|
+
var pAny = b.permissions.create({ roles: { svc: ["orders:read", "orders:write"] } });
|
|
878
|
+
pAny.policy("orders:read", function (a, c) { return true; });
|
|
879
|
+
pAny.policy("orders:write", function (a, c) { return false; });
|
|
880
|
+
var anyR = await _runMiddleware(
|
|
881
|
+
pAny.requireAny(["orders:read", "orders:write"]),
|
|
882
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:read"] } }));
|
|
883
|
+
check("abac any: unheld scope's policy skipped, held scope admits", anyR.nextCalled === true);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// ---- Audit opt-out for failures (lib 393 failure branch) ----
|
|
887
|
+
|
|
888
|
+
async function testAuditFailuresOptOut() {
|
|
889
|
+
var audit = b.testing.captureAudit();
|
|
890
|
+
var p = b.permissions.create({
|
|
891
|
+
roles: { viewer: ["*:read"] },
|
|
892
|
+
audit: audit,
|
|
893
|
+
auditFailures: false,
|
|
894
|
+
});
|
|
895
|
+
var mwDeny = p.require("users:write");
|
|
896
|
+
await _runMiddleware(mwDeny, Object.assign(_mockReq(), { user: { roles: ["viewer"] } }));
|
|
897
|
+
check("opt-out: deny NOT audited when auditFailures=false",
|
|
898
|
+
audit.byAction("permissions.check.deny").length === 0);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// ---- dbRoleFor: non-string / unknown role names + shared-ancestor guard ----
|
|
902
|
+
|
|
903
|
+
function testDbRoleForAdversarialRoles() {
|
|
904
|
+
var p = b.permissions.create({
|
|
905
|
+
roles: {
|
|
906
|
+
analyst: { permissions: ["users:read"], dbRole: "analytics_user" },
|
|
907
|
+
// Two roles share a dbRole-less ancestor to exercise the visited guard
|
|
908
|
+
// in _findDbRole (lib 752).
|
|
909
|
+
shared: { permissions: ["x:y"] },
|
|
910
|
+
a: { extends: ["shared"], permissions: [] },
|
|
911
|
+
b: { extends: ["shared"], permissions: [] },
|
|
912
|
+
},
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
// Non-string + unknown role names are skipped before a valid one resolves
|
|
916
|
+
// (lib 728-729).
|
|
917
|
+
check("dbRoleFor: non-string + unknown roles skipped, valid one wins",
|
|
918
|
+
p.dbRoleFor({ roles: [123, "ghost", "analyst"] }) === "analytics_user");
|
|
919
|
+
|
|
920
|
+
// Both top-level roles walk into the same dbRole-less ancestor; the second
|
|
921
|
+
// walk re-encounters the already-visited ancestor → null overall.
|
|
922
|
+
check("dbRoleFor: shared dbRole-less ancestor → null (visited guard)",
|
|
923
|
+
p.dbRoleFor({ roles: ["a", "b"] }) === null);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// ---- Residual defensive/default branches reached through the consumer path ----
|
|
927
|
+
|
|
928
|
+
// Returns a truthy non-Error value with no `.message` — thrown to drive the
|
|
929
|
+
// `(e && e.message) || String(e)` fallback. Routed through a call so it isn't
|
|
930
|
+
// a throw-literal.
|
|
931
|
+
function _nonErrorValue(tag) { return { note: tag }; }
|
|
932
|
+
|
|
933
|
+
async function testBranchCleanups() {
|
|
934
|
+
var minutes = b.constants.TIME.minutes;
|
|
935
|
+
|
|
936
|
+
function expect(label, fn, code) {
|
|
937
|
+
var threw = null;
|
|
938
|
+
try { fn(); } catch (e) { threw = e; }
|
|
939
|
+
check(label, threw && threw.code === code);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// denyStatus upper-bound (lib 257 `> 599` operand) + no-arg create()
|
|
943
|
+
// hitting the `opts || {}` default (lib 324).
|
|
944
|
+
expect("create: denyStatus above 599 → BAD_OPT",
|
|
945
|
+
function () { b.permissions.create({ roles: { a: ["*"] }, denyStatus: 600 }); }, "BAD_OPT");
|
|
946
|
+
expect("create: no args → roles-missing BAD_OPT (opts||{} default)",
|
|
947
|
+
function () { b.permissions.create(); }, "BAD_OPT");
|
|
948
|
+
|
|
949
|
+
// checkAll / checkAny non-array required-scopes → false (lib 425, 433).
|
|
950
|
+
var p = b.permissions.create({ roles: { admin: ["*"] } });
|
|
951
|
+
check("checkAll: non-array required → false", p.checkAll({ scopes: ["users:read"] }, "nope") === false);
|
|
952
|
+
check("checkAny: non-array required → false", p.checkAny({ scopes: ["users:read"] }, null) === false);
|
|
953
|
+
|
|
954
|
+
// Missing-actor hint branch when the resolver returns null despite an
|
|
955
|
+
// actor being present on the request (lib 486-487 path0).
|
|
956
|
+
var auditA = b.testing.captureAudit();
|
|
957
|
+
var pNull = b.permissions.create({
|
|
958
|
+
roles: { admin: ["*"] }, audit: auditA, resolver: function () { return null; },
|
|
959
|
+
});
|
|
960
|
+
var reqWithUser = _mockReq();
|
|
961
|
+
reqWithUser.user = { roles: ["admin"] };
|
|
962
|
+
await _runMiddleware(pNull.require("users:read"), reqWithUser);
|
|
963
|
+
var ma = auditA.byAction("permissions.missing_actor")[0];
|
|
964
|
+
check("missing-actor hint reflects resolver-returned-null-despite-actor",
|
|
965
|
+
ma && /actor present on req but resolver returned null/.test(ma.metadata.hint));
|
|
966
|
+
|
|
967
|
+
// Resolver-supplied userId flows into the audit actor shape (lib 778 path0).
|
|
968
|
+
var auditB = b.testing.captureAudit();
|
|
969
|
+
var pUid = b.permissions.create({
|
|
970
|
+
roles: { admin: ["*"] }, audit: auditB,
|
|
971
|
+
resolver: function () { return { userId: "svc-1", scopes: ["users:read"] }; },
|
|
972
|
+
});
|
|
973
|
+
await _runMiddleware(pUid.require("users:read"), _mockReq());
|
|
974
|
+
var succ = auditB.byAction("permissions.check.success")[0];
|
|
975
|
+
check("resolver-supplied userId appears in audit actor", succ && succ.actor.userId === "svc-1");
|
|
976
|
+
|
|
977
|
+
// MFA gate with an actor that set mfaAuthenticated but NO numeric mfaAt →
|
|
978
|
+
// mfaAt coerces to 0 → treated as ancient → denied (lib 583 `: 0`).
|
|
979
|
+
var pMfa = b.permissions.create({
|
|
980
|
+
roles: { editor: ["users:write"] },
|
|
981
|
+
resolver: function (req) { return req.user || null; },
|
|
982
|
+
});
|
|
983
|
+
var noStamp = await _runMiddleware(
|
|
984
|
+
pMfa.require("users:write", { requireMfa: true, mfaWindowMs: minutes(30) }),
|
|
985
|
+
Object.assign(_mockReq(), { user: { roles: ["editor"], mfaAuthenticated: true } }));
|
|
986
|
+
check("mfa: mfaAuthenticated without numeric mfaAt is treated as stale → 403",
|
|
987
|
+
noStamp.res._endedStatus === 403);
|
|
988
|
+
|
|
989
|
+
// Per-role requireMfa forcing the gate on a multi-scope (requireAny) route
|
|
990
|
+
// exercises the non-single `requestedList` branch (lib 554 `: requested`).
|
|
991
|
+
var pAnyMfa = b.permissions.create({
|
|
992
|
+
roles: {
|
|
993
|
+
admin: { permissions: ["users:delete"], requireMfa: true },
|
|
994
|
+
reader: ["users:read"],
|
|
995
|
+
},
|
|
996
|
+
resolver: function (req) { return req.user || null; },
|
|
997
|
+
});
|
|
998
|
+
var anyMfa = await _runMiddleware(
|
|
999
|
+
pAnyMfa.requireAny(["users:delete", "posts:read"]),
|
|
1000
|
+
Object.assign(_mockReq(), { user: { roles: ["admin"] } }));
|
|
1001
|
+
check("mfa: per-role gate on requireAny route denies un-stepped-up actor",
|
|
1002
|
+
anyMfa.res._endedStatus === 403);
|
|
1003
|
+
|
|
1004
|
+
// Non-Error throws fall through the `String(e)` audit-metadata fallback in
|
|
1005
|
+
// both ABAC error paths (lib 638 context, lib 660 predicate).
|
|
1006
|
+
// A thrown value with no `.message` (here a bare object, not an Error)
|
|
1007
|
+
// drives the `String(e)` fallback in the audit-metadata construction.
|
|
1008
|
+
var pCtxStr = b.permissions.create({ roles: { svc: ["orders:write"] } });
|
|
1009
|
+
pCtxStr.policy("orders:write", function (a, c) { return true; });
|
|
1010
|
+
var ctxStr = await _runMiddleware(
|
|
1011
|
+
pCtxStr.require("orders:write", { context: function () { throw _nonErrorValue("ctx"); } }),
|
|
1012
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:write"] } }));
|
|
1013
|
+
check("abac: non-Error context throw still denies (String(e) fallback)",
|
|
1014
|
+
ctxStr.res._endedStatus === 403);
|
|
1015
|
+
|
|
1016
|
+
var pPredStr = b.permissions.create({ roles: { svc: ["orders:write"] } });
|
|
1017
|
+
pPredStr.policy("orders:write", function (a, c) { throw _nonErrorValue("pred"); });
|
|
1018
|
+
var predStr = await _runMiddleware(
|
|
1019
|
+
pPredStr.require("orders:write"),
|
|
1020
|
+
Object.assign(_mockReq(), { user: { scopes: ["orders:write"] } }));
|
|
1021
|
+
check("abac: non-Error predicate throw still denies (String(e) fallback)",
|
|
1022
|
+
predStr.res._endedStatus === 403);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
514
1025
|
// ---- Run ----
|
|
515
1026
|
|
|
516
1027
|
async function run() {
|
|
517
1028
|
testSurface();
|
|
518
1029
|
testMatchTable();
|
|
1030
|
+
testMatchPerSegmentWildcardShortRequired();
|
|
519
1031
|
testRoleExpansion();
|
|
520
1032
|
testRoleExpansionDeepInheritance();
|
|
521
1033
|
testRolesProperty();
|
|
@@ -533,9 +1045,21 @@ async function run() {
|
|
|
533
1045
|
await testAuditAndObservabilityEmission();
|
|
534
1046
|
await testAuditDefaults();
|
|
535
1047
|
await testAuditSuccessOptOut();
|
|
1048
|
+
await testAuditFailuresOptOut();
|
|
536
1049
|
await testFiveWsAuditPropagation();
|
|
537
1050
|
testCreateRejectsBadOpts();
|
|
1051
|
+
testRoleTableValidationEdgeCases();
|
|
1052
|
+
testMiddlewareOptValidation();
|
|
1053
|
+
testPolicyRegistration();
|
|
1054
|
+
testPolicyPredicateArityWarning();
|
|
1055
|
+
await testMfaPerRouteEnforcement();
|
|
1056
|
+
await testMfaPerRoleEnforcement();
|
|
1057
|
+
await testPolicyAbacSingleMode();
|
|
1058
|
+
await testPolicyAbacContextProvider();
|
|
1059
|
+
await testPolicyAbacAllAndAnyModes();
|
|
538
1060
|
testDbRoleFor();
|
|
1061
|
+
testDbRoleForAdversarialRoles();
|
|
1062
|
+
await testBranchCleanups();
|
|
539
1063
|
}
|
|
540
1064
|
|
|
541
1065
|
module.exports = { run: run };
|
|
@@ -59,6 +59,25 @@ function testNarrowToFrameworkSubset() {
|
|
|
59
59
|
two.destroy();
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function testGroupsMirrorEcdhCurve() {
|
|
63
|
+
// The negotiated TLS `groups` list must track the resolved `ecdhCurve`
|
|
64
|
+
// string, not be independently re-derived from network-tls's
|
|
65
|
+
// tlsKeyShares ordering. A caller who narrows/reorders ecdhCurve and
|
|
66
|
+
// gets a groups list that ignores it would negotiate a different key
|
|
67
|
+
// share than requested.
|
|
68
|
+
var agent = b.pqcAgent.create();
|
|
69
|
+
check("default: groups mirrors ecdhCurve exactly",
|
|
70
|
+
agent.options.groups === agent.options.ecdhCurve);
|
|
71
|
+
agent.destroy();
|
|
72
|
+
|
|
73
|
+
// Narrowing to a single hybrid — groups tracks the narrowed value.
|
|
74
|
+
var narrowed = b.pqcAgent.create({ ecdhCurve: "SecP256r1MLKEM768" });
|
|
75
|
+
check("narrowed: groups mirrors the narrowed ecdhCurve",
|
|
76
|
+
narrowed.options.groups === "SecP256r1MLKEM768" &&
|
|
77
|
+
narrowed.options.ecdhCurve === "SecP256r1MLKEM768");
|
|
78
|
+
narrowed.destroy();
|
|
79
|
+
}
|
|
80
|
+
|
|
62
81
|
function testRefuseUnknownGroupByDefault() {
|
|
63
82
|
var threw = false;
|
|
64
83
|
try {
|
|
@@ -104,6 +123,8 @@ async function testAllowOperatorGroupsAuditEmit() {
|
|
|
104
123
|
});
|
|
105
124
|
check("secp256r1 accepted under allowOperatorGroups",
|
|
106
125
|
agent.options.ecdhCurve === "secp256r1");
|
|
126
|
+
check("operator-group: groups mirrors the operator-supplied ecdhCurve",
|
|
127
|
+
agent.options.groups === "secp256r1");
|
|
107
128
|
agent.destroy();
|
|
108
129
|
|
|
109
130
|
await b.audit.flush();
|
|
@@ -151,6 +172,7 @@ function testReloadAfterBuild() {
|
|
|
151
172
|
async function run() {
|
|
152
173
|
await testDefaultGroupList();
|
|
153
174
|
testNarrowToFrameworkSubset();
|
|
175
|
+
testGroupsMirrorEcdhCurve();
|
|
154
176
|
testRefuseUnknownGroupByDefault();
|
|
155
177
|
await testAllowOperatorGroupsAuditEmit();
|
|
156
178
|
testKnownTlsGroupsExposed();
|