@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
|
@@ -84,6 +84,39 @@ function run() {
|
|
|
84
84
|
withConsent(_mockReq({ user: { age: 12, parentalConsent: true } }), _mockRes(), function () { consentPassedCalls++; });
|
|
85
85
|
check("ageGate passes when parentalConsent present", consentPassedCalls === 1);
|
|
86
86
|
|
|
87
|
+
// A getAge that computes a NON-FINITE number (NaN from parseInt on a
|
|
88
|
+
// malformed birth field / date math, or ±Infinity) must NOT be read as a
|
|
89
|
+
// confirmed adult. typeof NaN === "number" and `NaN < consentRequired`
|
|
90
|
+
// is false, so the classifier fell through to "above-threshold" — silently
|
|
91
|
+
// dropping every child-safety privacy default for a user whose age simply
|
|
92
|
+
// failed to compute (an attacker-influenced fail-open when the birth field
|
|
93
|
+
// is request-derived). A non-finite age is classified "unknown" (privacy
|
|
94
|
+
// headers applied), consistent with a null / non-number return.
|
|
95
|
+
var nanGate = b.middleware.ageGate({
|
|
96
|
+
audit: false,
|
|
97
|
+
getAge: function () { return Number("not-a-birth-year"); }, // NaN
|
|
98
|
+
consentRequired: 18,
|
|
99
|
+
});
|
|
100
|
+
var nanRes = _mockRes();
|
|
101
|
+
var nanNext = 0;
|
|
102
|
+
nanGate(_mockReq({ url: "/kids", method: "POST" }), nanRes, function () { nanNext++; });
|
|
103
|
+
check("NaN age classified unknown, not above-threshold",
|
|
104
|
+
nanRes._captured.headers["X-Privacy-Posture"] === "unknown");
|
|
105
|
+
check("NaN age applies the no-store privacy default",
|
|
106
|
+
nanRes._captured.headers["Cache-Control"] === "private, no-store");
|
|
107
|
+
check("NaN age still flows downstream as unknown (privacy posture, no hard block)",
|
|
108
|
+
nanNext === 1 && nanRes._captured.status === 0);
|
|
109
|
+
|
|
110
|
+
var infGate = b.middleware.ageGate({
|
|
111
|
+
audit: false,
|
|
112
|
+
getAge: function () { return Infinity; },
|
|
113
|
+
consentRequired: 18,
|
|
114
|
+
});
|
|
115
|
+
var infRes = _mockRes();
|
|
116
|
+
infGate(_mockReq({ url: "/kids", method: "POST" }), infRes, function () {});
|
|
117
|
+
check("Infinity age classified unknown (non-finite is not a valid age)",
|
|
118
|
+
infRes._captured.headers["X-Privacy-Posture"] === "unknown");
|
|
119
|
+
|
|
87
120
|
var threwBadGetAge = false;
|
|
88
121
|
try { b.middleware.ageGate({ audit: false, getAge: "nope" }); }
|
|
89
122
|
catch (e) { threwBadGetAge = e.code === "age-gate/bad-get-age"; }
|
|
Binary file
|
|
@@ -271,9 +271,69 @@ async function run() {
|
|
|
271
271
|
await testErrorCauseAttached();
|
|
272
272
|
await testFailedCompStepNameCorrect();
|
|
273
273
|
await testSagaStatePersistedAcrossRun();
|
|
274
|
+
await testResumeCompensatesPreCrashSteps();
|
|
275
|
+
await testResumeRefusesTerminalSaga();
|
|
274
276
|
await testRefusesBadConfig();
|
|
275
277
|
}
|
|
276
278
|
|
|
279
|
+
async function testResumeCompensatesPreCrashSteps() {
|
|
280
|
+
// A saga that crashed after step 2, resumed, then FAILS at step 3 must
|
|
281
|
+
// compensate the FULL completed set — the pre-crash steps (s1, s2) included,
|
|
282
|
+
// in reverse order. Regression: _runFrom reset completedSteps=[] on resume,
|
|
283
|
+
// so a post-resume failure compensated only this run's steps, leaving the
|
|
284
|
+
// pre-crash work (e.g. a committed charge) uncompensated.
|
|
285
|
+
var compensated = [];
|
|
286
|
+
var stateStore = {
|
|
287
|
+
saveStep: async function () {},
|
|
288
|
+
loadResumePoint: async function () { return { stepIndex: 2, state: { s1: "done", s2: "done" } }; },
|
|
289
|
+
markFailed: async function () {},
|
|
290
|
+
};
|
|
291
|
+
var saga = b.agent.saga.create({
|
|
292
|
+
name: "test.resume-compensate",
|
|
293
|
+
stateStore: stateStore,
|
|
294
|
+
steps: [
|
|
295
|
+
{ name: "s1", run: async function () {}, compensate: async function () { compensated.push("s1"); } },
|
|
296
|
+
{ name: "s2", run: async function () {}, compensate: async function () { compensated.push("s2"); } },
|
|
297
|
+
{ name: "s3", run: async function () { throw new Error("s3 boom"); },
|
|
298
|
+
compensate: async function () { compensated.push("s3"); } },
|
|
299
|
+
],
|
|
300
|
+
});
|
|
301
|
+
var threw = null;
|
|
302
|
+
try { await saga.resume("saga-X", {}, {}); } catch (e) { threw = e; }
|
|
303
|
+
check("resume-then-fail rejects with agent-saga/failed", threw && /agent-saga\/failed/.test(threw.code || ""));
|
|
304
|
+
check("resume compensates pre-crash s2 first (reverse order)", compensated[0] === "s2");
|
|
305
|
+
check("resume compensates pre-crash s1 second", compensated[1] === "s1");
|
|
306
|
+
check("resume compensates BOTH pre-crash steps", compensated.length === 2);
|
|
307
|
+
check("the failing s3 is not compensated", compensated.indexOf("s3") === -1);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async function testResumeRefusesTerminalSaga() {
|
|
311
|
+
// A saga that already reached a terminal state (failed-and-compensated, or
|
|
312
|
+
// completed) must not be resumed — replaying it would re-invoke the completed
|
|
313
|
+
// steps' compensators, which are not required to be idempotent (a double
|
|
314
|
+
// refund). A stateStore that marks the saga terminal (resumePoint.terminal)
|
|
315
|
+
// gets the resume refused rather than replayed.
|
|
316
|
+
var compensated = [];
|
|
317
|
+
var stateStore = {
|
|
318
|
+
saveStep: async function () {},
|
|
319
|
+
loadResumePoint: async function () { return { stepIndex: 2, state: {}, terminal: true }; },
|
|
320
|
+
markFailed: async function () {},
|
|
321
|
+
};
|
|
322
|
+
var saga = b.agent.saga.create({
|
|
323
|
+
name: "test.terminal-resume",
|
|
324
|
+
stateStore: stateStore,
|
|
325
|
+
steps: [
|
|
326
|
+
{ name: "s1", run: async function () {}, compensate: async function () { compensated.push("s1"); } },
|
|
327
|
+
{ name: "s2", run: async function () {}, compensate: async function () { compensated.push("s2"); } },
|
|
328
|
+
{ name: "s3", run: async function () {}, compensate: async function () { compensated.push("s3"); } },
|
|
329
|
+
],
|
|
330
|
+
});
|
|
331
|
+
var threw = null;
|
|
332
|
+
try { await saga.resume("saga-terminal", {}, {}); } catch (e) { threw = e; }
|
|
333
|
+
check("resume of a terminal saga is refused", threw && /agent-saga\/not-resumable/.test(threw.code || ""));
|
|
334
|
+
check("a refused terminal resume runs no compensators", compensated.length === 0);
|
|
335
|
+
}
|
|
336
|
+
|
|
277
337
|
module.exports = { run: run };
|
|
278
338
|
if (require.main === module) {
|
|
279
339
|
run().then(function () { console.log("OK"); })
|
|
@@ -478,6 +478,8 @@ async function runReseal() {
|
|
|
478
478
|
await testResealSkipsPlaintextRows();
|
|
479
479
|
await testResealRefusesNonVaultSealer();
|
|
480
480
|
await testResealDescriptorMapsStore();
|
|
481
|
+
await testResealDescriptorBackendKey();
|
|
482
|
+
await testResealRekeyFailure();
|
|
481
483
|
} finally {
|
|
482
484
|
helpers.teardownVaultOnly(tmpDir);
|
|
483
485
|
}
|
|
@@ -529,14 +531,523 @@ async function testAllowPlaintextRefusedUnderRegulatedPosture() {
|
|
|
529
531
|
persisted && typeof persisted.snapshotId === "string");
|
|
530
532
|
}
|
|
531
533
|
|
|
534
|
+
// ---- Load-gate: wrapper-vs-body cross-checks + signature refusals -------
|
|
535
|
+
|
|
536
|
+
async function testTenantMismatchRefused() {
|
|
537
|
+
// A hostile backend relabels a SEALED row's decorative wrapper tenantId.
|
|
538
|
+
// The seal's AAD binds table + snapshotId + schemaVersion but NOT
|
|
539
|
+
// tenantId, so the Poly1305 tag still verifies after the relabel — yet
|
|
540
|
+
// the wrapper tenantId is exactly what loadLatest({ tenantId }) filters
|
|
541
|
+
// on. Without a wrapper-vs-body cross-check, loadLatest({ tenantId:"b" })
|
|
542
|
+
// returns tenant-a's AUTHENTIC snapshot (cross-tenant restore). The load
|
|
543
|
+
// gate must refuse the relabel.
|
|
544
|
+
var backend = _fakeBackend();
|
|
545
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
546
|
+
var s = await snapshot.takeSnapshot({ tenantId: "tenant-a" });
|
|
547
|
+
await snapshot.persist(s);
|
|
548
|
+
var raw = await backend.get(s.snapshotId);
|
|
549
|
+
await backend.put(s.snapshotId, Object.assign({}, raw, { tenantId: "tenant-b" }));
|
|
550
|
+
await expectRejection("loadLatest refuses relabelled cross-tenant wrapper",
|
|
551
|
+
snapshot.loadLatest({ tenantId: "tenant-b" }),
|
|
552
|
+
"agent-snapshot/tenant-id-mismatch");
|
|
553
|
+
|
|
554
|
+
// Control — an untouched tenant still round-trips.
|
|
555
|
+
var backend2 = _fakeBackend();
|
|
556
|
+
var snap2 = _signedSnapshot({ backend: backend2 });
|
|
557
|
+
var s2 = await snap2.takeSnapshot({ tenantId: "tenant-c" });
|
|
558
|
+
await snap2.persist(s2);
|
|
559
|
+
var ok = await snap2.loadLatest({ tenantId: "tenant-c" });
|
|
560
|
+
check("loadLatest returns matching-tenant snapshot",
|
|
561
|
+
ok && ok.snapshotId === s2.snapshotId && ok.tenantId === "tenant-c");
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async function testTakenAtMismatchRefused() {
|
|
565
|
+
// Same class as the tenant relabel: loadLatest sorts candidates on the
|
|
566
|
+
// untrusted wrapper takenAt to pick "latest", but takenAt is not AAD-bound,
|
|
567
|
+
// so a hostile backend can relabel a returned row's age. takenAt is a signed
|
|
568
|
+
// body field, so the load gate cross-checks the wrapper against the body and
|
|
569
|
+
// refuses a divergence (audit-integrity / rollback defense).
|
|
570
|
+
var backend = _fakeBackend();
|
|
571
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
572
|
+
var s = await snapshot.takeSnapshot({ tenantId: "tenant-a" });
|
|
573
|
+
await snapshot.persist(s);
|
|
574
|
+
var raw = await backend.get(s.snapshotId);
|
|
575
|
+
await backend.put(s.snapshotId, Object.assign({}, raw, { takenAt: (raw.takenAt || 0) + 1000000 }));
|
|
576
|
+
await expectRejection("loadById refuses a relabelled wrapper takenAt",
|
|
577
|
+
snapshot.loadById(s.snapshotId),
|
|
578
|
+
"agent-snapshot/taken-at-mismatch");
|
|
579
|
+
|
|
580
|
+
// Control — an untouched row still round-trips.
|
|
581
|
+
var backend2 = _fakeBackend();
|
|
582
|
+
var snap2 = _signedSnapshot({ backend: backend2 });
|
|
583
|
+
var s2 = await snap2.takeSnapshot({ tenantId: "tenant-c" });
|
|
584
|
+
await snap2.persist(s2);
|
|
585
|
+
var ok = await snap2.loadLatest({ tenantId: "tenant-c" });
|
|
586
|
+
check("loadLatest returns row with un-relabelled takenAt",
|
|
587
|
+
ok && ok.snapshotId === s2.snapshotId);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// A backend whose list() can be forged independently of get() — the deeper
|
|
591
|
+
// threat model where list() and get() are separately tamperable.
|
|
592
|
+
function _listForgingBackend() {
|
|
593
|
+
var map = new Map();
|
|
594
|
+
var forge = null; // when set: { field, value } applied to list() entries only
|
|
595
|
+
return {
|
|
596
|
+
put: function (k, v) { map.set(k, v); return Promise.resolve(); },
|
|
597
|
+
get: function (k) { return Promise.resolve(map.get(k) || null); },
|
|
598
|
+
delete: function (k) { map.delete(k); return Promise.resolve(); },
|
|
599
|
+
list: function () {
|
|
600
|
+
var out = [];
|
|
601
|
+
map.forEach(function (v) {
|
|
602
|
+
if (forge) { var c = Object.assign({}, v); c[forge.field] = forge.value; out.push(c); }
|
|
603
|
+
else out.push(v);
|
|
604
|
+
});
|
|
605
|
+
return Promise.resolve(out);
|
|
606
|
+
},
|
|
607
|
+
forgeList: function (field, value) { forge = { field: field, value: value }; },
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
async function testListOnlyTenantForgeryRefused() {
|
|
612
|
+
// Deeper than a get() wrapper relabel: list() and get() are independently
|
|
613
|
+
// tamperable. A backend that relabels tenant A's LIST entry as tenant B while
|
|
614
|
+
// leaving A's get() row honest passes the wrapper/body cross-check in
|
|
615
|
+
// _unwrapAndVerify (the honest row agrees with its own body), yet
|
|
616
|
+
// loadLatest({ tenantId:'tenant-b' }) selects it via the forged list filter
|
|
617
|
+
// and would return A's authentic snapshot for a tenant-B query. The requested
|
|
618
|
+
// tenantId must be bound to the loaded snapshot's authenticated tenantId.
|
|
619
|
+
var backend = _listForgingBackend();
|
|
620
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
621
|
+
var s = await snapshot.takeSnapshot({ tenantId: "tenant-a" });
|
|
622
|
+
await snapshot.persist(s);
|
|
623
|
+
backend.forgeList("tenantId", "tenant-b"); // list() now claims tenant-b; get() stays tenant-a
|
|
624
|
+
await expectRejection("loadLatest refuses a list()-only tenant forgery (requested vs authenticated)",
|
|
625
|
+
snapshot.loadLatest({ tenantId: "tenant-b" }),
|
|
626
|
+
"agent-snapshot/tenant-id-mismatch");
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
async function testListOnlyTakenAtForgeryRefused() {
|
|
630
|
+
// list() sort metadata is likewise untrusted: a backend that inflates a row's
|
|
631
|
+
// list() takenAt to win the "latest" sort, while get() returns the honest
|
|
632
|
+
// (older) body, is caught by binding the selection sort key to the loaded
|
|
633
|
+
// snapshot's authenticated takenAt.
|
|
634
|
+
var backend = _listForgingBackend();
|
|
635
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
636
|
+
var s = await snapshot.takeSnapshot({ tenantId: "tenant-a" });
|
|
637
|
+
await snapshot.persist(s);
|
|
638
|
+
backend.forgeList("takenAt", 99999999999999); // list() claims a far-future age; get() stays honest
|
|
639
|
+
await expectRejection("loadLatest refuses a list()-only takenAt sort-key forgery",
|
|
640
|
+
snapshot.loadLatest({ tenantId: "tenant-a" }),
|
|
641
|
+
"agent-snapshot/taken-at-mismatch");
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
async function testTenantMismatchTamperDirections() {
|
|
645
|
+
// Both directions of a wrapper/body tenant divergence are refused: a
|
|
646
|
+
// hostile backend that ADDS a tenant to a no-tenant body, and one that
|
|
647
|
+
// STRIPS the tenant from a tenant body.
|
|
648
|
+
var backend = _fakeBackend();
|
|
649
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
650
|
+
|
|
651
|
+
var s0 = await snapshot.takeSnapshot({});
|
|
652
|
+
await snapshot.persist(s0);
|
|
653
|
+
var raw0 = await backend.get(s0.snapshotId);
|
|
654
|
+
await backend.put(s0.snapshotId, Object.assign({}, raw0, { tenantId: "ghost" }));
|
|
655
|
+
await expectRejection("wrapper adds a tenant to a no-tenant body → refused",
|
|
656
|
+
snapshot.loadById(s0.snapshotId), "agent-snapshot/tenant-id-mismatch");
|
|
657
|
+
|
|
658
|
+
var s1 = await snapshot.takeSnapshot({ tenantId: "real" });
|
|
659
|
+
await snapshot.persist(s1);
|
|
660
|
+
var raw1 = await backend.get(s1.snapshotId);
|
|
661
|
+
await backend.put(s1.snapshotId, Object.assign({}, raw1, { tenantId: null }));
|
|
662
|
+
await expectRejection("wrapper strips the tenant from a tenant body → refused",
|
|
663
|
+
snapshot.loadById(s1.snapshotId), "agent-snapshot/tenant-id-mismatch");
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
async function testTopologySameCountRemap() {
|
|
667
|
+
// Same consumer COUNT but a different topic SET is a real topology
|
|
668
|
+
// change — a count-only comparison would miss it and defeat
|
|
669
|
+
// refuseOnTopologyChange. [a,b] -> [a,c].
|
|
670
|
+
var snapHealth = { agents: [], elections: [], consumers: [{ topic: "a" }, { topic: "b" }], streams: 0, draining: false, overall: "ok" };
|
|
671
|
+
var restoreHealth = { agents: [], elections: [], consumers: [{ topic: "a" }, { topic: "c" }], streams: 0, draining: false, overall: "ok" };
|
|
672
|
+
var s1 = _signedSnapshot({ orchestrator: _fakeOrch(snapHealth) });
|
|
673
|
+
var snap = await s1.takeSnapshot({ sagas: [{ id: "x" }] });
|
|
674
|
+
var r = await _signedSnapshot({ orchestrator: _fakeOrch(restoreHealth) }).restore(snap, {});
|
|
675
|
+
check("same-count topic remap detected as topology change", r.topologyChanged === true);
|
|
676
|
+
await expectRejection("same-count remap honored by refuseOnTopologyChange",
|
|
677
|
+
_signedSnapshot({ orchestrator: _fakeOrch(restoreHealth) })
|
|
678
|
+
.restore(snap, { refuseOnTopologyChange: true }),
|
|
679
|
+
"agent-snapshot/topology-changed");
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
async function testSnapshotIdMismatchRefused() {
|
|
683
|
+
// A hostile backend returns a different snapshot's body for the
|
|
684
|
+
// requested id. The wrapper/body snapshotId cross-check refuses it
|
|
685
|
+
// before any signature is even consulted.
|
|
686
|
+
var backend = _fakeBackend();
|
|
687
|
+
var writer = _signedSnapshot({ backend: backend });
|
|
688
|
+
var s = await writer.takeSnapshot({});
|
|
689
|
+
await writer.persist(s);
|
|
690
|
+
await backend.put("different-key", s);
|
|
691
|
+
await expectRejection("loadById refuses wrapper/body snapshotId mismatch",
|
|
692
|
+
writer.loadById("different-key"), "agent-snapshot/snapshot-id-mismatch");
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
async function testPlaintextForgedSignatureRefused() {
|
|
696
|
+
// Plaintext-downgrade + forgery: an attacker writes a bare (unsealed)
|
|
697
|
+
// envelope with a tampered signed field, so the stored signature no
|
|
698
|
+
// longer covers the bytes. Load must refuse with bad-signature.
|
|
699
|
+
var backend = _fakeBackend();
|
|
700
|
+
var writer = _signedSnapshot({ backend: backend });
|
|
701
|
+
var s = await writer.takeSnapshot({});
|
|
702
|
+
await writer.persist(s);
|
|
703
|
+
var forged = Object.assign({}, s, { takenAt: s.takenAt + 1 });
|
|
704
|
+
await backend.put(forged.snapshotId, forged);
|
|
705
|
+
await expectRejection("loadById refuses forged plaintext (bad signature)",
|
|
706
|
+
writer.loadById(forged.snapshotId), "agent-snapshot/bad-signature");
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
async function testVerifyThrowsRefused() {
|
|
710
|
+
// A verifier that THROWS (e.g. malformed key material) must fail closed
|
|
711
|
+
// to bad-signature, never accept the snapshot.
|
|
712
|
+
var base = _fakeSigner();
|
|
713
|
+
var throwingVerify = {
|
|
714
|
+
sign: base.sign,
|
|
715
|
+
verify: function () { throw new Error("verify boom"); },
|
|
716
|
+
getPublicKey: function () { return null; },
|
|
717
|
+
};
|
|
718
|
+
var backend = _fakeBackend();
|
|
719
|
+
var snapshot = b.agent.snapshot.create({
|
|
720
|
+
orchestrator: _fakeOrch(), backend: backend, signer: throwingVerify, sealer: _fakeSealer(),
|
|
721
|
+
});
|
|
722
|
+
var s = await snapshot.takeSnapshot({});
|
|
723
|
+
await snapshot.persist(s);
|
|
724
|
+
await expectRejection("load refuses when verify throws",
|
|
725
|
+
snapshot.loadById(s.snapshotId), "agent-snapshot/bad-signature");
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
async function testSealedLoadWithoutSealerRefused() {
|
|
729
|
+
// An allowPlaintext-mode loader (no sealer wired, vault not initialized)
|
|
730
|
+
// encountering a SEALED row must refuse — it cannot silently skip the
|
|
731
|
+
// seal and treat the ciphertext as plaintext.
|
|
732
|
+
var backend = _fakeBackend();
|
|
733
|
+
var writer = _signedSnapshot({ backend: backend });
|
|
734
|
+
var s = await writer.takeSnapshot({});
|
|
735
|
+
await writer.persist(s);
|
|
736
|
+
var loader = b.agent.snapshot.create({
|
|
737
|
+
orchestrator: _fakeOrch(), backend: backend, signer: _fakeSigner(), allowPlaintext: true,
|
|
738
|
+
});
|
|
739
|
+
await expectRejection("sealed row + no sealer on load refuses",
|
|
740
|
+
loader.loadById(s.snapshotId), "agent-snapshot/sealer-not-wired");
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
async function testPersistSealerNotWiredRefused() {
|
|
744
|
+
// Signer wired, no sealer, vault not initialized, allowPlaintext not set
|
|
745
|
+
// — persist must refuse rather than write cleartext (secure-by-default).
|
|
746
|
+
var snapshot = b.agent.snapshot.create({
|
|
747
|
+
orchestrator: _fakeOrch(), backend: _fakeBackend(), signer: _fakeSigner(),
|
|
748
|
+
});
|
|
749
|
+
var s = await snapshot.takeSnapshot({});
|
|
750
|
+
await expectRejection("persist without sealer refuses (sealer-not-wired)",
|
|
751
|
+
snapshot.persist(s), "agent-snapshot/sealer-not-wired");
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// ---- Size caps + defensive take-snapshot shape -------------------------
|
|
755
|
+
|
|
756
|
+
async function testTakeSnapshotOversizeRefused() {
|
|
757
|
+
var tiny = b.agent.snapshot.create({
|
|
758
|
+
orchestrator: _fakeOrch(), backend: _fakeBackend(),
|
|
759
|
+
signer: _fakeSigner(), sealer: _fakeSealer(),
|
|
760
|
+
policy: { maxSnapshotBytes: 10, drainTimeoutMs: 1000, snapshotIntervalMs: 2000 },
|
|
761
|
+
});
|
|
762
|
+
await expectRejection("takeSnapshot oversize refuses",
|
|
763
|
+
tiny.takeSnapshot({}), "agent-snapshot/oversize");
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
async function testPersistOversizeRefused() {
|
|
767
|
+
// takeSnapshot on a generous facade, persist on a tiny-cap facade: the
|
|
768
|
+
// signed envelope exceeds the persist-time cap.
|
|
769
|
+
var big = _signedSnapshot();
|
|
770
|
+
var s = await big.takeSnapshot({});
|
|
771
|
+
var tiny = b.agent.snapshot.create({
|
|
772
|
+
orchestrator: _fakeOrch(), backend: _fakeBackend(),
|
|
773
|
+
signer: _fakeSigner(), sealer: _fakeSealer(),
|
|
774
|
+
policy: { maxSnapshotBytes: 10 },
|
|
775
|
+
});
|
|
776
|
+
await expectRejection("persist oversize refuses",
|
|
777
|
+
tiny.persist(s), "agent-snapshot/oversize");
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
async function testTakeSnapshotHealthNonArray() {
|
|
781
|
+
// health() that omits the agents/elections/consumers arrays coerces to
|
|
782
|
+
// empty arrays rather than throwing. takeSnapshot() with no opts also
|
|
783
|
+
// exercises the snapshotOpts default.
|
|
784
|
+
var snapshot = _signedSnapshot({ orchestrator: _fakeOrch({ overall: "ok" }) });
|
|
785
|
+
var s = await snapshot.takeSnapshot();
|
|
786
|
+
check("health non-array → empty agents",
|
|
787
|
+
Array.isArray(s.orchestratorState.agents) && s.orchestratorState.agents.length === 0);
|
|
788
|
+
check("health non-array → empty elections", s.orchestratorState.elections.length === 0);
|
|
789
|
+
check("health non-array → empty consumers", s.orchestratorState.consumers.length === 0);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// ---- Restore-handler dispatch edges ------------------------------------
|
|
793
|
+
|
|
794
|
+
async function testRestoreNoHandlersAcknowledgedDrop() {
|
|
795
|
+
// In-flight items, no handlers, requireHandlers NOT set → the drop is
|
|
796
|
+
// acknowledged: restore returns a zero-count result (no throw), the
|
|
797
|
+
// audited skip is the operator's grep signal.
|
|
798
|
+
var snapshot = _signedSnapshot();
|
|
799
|
+
var snap = await snapshot.takeSnapshot({ sagas: [{ id: "s1" }] });
|
|
800
|
+
var r = await snapshot.restore(snap);
|
|
801
|
+
check("restore acknowledged-drop echoes snapshotId", r.snapshotId === snap.snapshotId);
|
|
802
|
+
check("restore acknowledged-drop counts zero", r.restored.sagas === 0);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
async function testRestoreHandlerThrows() {
|
|
806
|
+
var handlers = { sagas: function () { throw new Error("handler boom"); } };
|
|
807
|
+
var snapshot = _signedSnapshot({ restoreHandlers: handlers });
|
|
808
|
+
var snap = await snapshot.takeSnapshot({ sagas: [{ id: "s1" }] });
|
|
809
|
+
await expectRejection("restore handler throw surfaces as restore-handler-failed",
|
|
810
|
+
snapshot.restore(snap, {}), "agent-snapshot/restore-handler-failed");
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
async function testRestoreVoidHandlerAndNullPayload() {
|
|
814
|
+
// Void (return-undefined) handlers: array payloads count their length,
|
|
815
|
+
// object payloads count 1; a null payload segment is a 0-count no-op.
|
|
816
|
+
var handlers = {
|
|
817
|
+
sagas: function () { /* void, array payload */ },
|
|
818
|
+
idempotencyCache: function () { /* void, object payload */ },
|
|
819
|
+
streams: function () { /* payload forced null below */ },
|
|
820
|
+
};
|
|
821
|
+
var snapshot = _signedSnapshot({ restoreHandlers: handlers });
|
|
822
|
+
var snap = await snapshot.takeSnapshot({
|
|
823
|
+
sagas: [{ id: "s1" }, { id: "s2" }], idempotencyCache: { hot: 1 },
|
|
824
|
+
});
|
|
825
|
+
snap.inFlight.streams = null;
|
|
826
|
+
var r = await snapshot.restore(snap, {});
|
|
827
|
+
check("void array-handler returns payload length", r.restored.sagas === 2);
|
|
828
|
+
check("void object-handler returns 1", r.restored.idempotencyCache === 1);
|
|
829
|
+
check("null-payload handler returns 0", r.restored.streams === 0);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// ---- Load/list/gc filtering + defensive backends -----------------------
|
|
833
|
+
|
|
834
|
+
async function testLoadLatestTenantFilter() {
|
|
835
|
+
var snapshot = _signedSnapshot();
|
|
836
|
+
var sa = await snapshot.takeSnapshot({ tenantId: "t-alpha" });
|
|
837
|
+
await snapshot.persist(sa);
|
|
838
|
+
var missByTenant = await snapshot.loadLatest({ tenantId: "t-nope" });
|
|
839
|
+
check("loadLatest tenant filter: no match → null", missByTenant === null);
|
|
840
|
+
var hit = await snapshot.loadLatest({ tenantId: "t-alpha" });
|
|
841
|
+
check("loadLatest tenant filter: match returns snap",
|
|
842
|
+
hit && hit.snapshotId === sa.snapshotId);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
async function testListFilters() {
|
|
846
|
+
var snapshot = _signedSnapshot();
|
|
847
|
+
var sa = await snapshot.takeSnapshot({ tenantId: "l-alpha" });
|
|
848
|
+
await snapshot.persist(sa);
|
|
849
|
+
var only = await snapshot.list({ tenantId: "l-alpha", sinceMs: 1 });
|
|
850
|
+
check("list tenant+since filter keeps match",
|
|
851
|
+
only.length === 1 && only[0].tenantId === "l-alpha");
|
|
852
|
+
var none = await snapshot.list({ tenantId: "l-beta" });
|
|
853
|
+
check("list tenant filter excludes non-match", none.length === 0);
|
|
854
|
+
var future = await snapshot.list({ sinceMs: Date.now() + 100000 });
|
|
855
|
+
check("list sinceMs filter excludes older", future.length === 0);
|
|
856
|
+
var all = await snapshot.list();
|
|
857
|
+
check("list() no opts returns entries", all.length === 1);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
async function testGcNoDeleteBackend() {
|
|
861
|
+
var noDel = {
|
|
862
|
+
put: function () { return Promise.resolve(); },
|
|
863
|
+
get: function () { return Promise.resolve(null); },
|
|
864
|
+
list: function () { return Promise.resolve([]); },
|
|
865
|
+
};
|
|
866
|
+
var snapshot = _signedSnapshot({ backend: noDel });
|
|
867
|
+
var r = await snapshot.gc();
|
|
868
|
+
check("gc without backend.delete → purged 0", r.purged === 0);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
async function testGcDeleteThrows() {
|
|
872
|
+
var map = new Map();
|
|
873
|
+
var throwingDel = {
|
|
874
|
+
put: function (k, v) { map.set(k, v); return Promise.resolve(); },
|
|
875
|
+
get: function (k) { return Promise.resolve(map.get(k) || null); },
|
|
876
|
+
list: function () { var o = []; map.forEach(function (v) { o.push(v); }); return Promise.resolve(o); },
|
|
877
|
+
delete: function () { return Promise.reject(new Error("delete boom")); },
|
|
878
|
+
};
|
|
879
|
+
var snapshot = _signedSnapshot({ backend: throwingDel });
|
|
880
|
+
var s = await snapshot.takeSnapshot({});
|
|
881
|
+
await snapshot.persist(s);
|
|
882
|
+
await helpers.waitUntil(function () { return Date.now() > s.takenAt; },
|
|
883
|
+
{ label: "agent-snapshot.gc: clock past takenAt before delete-throw gc" });
|
|
884
|
+
var r = await snapshot.gc({ olderThanMs: 0 });
|
|
885
|
+
check("gc swallows delete rejection, purged 0", r.purged === 0);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// ---- create() + reseal() input-shape edges -----------------------------
|
|
889
|
+
|
|
890
|
+
async function testCreateNoArgs() {
|
|
891
|
+
var threw = null;
|
|
892
|
+
try { b.agent.snapshot.create(); } catch (e) { threw = e; }
|
|
893
|
+
check("create() no args → bad-orchestrator",
|
|
894
|
+
threw && (threw.code || "").indexOf("agent-snapshot/bad-orchestrator") !== -1);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
async function testResealBackendListNonArray() {
|
|
898
|
+
var backend = {
|
|
899
|
+
put: function () { return Promise.resolve(); },
|
|
900
|
+
get: function () { return Promise.resolve(null); },
|
|
901
|
+
list: function () { return Promise.resolve(null); },
|
|
902
|
+
};
|
|
903
|
+
var r = await b.agent.snapshot.reseal({ backend: backend, oldRootJson: "x", newRootJson: "y" });
|
|
904
|
+
check("reseal list non-array → resealed 0",
|
|
905
|
+
r.resealed === 0 && r.table === "agent.snapshot");
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
async function testResealSkipsBadEntries() {
|
|
909
|
+
var backend = {
|
|
910
|
+
put: function () { return Promise.resolve(); },
|
|
911
|
+
get: function (k) { return Promise.resolve(k === "present-null" ? null : null); },
|
|
912
|
+
list: function () {
|
|
913
|
+
return Promise.resolve([{}, { snapshotId: "" }, { snapshotId: "present-null" }]);
|
|
914
|
+
},
|
|
915
|
+
};
|
|
916
|
+
var r = await b.agent.snapshot.reseal({ backend: backend, oldRootJson: "x", newRootJson: "y" });
|
|
917
|
+
check("reseal skips no/empty snapshotId + missing raw", r.resealed === 0);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
async function testResealNoArgsAndDescriptorNoArgs() {
|
|
921
|
+
await expectRejection("reseal() no args → bad-backend",
|
|
922
|
+
b.agent.snapshot.reseal(), "agent-snapshot/bad-backend");
|
|
923
|
+
await expectRejection("AAD_ROTATION.reseal() no args → bad-backend",
|
|
924
|
+
b.agent.snapshot.AAD_ROTATION.reseal(), "agent-snapshot/bad-backend");
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
async function testLoadByIdBadId() {
|
|
928
|
+
var snapshot = _signedSnapshot();
|
|
929
|
+
await expectRejection("loadById empty id refuses",
|
|
930
|
+
snapshot.loadById(""), "agent-snapshot/bad-snapshot-id");
|
|
931
|
+
await expectRejection("loadById non-string id refuses",
|
|
932
|
+
snapshot.loadById(null), "agent-snapshot/bad-snapshot-id");
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
async function testListAndLoadLatestBackendNonArray() {
|
|
936
|
+
var backend = {
|
|
937
|
+
put: function () { return Promise.resolve(); },
|
|
938
|
+
get: function () { return Promise.resolve(null); },
|
|
939
|
+
list: function () { return Promise.resolve(null); },
|
|
940
|
+
};
|
|
941
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
942
|
+
var l = await snapshot.list({});
|
|
943
|
+
check("list non-array backend → []", Array.isArray(l) && l.length === 0);
|
|
944
|
+
var latest = await snapshot.loadLatest({});
|
|
945
|
+
check("loadLatest non-array backend → null", latest === null);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
async function testGcDefaultOlderThan() {
|
|
949
|
+
var backend = _fakeBackend();
|
|
950
|
+
var snapshot = _signedSnapshot({ backend: backend });
|
|
951
|
+
var s = await snapshot.takeSnapshot({});
|
|
952
|
+
await snapshot.persist(s);
|
|
953
|
+
await helpers.waitUntil(function () { return Date.now() > s.takenAt; },
|
|
954
|
+
{ label: "agent-snapshot.gc: clock past takenAt for default-olderThan gc" });
|
|
955
|
+
var r = await snapshot.gc({});
|
|
956
|
+
check("gc default olderThanMs purges old entry",
|
|
957
|
+
r.purged === 1 && backend._size() === 0);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
async function testRealAuditSignerRoundTrip() {
|
|
961
|
+
// No opts.signer → _resolveSigner falls back to the framework's real
|
|
962
|
+
// b.auditSign, exercising the signer wrapper (sign / verify /
|
|
963
|
+
// getPublicKey) and persist's getPublicKey-bound sigPubKey path.
|
|
964
|
+
var dir = fs.mkdtempSync(path.join(os.tmpdir(), "blamejs-snapshot-auditsign-"));
|
|
965
|
+
b.auditSign._resetForTest();
|
|
966
|
+
await b.auditSign.init({ dataDir: dir, mode: "plaintext", algorithm: "ml-dsa-65" });
|
|
967
|
+
try {
|
|
968
|
+
var backend = _fakeBackend();
|
|
969
|
+
var snapshot = b.agent.snapshot.create({
|
|
970
|
+
orchestrator: _fakeOrch(), backend: backend, sealer: _fakeSealer(),
|
|
971
|
+
});
|
|
972
|
+
var s = await snapshot.takeSnapshot({});
|
|
973
|
+
await snapshot.persist(s);
|
|
974
|
+
check("real auditSign: sig populated",
|
|
975
|
+
typeof s.sig === "string" && s.sig.length > 0);
|
|
976
|
+
check("real auditSign: sigPubKey bound off getPublicKey",
|
|
977
|
+
typeof s.sigPubKey === "string" && s.sigPubKey.length > 0);
|
|
978
|
+
var loaded = await snapshot.loadById(s.snapshotId);
|
|
979
|
+
check("real auditSign: verified round-trip",
|
|
980
|
+
loaded && loaded.snapshotId === s.snapshotId);
|
|
981
|
+
} finally {
|
|
982
|
+
b.auditSign._resetForTest();
|
|
983
|
+
try { fs.rmSync(dir, { recursive: true, force: true }); } catch (_e) { /* best-effort */ }
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// ---- reseal rekey-failure + descriptor backend-key (vault-backed) ------
|
|
988
|
+
|
|
989
|
+
async function testResealRekeyFailure() {
|
|
990
|
+
var backend = _fakeBackend();
|
|
991
|
+
var snapshot = _vaultBackedSnapshot(backend);
|
|
992
|
+
var snap = await snapshot.takeSnapshot({});
|
|
993
|
+
await snapshot.persist(snap);
|
|
994
|
+
var raw = await backend.get(snap.snapshotId);
|
|
995
|
+
var prefix = b.agent.snapshot.SEALED_PREFIX;
|
|
996
|
+
var inner = raw.sealed.slice(prefix.length);
|
|
997
|
+
// Corrupt the inner vault.aad ciphertext (keep the prefix so it still
|
|
998
|
+
// looks vault-sealed) so resealRoot's unseal fails. Stamp an explicit
|
|
999
|
+
// wrapper schemaVersion so the != null AAD reconstruction branch runs.
|
|
1000
|
+
var corrupted = inner.slice(0, inner.length - 6) + "AAAAAA";
|
|
1001
|
+
await backend.put(snap.snapshotId,
|
|
1002
|
+
Object.assign({}, raw, { sealed: prefix + corrupted, schemaVersion: 1 }));
|
|
1003
|
+
var oldRootJson = b.vault.getKeysJson();
|
|
1004
|
+
var newRootJson = JSON.stringify(
|
|
1005
|
+
Object.assign(JSON.parse(oldRootJson), { _rotationTestRoot: "v6" }));
|
|
1006
|
+
await expectRejection("reseal refuses a row it cannot re-key",
|
|
1007
|
+
b.agent.snapshot.reseal({
|
|
1008
|
+
backend: backend, oldRootJson: oldRootJson, newRootJson: newRootJson,
|
|
1009
|
+
}),
|
|
1010
|
+
"agent-snapshot/reseal-failed");
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
async function testResealDescriptorBackendKey() {
|
|
1014
|
+
// AAD_ROTATION.reseal maps `backend` when the pipeline passes no `store`.
|
|
1015
|
+
var backend = _fakeBackend();
|
|
1016
|
+
var snapshot = _vaultBackedSnapshot(backend);
|
|
1017
|
+
await snapshot.persist(await snapshot.takeSnapshot({}));
|
|
1018
|
+
var oldRootJson = b.vault.getKeysJson();
|
|
1019
|
+
var newRootJson = JSON.stringify(
|
|
1020
|
+
Object.assign(JSON.parse(oldRootJson), { _rotationTestRoot: "v7" }));
|
|
1021
|
+
var result = await b.agent.snapshot.AAD_ROTATION.reseal({
|
|
1022
|
+
backend: backend, oldRootJson: oldRootJson, newRootJson: newRootJson,
|
|
1023
|
+
});
|
|
1024
|
+
check("AAD_ROTATION.reseal via backend key re-keyed", result.resealed === 1);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
532
1027
|
async function run() {
|
|
533
1028
|
testSurface();
|
|
534
1029
|
await testCreateRequiresOrchestrator();
|
|
535
1030
|
await testCreateRequiresBackend();
|
|
1031
|
+
await testCreateNoArgs();
|
|
536
1032
|
await testSignerNotWiredRefused();
|
|
1033
|
+
await testPersistSealerNotWiredRefused();
|
|
537
1034
|
await testTakeAndPersist();
|
|
1035
|
+
await testTakeSnapshotHealthNonArray();
|
|
1036
|
+
await testTakeSnapshotOversizeRefused();
|
|
1037
|
+
await testPersistOversizeRefused();
|
|
538
1038
|
await testLoadLatest();
|
|
1039
|
+
await testLoadLatestTenantFilter();
|
|
539
1040
|
await testLoadById();
|
|
1041
|
+
await testSnapshotIdMismatchRefused();
|
|
1042
|
+
await testTenantMismatchRefused();
|
|
1043
|
+
await testTakenAtMismatchRefused();
|
|
1044
|
+
await testListOnlyTenantForgeryRefused();
|
|
1045
|
+
await testListOnlyTakenAtForgeryRefused();
|
|
1046
|
+
await testTenantMismatchTamperDirections();
|
|
1047
|
+
await testTopologySameCountRemap();
|
|
1048
|
+
await testPlaintextForgedSignatureRefused();
|
|
1049
|
+
await testVerifyThrowsRefused();
|
|
1050
|
+
await testSealedLoadWithoutSealerRefused();
|
|
540
1051
|
await testTamperedEnvelopeRefused();
|
|
541
1052
|
await testUnsignedEnvelopeRefused();
|
|
542
1053
|
await testAllowPlaintextRefusedUnderRegulatedPosture();
|
|
@@ -544,9 +1055,22 @@ async function run() {
|
|
|
544
1055
|
await testRefuseOnTopologyChange();
|
|
545
1056
|
await testSchemaVersionMismatch();
|
|
546
1057
|
await testList();
|
|
1058
|
+
await testListFilters();
|
|
547
1059
|
await testGc();
|
|
1060
|
+
await testGcNoDeleteBackend();
|
|
1061
|
+
await testGcDeleteThrows();
|
|
548
1062
|
await testRestoreHandlersInvoked();
|
|
549
1063
|
await testRestoreRequireHandlersRefuses();
|
|
1064
|
+
await testRestoreNoHandlersAcknowledgedDrop();
|
|
1065
|
+
await testRestoreHandlerThrows();
|
|
1066
|
+
await testRestoreVoidHandlerAndNullPayload();
|
|
1067
|
+
await testLoadByIdBadId();
|
|
1068
|
+
await testListAndLoadLatestBackendNonArray();
|
|
1069
|
+
await testGcDefaultOlderThan();
|
|
1070
|
+
await testResealBackendListNonArray();
|
|
1071
|
+
await testResealSkipsBadEntries();
|
|
1072
|
+
await testResealNoArgsAndDescriptorNoArgs();
|
|
1073
|
+
await testRealAuditSignerRoundTrip();
|
|
550
1074
|
await runReseal();
|
|
551
1075
|
}
|
|
552
1076
|
|