@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
|
@@ -129,6 +129,310 @@ function testCreateHandle() {
|
|
|
129
129
|
!v.ok && v.issues[0].ruleId === "safe-sieve/unknown-capability");
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
// ---- tests / adversarial input ------------------------------------------
|
|
133
|
+
|
|
134
|
+
function testUnknownTestRefused() {
|
|
135
|
+
// A test identifier the parser accepts (any id is a test) but the
|
|
136
|
+
// interpreter never wired — must refuse, not silently pass/fail-open.
|
|
137
|
+
var threw = null;
|
|
138
|
+
try { b.mail.sieve.runScript('if bogustest "x" { keep; }', {}); }
|
|
139
|
+
catch (e) { threw = e; }
|
|
140
|
+
check("unknown test refused with typed error",
|
|
141
|
+
threw && threw.code === "mail-sieve/unknown-test");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function testUnknownActionRefused() {
|
|
145
|
+
var threw = null;
|
|
146
|
+
try { b.mail.sieve.runScript('frobnicate;', {}); } catch (e) { threw = e; }
|
|
147
|
+
check("unknown action refused with typed error",
|
|
148
|
+
threw && threw.code === "mail-sieve/unknown-action");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function testBadCommandKind() {
|
|
152
|
+
// Hand-built AST fed to the public run() entry — an unmodeled command
|
|
153
|
+
// kind must throw a typed refusal, never fall through.
|
|
154
|
+
var threw = null;
|
|
155
|
+
try {
|
|
156
|
+
b.mail.sieve.run({ kind: "script", commands: [{ kind: "weird" }] }, {});
|
|
157
|
+
} catch (e) { threw = e; }
|
|
158
|
+
check("unmodeled command kind refused",
|
|
159
|
+
threw && threw.code === "mail-sieve/bad-command");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function testFileintoMissingFolder() {
|
|
163
|
+
var threw = null;
|
|
164
|
+
try { b.mail.sieve.runScript('require ["fileinto"];\r\nfileinto;\r\n', {}); }
|
|
165
|
+
catch (e) { threw = e; }
|
|
166
|
+
check("fileinto without folder refused",
|
|
167
|
+
threw && threw.code === "mail-sieve/bad-fileinto");
|
|
168
|
+
// Empty string-list argument is equally malformed (v.v[0] → null).
|
|
169
|
+
var threw2 = null;
|
|
170
|
+
try { b.mail.sieve.runScript('require ["fileinto"];\r\nfileinto [];\r\n', {}); }
|
|
171
|
+
catch (e) { threw2 = e; }
|
|
172
|
+
check("fileinto with empty list refused",
|
|
173
|
+
threw2 && threw2.code === "mail-sieve/bad-fileinto");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function testRedirectMissingAddress() {
|
|
177
|
+
var threw = null;
|
|
178
|
+
try { b.mail.sieve.runScript('redirect;', {}); } catch (e) { threw = e; }
|
|
179
|
+
check("redirect without address refused",
|
|
180
|
+
threw && threw.code === "mail-sieve/bad-redirect");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function testNotTest() {
|
|
184
|
+
var rv = b.mail.sieve.runScript('if not exists "X-Missing" { discard; }',
|
|
185
|
+
{ headers: [] });
|
|
186
|
+
check("`not` inverts the sub-test",
|
|
187
|
+
rv.actions[0].kind === "discard");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function testExists() {
|
|
191
|
+
var present = b.mail.sieve.runScript('if exists "Subject" { discard; }',
|
|
192
|
+
{ headers: [{ name: "Subject", value: "hi" }] });
|
|
193
|
+
check("exists fires when header present", present.actions[0].kind === "discard");
|
|
194
|
+
var absent = b.mail.sieve.runScript('if exists "Subject" { discard; }',
|
|
195
|
+
{ headers: [] });
|
|
196
|
+
check("exists false → implicit keep when header absent",
|
|
197
|
+
absent.actions[0].implicit === true);
|
|
198
|
+
// Header present but value null still counts as existing.
|
|
199
|
+
var nullVal = b.mail.sieve.runScript('if exists "X-Flag" { discard; }',
|
|
200
|
+
{ headers: [{ name: "X-Flag", value: null }] });
|
|
201
|
+
check("exists treats null-valued header as present",
|
|
202
|
+
nullVal.actions[0].kind === "discard");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function testSizeUnderAndFallbacks() {
|
|
206
|
+
var under = b.mail.sieve.runScript('if size :under 1K { discard; }',
|
|
207
|
+
{ sizeBytes: 512 });
|
|
208
|
+
check("size :under fires below threshold", under.actions[0].kind === "discard");
|
|
209
|
+
// Falls back to bodyBytes.length when sizeBytes absent.
|
|
210
|
+
var body = b.mail.sieve.runScript('if size :over 3 { discard; }',
|
|
211
|
+
{ bodyBytes: Buffer.from("hello") });
|
|
212
|
+
check("size falls back to bodyBytes.length", body.actions[0].kind === "discard");
|
|
213
|
+
// No size info at all → 0 bytes, :under fires.
|
|
214
|
+
var zero = b.mail.sieve.runScript('if size :under 10 { discard; }', {});
|
|
215
|
+
check("size defaults to 0 bytes with no env info",
|
|
216
|
+
zero.actions[0].kind === "discard");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function testAddressPartsAndExtraction() {
|
|
220
|
+
// :localpart on a display-name address.
|
|
221
|
+
var lp = b.mail.sieve.runScript(
|
|
222
|
+
'if address :is :localpart "From" "alice" { keep; }',
|
|
223
|
+
{ headers: [{ name: "From", value: "Alice Smith <alice@example.com>" }] });
|
|
224
|
+
check("address :localpart extracts local part before @",
|
|
225
|
+
lp.actions[0].kind === "keep" && !lp.actions[0].implicit);
|
|
226
|
+
// :all on a bracketed address returns the full addr-spec.
|
|
227
|
+
var all = b.mail.sieve.runScript(
|
|
228
|
+
'if address :is :all "From" "a@x.com" { keep; }',
|
|
229
|
+
{ headers: [{ name: "From", value: "A <a@x.com>" }] });
|
|
230
|
+
check("address :all extracts full addr-spec from brackets",
|
|
231
|
+
all.actions[0].kind === "keep" && !all.actions[0].implicit);
|
|
232
|
+
// Address without an @: localpart is the whole token; domain is "".
|
|
233
|
+
var noAtLocal = b.mail.sieve.runScript(
|
|
234
|
+
'if address :is :localpart "From" "weird" { keep; }',
|
|
235
|
+
{ headers: [{ name: "From", value: "weird" }] });
|
|
236
|
+
check("address :localpart of at-less token is the whole token",
|
|
237
|
+
!noAtLocal.actions[0].implicit);
|
|
238
|
+
var noAtDomain = b.mail.sieve.runScript(
|
|
239
|
+
'if address :is :domain "From" "" { keep; }',
|
|
240
|
+
{ headers: [{ name: "From", value: "nodomain" }] });
|
|
241
|
+
check("address :domain of at-less token is empty string",
|
|
242
|
+
!noAtDomain.actions[0].implicit);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function testEnvelopeArrayAndBogusField() {
|
|
246
|
+
// Array-valued envelope recipient list — each entry compared.
|
|
247
|
+
var arr = b.mail.sieve.runScript('if envelope :is "to" "b@x.com" { keep; }',
|
|
248
|
+
{ envelope: { to: ["a@x.com", "b@x.com"] } });
|
|
249
|
+
check("envelope matches any entry of an array value",
|
|
250
|
+
arr.actions[0].kind === "keep" && !arr.actions[0].implicit);
|
|
251
|
+
// Envelope field other than from/to is skipped per RFC 5228 §5.4.
|
|
252
|
+
var bogus = b.mail.sieve.runScript('if envelope :is "subject" "x" { discard; }',
|
|
253
|
+
{ envelope: { from: "a@x.com" } });
|
|
254
|
+
check("envelope ignores fields other than from/to",
|
|
255
|
+
bogus.actions[0].implicit === true);
|
|
256
|
+
// No envelope object at all → no match.
|
|
257
|
+
var none = b.mail.sieve.runScript('if envelope :is "from" "a@x.com" { discard; }', {});
|
|
258
|
+
check("envelope with no env.envelope → implicit keep",
|
|
259
|
+
none.actions[0].implicit === true);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function testHeaderListsAndMultiValue() {
|
|
263
|
+
// List of header names + list of keys.
|
|
264
|
+
var lists = b.mail.sieve.runScript(
|
|
265
|
+
'if header :contains ["To","Cc"] ["vip"] { discard; }',
|
|
266
|
+
{ headers: [{ name: "Cc", value: "vip@x.com" }] });
|
|
267
|
+
check("header test spans a list of names and keys",
|
|
268
|
+
lists.actions[0].kind === "discard");
|
|
269
|
+
// Two headers of the same name — both values considered.
|
|
270
|
+
var multi = b.mail.sieve.runScript('if header :is "Received" "b" { discard; }',
|
|
271
|
+
{ headers: [{ name: "Received", value: "a" }, { name: "Received", value: "b" }] });
|
|
272
|
+
check("header test considers every value of a repeated header",
|
|
273
|
+
multi.actions[0].kind === "discard");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function testComparatorDefaultCaseInsensitive() {
|
|
277
|
+
// Default comparator is i;ascii-casemap → case-insensitive :is.
|
|
278
|
+
var ci = b.mail.sieve.runScript('if header :is "Subject" "hello" { discard; }',
|
|
279
|
+
{ headers: [{ name: "Subject", value: "HELLO" }] });
|
|
280
|
+
check("default comparator is case-insensitive (i;ascii-casemap)",
|
|
281
|
+
ci.actions[0].kind === "discard");
|
|
282
|
+
|
|
283
|
+
// An explicit `:comparator "i;octet"` binds the comparator name to the tag
|
|
284
|
+
// (RFC 5228 §2.7.3), not into the positional stream -- so the header name and
|
|
285
|
+
// keys stay aligned and the test still matches (previously the comparator
|
|
286
|
+
// value was mis-read as the header name, silently disabling the test = a
|
|
287
|
+
// filter bypass). i;octet is case-SENSITIVE (unlike the default
|
|
288
|
+
// i;ascii-casemap): an exact-case key matches, a wrong-case key does not.
|
|
289
|
+
var octet = b.mail.sieve.runScript(
|
|
290
|
+
'if header :comparator "i;octet" :is "Subject" "HELLO" { discard; }',
|
|
291
|
+
{ headers: [{ name: "Subject", value: "HELLO" }] });
|
|
292
|
+
check("explicit :comparator :is exact-case matches (no filter bypass)",
|
|
293
|
+
octet.actions[0].kind === "discard");
|
|
294
|
+
var octetMiss = b.mail.sieve.runScript(
|
|
295
|
+
'if header :comparator "i;octet" :is "Subject" "hello" { discard; }',
|
|
296
|
+
{ headers: [{ name: "Subject", value: "HELLO" }] });
|
|
297
|
+
check("explicit :comparator i;octet is case-sensitive (wrong case falls through to keep)",
|
|
298
|
+
octetMiss.actions[0].implicit === true);
|
|
299
|
+
// A `:comparator` with no following comparator-name string fails closed at parse.
|
|
300
|
+
var badComp = false;
|
|
301
|
+
try { b.mail.sieve.runScript('if header :comparator :is "Subject" "x" { discard; }', { headers: [] }); }
|
|
302
|
+
catch (e) { badComp = /parse-error/.test(e.code || e.message); }
|
|
303
|
+
check("explicit :comparator without a value is refused at parse", badComp);
|
|
304
|
+
// An unsupported comparator name is refused at parse (like the
|
|
305
|
+
// require ["comparator-<name>"] capability guard), not silently treated as
|
|
306
|
+
// octet exact-matching -- otherwise it would bypass the capability guard.
|
|
307
|
+
var badCompName = false;
|
|
308
|
+
try {
|
|
309
|
+
b.mail.sieve.runScript('if header :comparator "i;unicode-casemap" :is "Subject" "HELLO" { discard; }',
|
|
310
|
+
{ headers: [{ name: "Subject", value: "HELLO" }] });
|
|
311
|
+
} catch (e) { badCompName = /unknown-capability|unimplemented-capability/.test(e.code || e.message); }
|
|
312
|
+
check("explicit :comparator with an unsupported name is refused (no capability-guard bypass)", badCompName);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function testWildcardEscaping() {
|
|
316
|
+
// `?` matches exactly one byte.
|
|
317
|
+
var q = b.mail.sieve.runScript('if header :matches "Subject" "a?c" { discard; }',
|
|
318
|
+
{ headers: [{ name: "Subject", value: "abc" }] });
|
|
319
|
+
check("`:matches` ? matches a single byte", q.actions[0].kind === "discard");
|
|
320
|
+
// Regex metacharacters other than * / ? are escaped — `.` is literal.
|
|
321
|
+
var dot = b.mail.sieve.runScript('if header :matches "Subject" "a.c" { discard; }',
|
|
322
|
+
{ headers: [{ name: "Subject", value: "axc" }] });
|
|
323
|
+
check("`:matches` escapes regex metachars (`.` is literal, not wildcard)",
|
|
324
|
+
dot.actions[0].implicit === true);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function testElsifElse() {
|
|
328
|
+
var script =
|
|
329
|
+
'if header :is "X" "1" { discard; }\r\n' +
|
|
330
|
+
'elsif header :is "X" "2" { redirect "a@b.com"; }\r\n' +
|
|
331
|
+
'else { keep; }\r\n';
|
|
332
|
+
var elif = b.mail.sieve.runScript(script, { headers: [{ name: "X", value: "2" }] });
|
|
333
|
+
check("elsif branch taken",
|
|
334
|
+
elif.actions[0].kind === "redirect" && elif.actions[0].address === "a@b.com");
|
|
335
|
+
var els = b.mail.sieve.runScript(script, { headers: [{ name: "X", value: "9" }] });
|
|
336
|
+
check("else branch taken when no if/elsif matches",
|
|
337
|
+
els.actions[0].kind === "keep" && !els.actions[0].implicit);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function testExplicitKeepAndStopSkips() {
|
|
341
|
+
var k = b.mail.sieve.runScript('keep;\r\n', {});
|
|
342
|
+
check("explicit keep is not marked implicit",
|
|
343
|
+
k.actions.length === 1 && k.actions[0].kind === "keep" && !k.actions[0].implicit);
|
|
344
|
+
// stop halts before a following action ever runs.
|
|
345
|
+
var s = b.mail.sieve.runScript('stop;\r\nfileinto "X";\r\n', {});
|
|
346
|
+
check("stop skips subsequent commands",
|
|
347
|
+
s.stopped === true &&
|
|
348
|
+
!s.actions.some(function (a) { return a.kind === "fileinto"; }));
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function testFileintoListArg() {
|
|
352
|
+
var rv = b.mail.sieve.runScript('require ["fileinto"];\r\nfileinto ["A","B"];\r\n', {});
|
|
353
|
+
check("fileinto takes first element of a string-list arg",
|
|
354
|
+
rv.actions[0].kind === "fileinto" && rv.actions[0].folder === "A");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function testGasExhaustionInCommands() {
|
|
358
|
+
var threw = null;
|
|
359
|
+
try { b.mail.sieve.runScript('keep;\r\nkeep;\r\nkeep;\r\n', {}, { maxGas: 2 }); }
|
|
360
|
+
catch (e) { threw = e; }
|
|
361
|
+
check("gas exhausts across a command sequence",
|
|
362
|
+
threw && threw.code === "mail-sieve/gas-exhausted");
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function testMaxGasOptValidation() {
|
|
366
|
+
var cases = [
|
|
367
|
+
["zero", 0],
|
|
368
|
+
["negative", -1],
|
|
369
|
+
["Infinity", Infinity],
|
|
370
|
+
["NaN", NaN],
|
|
371
|
+
["string", "5"],
|
|
372
|
+
["fractional", 1.5],
|
|
373
|
+
["over-cap", b.mail.sieve.MAX_GAS_UNITS + 1],
|
|
374
|
+
];
|
|
375
|
+
var allRefused = true;
|
|
376
|
+
for (var i = 0; i < cases.length; i++) {
|
|
377
|
+
var threw = null;
|
|
378
|
+
try { b.mail.sieve.runScript('keep;', {}, { maxGas: cases[i][1] }); }
|
|
379
|
+
catch (e) { threw = e; }
|
|
380
|
+
if (!threw || threw.code !== "mail-sieve/bad-opt") allRefused = false;
|
|
381
|
+
}
|
|
382
|
+
check("run() refuses every out-of-range/ill-typed maxGas", allRefused);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function testParseErrorsPropagate() {
|
|
386
|
+
// runScript surfaces the parser's typed refusals unchanged.
|
|
387
|
+
var badSyntax = null;
|
|
388
|
+
try { b.mail.sieve.runScript('if header :is', {}); } catch (e) { badSyntax = e; }
|
|
389
|
+
check("runScript propagates parse-error", badSyntax && badSyntax.code === "safe-sieve/parse-error");
|
|
390
|
+
var unimpl = null;
|
|
391
|
+
try { b.mail.sieve.runScript('require ["vacation"];\r\nkeep;\r\n', {}); }
|
|
392
|
+
catch (e) { unimpl = e; }
|
|
393
|
+
check("runScript propagates unimplemented-capability refusal",
|
|
394
|
+
unimpl && unimpl.code === "safe-sieve/unimplemented-capability");
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function testCreateOptValidation() {
|
|
398
|
+
var badOpts = null;
|
|
399
|
+
try { b.mail.sieve.create(42); } catch (e) { badOpts = e; }
|
|
400
|
+
check("create refuses non-object opts", badOpts && badOpts.code === "mail-sieve/bad-opt");
|
|
401
|
+
var badGas = null;
|
|
402
|
+
try { b.mail.sieve.create({ maxGas: -1 }); } catch (e) { badGas = e; }
|
|
403
|
+
check("create refuses bad maxGas", badGas && badGas.code === "mail-sieve/bad-opt");
|
|
404
|
+
var overCap = null;
|
|
405
|
+
try { b.mail.sieve.create({ maxGas: b.mail.sieve.MAX_GAS_UNITS + 1 }); }
|
|
406
|
+
catch (e) { overCap = e; }
|
|
407
|
+
check("create refuses maxGas over cap", overCap && overCap.code === "mail-sieve/bad-opt");
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function testCreateAuditEmissions() {
|
|
411
|
+
var events = [];
|
|
412
|
+
var sieve = b.mail.sieve.create({
|
|
413
|
+
audit: { safeEmit: function (e) { events.push(e.action + "/" + e.outcome); } },
|
|
414
|
+
});
|
|
415
|
+
sieve.runScript('keep;\r\n', {});
|
|
416
|
+
sieve.validateScript('require ["fileinto"];\r\nkeep;\r\n');
|
|
417
|
+
sieve.validateScript('require ["nonsense"];\r\nkeep;\r\n');
|
|
418
|
+
sieve.run(b.safeSieve.parse('keep;\r\n'), {});
|
|
419
|
+
check("create handle emits run + validate(success/failure) + run audit events",
|
|
420
|
+
events.length === 4 &&
|
|
421
|
+
events[0] === "mail.sieve.run/success" &&
|
|
422
|
+
events[1] === "mail.sieve.validate/success" &&
|
|
423
|
+
events[2] === "mail.sieve.validate/failure" &&
|
|
424
|
+
events[3] === "mail.sieve.run/success");
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function testCreateAuditThrowDropSilent() {
|
|
428
|
+
var sieve = b.mail.sieve.create({
|
|
429
|
+
audit: { safeEmit: function () { throw new Error("audit sink exploded"); } },
|
|
430
|
+
});
|
|
431
|
+
var rv = sieve.runScript('keep;\r\n', {});
|
|
432
|
+
check("create handle survives a throwing audit sink (drop-silent)",
|
|
433
|
+
rv.actions[0].kind === "keep");
|
|
434
|
+
}
|
|
435
|
+
|
|
132
436
|
function run() {
|
|
133
437
|
testSurface();
|
|
134
438
|
testImplicitKeep();
|
|
@@ -143,6 +447,28 @@ function run() {
|
|
|
143
447
|
testGasExhaustion();
|
|
144
448
|
testBadAst();
|
|
145
449
|
testCreateHandle();
|
|
450
|
+
testUnknownTestRefused();
|
|
451
|
+
testUnknownActionRefused();
|
|
452
|
+
testBadCommandKind();
|
|
453
|
+
testFileintoMissingFolder();
|
|
454
|
+
testRedirectMissingAddress();
|
|
455
|
+
testNotTest();
|
|
456
|
+
testExists();
|
|
457
|
+
testSizeUnderAndFallbacks();
|
|
458
|
+
testAddressPartsAndExtraction();
|
|
459
|
+
testEnvelopeArrayAndBogusField();
|
|
460
|
+
testHeaderListsAndMultiValue();
|
|
461
|
+
testComparatorDefaultCaseInsensitive();
|
|
462
|
+
testWildcardEscaping();
|
|
463
|
+
testElsifElse();
|
|
464
|
+
testExplicitKeepAndStopSkips();
|
|
465
|
+
testFileintoListArg();
|
|
466
|
+
testGasExhaustionInCommands();
|
|
467
|
+
testMaxGasOptValidation();
|
|
468
|
+
testParseErrorsPropagate();
|
|
469
|
+
testCreateOptValidation();
|
|
470
|
+
testCreateAuditEmissions();
|
|
471
|
+
testCreateAuditThrowDropSilent();
|
|
146
472
|
}
|
|
147
473
|
|
|
148
474
|
module.exports = { run: run };
|
|
@@ -102,6 +102,58 @@ function testHashEmptyAndNonString() {
|
|
|
102
102
|
check("non-string returns empty", b.mailStore.fts.hashText("t", "subject", 42) === "");
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// ---- b.mailStore.fts.hashTokens — token-array → sealed FTS string ----
|
|
106
|
+
//
|
|
107
|
+
// hashTokens hashes each token under the (table, field) namespace and
|
|
108
|
+
// joins the 16-hex digests with a space — the exact string inserted into
|
|
109
|
+
// an FTS5 column. Empty + duplicate token-hashes drop on the way out.
|
|
110
|
+
// (Requires the vault salt, which run() primes before the sync tests.)
|
|
111
|
+
function testHashTokensBehavior() {
|
|
112
|
+
var out = b.mailStore.fts.hashTokens("t", "subject", ["hello", "world"]);
|
|
113
|
+
var parts = out.split(" ");
|
|
114
|
+
check("hashTokens: two tokens → two space-joined hashes", parts.length === 2);
|
|
115
|
+
check("hashTokens: each part is a 16-char hex hash",
|
|
116
|
+
/^[0-9a-f]{16}$/.test(parts[0]) && /^[0-9a-f]{16}$/.test(parts[1]));
|
|
117
|
+
// Each part equals the per-token hashToken under the same namespace.
|
|
118
|
+
check("hashTokens: parts match hashToken() per token in order",
|
|
119
|
+
parts[0] === b.mailStore.fts.hashToken("t", "subject", "hello") &&
|
|
120
|
+
parts[1] === b.mailStore.fts.hashToken("t", "subject", "world"));
|
|
121
|
+
|
|
122
|
+
// Duplicate tokens collapse to a single hash.
|
|
123
|
+
var dup = b.mailStore.fts.hashTokens("t", "subject", ["foo", "foo", "foo"]);
|
|
124
|
+
check("hashTokens: duplicate tokens collapse to one hash",
|
|
125
|
+
dup === b.mailStore.fts.hashToken("t", "subject", "foo"));
|
|
126
|
+
|
|
127
|
+
// Empty-string tokens contribute no hash and are dropped.
|
|
128
|
+
var withEmpty = b.mailStore.fts.hashTokens("t", "subject", ["hello", "", "world"]);
|
|
129
|
+
check("hashTokens: empty-string tokens drop (2 hashes, not 3)",
|
|
130
|
+
withEmpty.split(" ").length === 2);
|
|
131
|
+
|
|
132
|
+
// Order of first appearance is preserved.
|
|
133
|
+
var ordered = b.mailStore.fts.hashTokens("t", "subject", ["bravo", "alpha"]);
|
|
134
|
+
check("hashTokens: preserves first-seen token order",
|
|
135
|
+
ordered.split(" ")[0] === b.mailStore.fts.hashToken("t", "subject", "bravo"));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function testHashTokensNamespaceScoping() {
|
|
139
|
+
var base = b.mailStore.fts.hashTokens("t1", "subject", ["kubernetes"]);
|
|
140
|
+
var field = b.mailStore.fts.hashTokens("t1", "body", ["kubernetes"]);
|
|
141
|
+
var table = b.mailStore.fts.hashTokens("t2", "subject", ["kubernetes"]);
|
|
142
|
+
check("hashTokens: different field → different hash", base !== field);
|
|
143
|
+
check("hashTokens: different table → different hash", base !== table);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function testHashTokensEmptyAndNonArray() {
|
|
147
|
+
check("hashTokens: empty array → empty string",
|
|
148
|
+
b.mailStore.fts.hashTokens("t", "subject", []) === "");
|
|
149
|
+
check("hashTokens: non-array (string) → empty string",
|
|
150
|
+
b.mailStore.fts.hashTokens("t", "subject", "notanarray") === "");
|
|
151
|
+
check("hashTokens: null → empty string",
|
|
152
|
+
b.mailStore.fts.hashTokens("t", "subject", null) === "");
|
|
153
|
+
check("hashTokens: array of only empty strings → empty string",
|
|
154
|
+
b.mailStore.fts.hashTokens("t", "subject", ["", ""]) === "");
|
|
155
|
+
}
|
|
156
|
+
|
|
105
157
|
function testBuildMatchExpressionEmptyTerm() {
|
|
106
158
|
check("empty term → null", b.mailStore.fts.buildMatchExpression("t", "subject", "") === null);
|
|
107
159
|
check("stopword-only term → null", b.mailStore.fts.buildMatchExpression("t", "subject", "the a") === null);
|
|
@@ -464,6 +516,9 @@ async function run() {
|
|
|
464
516
|
testTokenizerNfcAndLength();
|
|
465
517
|
testHashTokenDeterministic();
|
|
466
518
|
testHashEmptyAndNonString();
|
|
519
|
+
testHashTokensBehavior();
|
|
520
|
+
testHashTokensNamespaceScoping();
|
|
521
|
+
testHashTokensEmptyAndNonArray();
|
|
467
522
|
testBuildMatchExpressionEmptyTerm();
|
|
468
523
|
await testStoreSearchHappyPath();
|
|
469
524
|
await testStoreSearchSinceModseqCursor();
|
|
@@ -389,7 +389,249 @@ async function testByteCapMultibyte() {
|
|
|
389
389
|
} finally { _teardown(fx); }
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
async function testBadTablePrefix() {
|
|
393
|
+
var fx = await _setupStore("badprefix");
|
|
394
|
+
try {
|
|
395
|
+
var threw = null;
|
|
396
|
+
try { b.mailStore.create({ backend: fx.db, tablePrefix: "bad-prefix!;DROP" }); }
|
|
397
|
+
catch (e) { threw = e; }
|
|
398
|
+
check("create: invalid tablePrefix refused",
|
|
399
|
+
threw && (threw.code || "").indexOf("mail-store/bad-table-prefix") !== -1);
|
|
400
|
+
} finally { _teardown(fx); }
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async function testBadHeaderIds() {
|
|
404
|
+
var fx = await _setupStore("badids");
|
|
405
|
+
try {
|
|
406
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
407
|
+
|
|
408
|
+
// Unbracketed Message-Id is refused under the strict default profile.
|
|
409
|
+
var t1 = null;
|
|
410
|
+
try { store.appendMessage("INBOX", _msg(["From: a@x", "Subject: s", "Message-Id: bareid@example.com"], "body")); }
|
|
411
|
+
catch (e) { t1 = e; }
|
|
412
|
+
check("append: bad Message-Id refused",
|
|
413
|
+
t1 && (t1.code || "").indexOf("mail-store/bad-message-id") !== -1);
|
|
414
|
+
|
|
415
|
+
// Valid Message-Id but unbracketed In-Reply-To.
|
|
416
|
+
var t2 = null;
|
|
417
|
+
try {
|
|
418
|
+
store.appendMessage("INBOX",
|
|
419
|
+
_msg(["From: a@x", "Subject: s", "Message-Id: <ok1@x>", "In-Reply-To: notbracketed@x"], "body"));
|
|
420
|
+
} catch (e) { t2 = e; }
|
|
421
|
+
check("append: bad In-Reply-To refused",
|
|
422
|
+
t2 && (t2.code || "").indexOf("mail-store/bad-in-reply-to") !== -1);
|
|
423
|
+
|
|
424
|
+
// Valid Message-Id but a References entry that fails the msg-id grammar.
|
|
425
|
+
var t3 = null;
|
|
426
|
+
try {
|
|
427
|
+
store.appendMessage("INBOX",
|
|
428
|
+
_msg(["From: a@x", "Subject: s", "Message-Id: <ok2@x>", "References: <good@x> notbracketed@x"], "body"));
|
|
429
|
+
} catch (e) { t3 = e; }
|
|
430
|
+
check("append: bad References entry refused",
|
|
431
|
+
t3 && (t3.code || "").indexOf("mail-store/bad-references") !== -1);
|
|
432
|
+
} finally { _teardown(fx); }
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
async function testOversizeMessageDirect() {
|
|
436
|
+
var fx = await _setupStore("oversize");
|
|
437
|
+
try {
|
|
438
|
+
var store = b.mailStore.create({ backend: fx.db, maxMessageBytes: 10 });
|
|
439
|
+
var threw = null;
|
|
440
|
+
try { store.appendMessage("INBOX", _msg(["From: a@x", "Subject: big", "Message-Id: <big@x>"], "way over ten bytes of body")); }
|
|
441
|
+
catch (e) { threw = e; }
|
|
442
|
+
check("append: message over maxMessageBytes refused",
|
|
443
|
+
threw && threw.code === "mail-store/oversize-message");
|
|
444
|
+
} finally { _teardown(fx); }
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
async function testMissingFolderEveryReader() {
|
|
448
|
+
var fx = await _setupStore("nofolder");
|
|
449
|
+
try {
|
|
450
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
451
|
+
function noFolder(label, fn) {
|
|
452
|
+
var threw = null;
|
|
453
|
+
try { fn(); } catch (e) { threw = e; }
|
|
454
|
+
check(label + ": missing folder refused",
|
|
455
|
+
threw && (threw.code || "").indexOf("mail-store/no-folder") !== -1);
|
|
456
|
+
}
|
|
457
|
+
noFolder("search", function () { store.search("Ghost", { text: "x" }); });
|
|
458
|
+
noFolder("queryByModseq", function () { store.queryByModseq("Ghost", {}); });
|
|
459
|
+
noFolder("quota", function () { store.quota("Ghost"); });
|
|
460
|
+
noFolder("fetchByObjectId", function () { store.fetchByObjectId("Ghost", "obj_x"); });
|
|
461
|
+
noFolder("hardExpunge", function () { store.hardExpunge("Ghost", ["obj_x"]); });
|
|
462
|
+
noFolder("moveMessages/from", function () { store.moveMessages("Ghost", "INBOX", []); });
|
|
463
|
+
noFolder("moveMessages/to", function () { store.moveMessages("INBOX", "Ghost", []); });
|
|
464
|
+
} finally { _teardown(fx); }
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
async function testMoveBadObjectids() {
|
|
468
|
+
var fx = await _setupStore("movebad");
|
|
469
|
+
try {
|
|
470
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
471
|
+
var threw = null;
|
|
472
|
+
try { store.moveMessages("INBOX", "Archive", "not-an-array"); }
|
|
473
|
+
catch (e) { threw = e; }
|
|
474
|
+
check("moveMessages: non-array objectids refused",
|
|
475
|
+
threw && (threw.code || "").indexOf("mail-store/bad-input") !== -1);
|
|
476
|
+
} finally { _teardown(fx); }
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
async function testCreateFolderBadName() {
|
|
480
|
+
var fx = await _setupStore("badfolder");
|
|
481
|
+
try {
|
|
482
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
483
|
+
var threw = null;
|
|
484
|
+
try { store.createFolder("Bad Name With Spaces"); }
|
|
485
|
+
catch (e) { threw = e; }
|
|
486
|
+
check("createFolder: name outside [A-Za-z0-9_.-]+ refused",
|
|
487
|
+
threw && (threw.code || "").indexOf("mail-store/bad-folder-name") !== -1);
|
|
488
|
+
} finally { _teardown(fx); }
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async function testQuotaAndThreadEmptyStates() {
|
|
492
|
+
var fx = await _setupStore("empty");
|
|
493
|
+
try {
|
|
494
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
495
|
+
// A freshly-created folder has no quota row yet — quota() returns
|
|
496
|
+
// zeroed defaults rather than throwing.
|
|
497
|
+
store.createFolder("EmptyBox");
|
|
498
|
+
var q = store.quota("EmptyBox");
|
|
499
|
+
check("quota: fresh folder returns zeroed defaults",
|
|
500
|
+
q.usedBytes === 0 && q.usedCount === 0 && q.capBytes === null && q.capCount === null);
|
|
501
|
+
|
|
502
|
+
// threadFor on an unknown objectid returns an empty array.
|
|
503
|
+
check("threadFor: unknown objectid → []",
|
|
504
|
+
Array.isArray(store.threadFor("obj_missing")) && store.threadFor("obj_missing").length === 0);
|
|
505
|
+
|
|
506
|
+
// fetchByObjectId on a present folder but missing id returns null.
|
|
507
|
+
check("fetchByObjectId: unknown id → null",
|
|
508
|
+
store.fetchByObjectId("INBOX", "obj_missing") === null);
|
|
509
|
+
} finally { _teardown(fx); }
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
async function testHardExpungeEdgeCases() {
|
|
513
|
+
var fx = await _setupStore("expungeedge");
|
|
514
|
+
try {
|
|
515
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
516
|
+
|
|
517
|
+
// Empty objectid set — no-op result shape.
|
|
518
|
+
var e0 = store.hardExpunge("INBOX", []);
|
|
519
|
+
check("hardExpunge: empty set → empty result",
|
|
520
|
+
e0.rows.length === 0 && e0.deleted.length === 0 && e0.refused.length === 0);
|
|
521
|
+
|
|
522
|
+
// Non-array objectids — same no-op result shape.
|
|
523
|
+
var eNull = store.hardExpunge("INBOX", null);
|
|
524
|
+
check("hardExpunge: non-array set → empty result",
|
|
525
|
+
eNull.rows.length === 0 && eNull.deleted.length === 0 && eNull.refused.length === 0);
|
|
526
|
+
|
|
527
|
+
// Unknown id — refused with not-in-folder, nothing deleted.
|
|
528
|
+
var eMiss = store.hardExpunge("INBOX", ["obj_notthere"]);
|
|
529
|
+
check("hardExpunge: unknown id refused not-in-folder",
|
|
530
|
+
eMiss.deleted.length === 0 && eMiss.refused.length === 1 &&
|
|
531
|
+
eMiss.refused[0].reason === "not-in-folder");
|
|
532
|
+
|
|
533
|
+
// Duplicate ids must be deduplicated so quota is not driven negative.
|
|
534
|
+
var meta = store.appendMessage("INBOX",
|
|
535
|
+
_msg(["From: a@x", "Subject: dup", "Message-Id: <dup@x>"], "dup body"));
|
|
536
|
+
var eDup = store.hardExpunge("INBOX", [meta.objectid, meta.objectid]);
|
|
537
|
+
check("hardExpunge: duplicate id collapses to one delete",
|
|
538
|
+
eDup.deleted.length === 1 && eDup.deleted[0] === meta.objectid);
|
|
539
|
+
var qAfter = store.quota("INBOX");
|
|
540
|
+
check("hardExpunge: dedup keeps quota non-negative",
|
|
541
|
+
qAfter.usedCount === 0 && qAfter.usedBytes === 0);
|
|
542
|
+
} finally { _teardown(fx); }
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
async function testSearchColumnFiltersAndPagination() {
|
|
546
|
+
var fx = await _setupStore("searchcols");
|
|
547
|
+
try {
|
|
548
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
549
|
+
var m1 = store.appendMessage("INBOX",
|
|
550
|
+
_msg(["From: alice@example.com", "To: dave@example.com",
|
|
551
|
+
"Subject: quarterly report", "Message-Id: <c1@x>"],
|
|
552
|
+
"the pipeline throughput doubled"));
|
|
553
|
+
store.appendMessage("INBOX",
|
|
554
|
+
_msg(["From: erin@example.com", "To: frank@example.com",
|
|
555
|
+
"Subject: lunch", "Message-Id: <c2@x>"],
|
|
556
|
+
"grab a sandwich"));
|
|
557
|
+
|
|
558
|
+
// body-column MATCH.
|
|
559
|
+
var rb = store.search("INBOX", { body: "throughput" });
|
|
560
|
+
check("search: body filter hits only m1",
|
|
561
|
+
rb.rows.length === 1 && rb.rows[0].objectid === m1.objectid);
|
|
562
|
+
|
|
563
|
+
// to-address MATCH (addr_toks shared by from/to).
|
|
564
|
+
var rt = store.search("INBOX", { to: "dave@example.com" });
|
|
565
|
+
check("search: to filter hits only m1",
|
|
566
|
+
rt.rows.length === 1 && rt.rows[0].objectid === m1.objectid);
|
|
567
|
+
|
|
568
|
+
// Stopword-only term → no surviving tokens → falls back to the modseq
|
|
569
|
+
// cursor (distinct from the empty-FTS-result branch) and carries a
|
|
570
|
+
// nextModseq.
|
|
571
|
+
var rs = store.search("INBOX", { subject: "the" });
|
|
572
|
+
check("search: stopword-only term falls back to modseq cursor",
|
|
573
|
+
rs.rows.length === 2 && typeof rs.nextModseq === "number" && rs.matchExpr === undefined);
|
|
574
|
+
|
|
575
|
+
// Garbage limit floors to the default page size; oversized limit caps
|
|
576
|
+
// at 1000 — neither throws through b.sql's integer-only limit().
|
|
577
|
+
var rGarbage = store.search("INBOX", { text: "sandwich", limit: "not-a-number" });
|
|
578
|
+
check("search: garbage limit tolerated", rGarbage.rows.length === 1);
|
|
579
|
+
var rHuge = store.search("INBOX", { body: "throughput", limit: 999999 });
|
|
580
|
+
check("search: oversized limit capped without throw", rHuge.rows.length === 1);
|
|
581
|
+
} finally { _teardown(fx); }
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
async function testSearchPaginationSinceModseq() {
|
|
585
|
+
var fx = await _setupStore("searchpage");
|
|
586
|
+
try {
|
|
587
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
588
|
+
for (var i = 0; i < 3; i += 1) {
|
|
589
|
+
store.appendMessage("INBOX",
|
|
590
|
+
_msg(["From: a@x", "Subject: report " + i, "Message-Id: <p" + i + "@x>"],
|
|
591
|
+
"shared keyword body content"));
|
|
592
|
+
}
|
|
593
|
+
// Page 1 — one row via the FTS MATCH path, nextModseq advances.
|
|
594
|
+
var page1 = store.search("INBOX", { body: "keyword", limit: 1 });
|
|
595
|
+
check("search: FTS page 1 returns one row",
|
|
596
|
+
page1.rows.length === 1 && typeof page1.nextModseq === "number");
|
|
597
|
+
// Page 2 — resume from nextModseq, the FTS window excludes page 1.
|
|
598
|
+
var page2 = store.search("INBOX", { body: "keyword", sinceModseq: page1.nextModseq, limit: 10 });
|
|
599
|
+
check("search: FTS pagination resumes past page 1",
|
|
600
|
+
page2.rows.length === 2 && page2.rows[0].modseq > page1.nextModseq);
|
|
601
|
+
} finally { _teardown(fx); }
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
async function testSearchFtsUnavailableFallback() {
|
|
605
|
+
var fx = await _setupStore("ftsunavail");
|
|
606
|
+
try {
|
|
607
|
+
var store = b.mailStore.create({ backend: fx.db });
|
|
608
|
+
store.appendMessage("INBOX",
|
|
609
|
+
_msg(["From: a@x", "Subject: indexed subject", "Message-Id: <u1@x>"], "indexed body"));
|
|
610
|
+
|
|
611
|
+
// Corrupt the on-disk FTS format marker so _ftsIndexUsable() reads
|
|
612
|
+
// the index as non-final. search() must fall back to the modseq
|
|
613
|
+
// cursor and flag ftsUnavailable rather than returning partial /
|
|
614
|
+
// wrong-scheme FTS hits.
|
|
615
|
+
fx.db.prepare("UPDATE " + store._tablePrefix + "_meta SET value = 'rebuilding' WHERE key = 'fts_format'").run();
|
|
616
|
+
|
|
617
|
+
var r = store.search("INBOX", { subject: "indexed" });
|
|
618
|
+
check("search: stale FTS marker falls back to modseq cursor",
|
|
619
|
+
r.ftsUnavailable === true && r.rows.length === 1 && typeof r.nextModseq === "number");
|
|
620
|
+
} finally { _teardown(fx); }
|
|
621
|
+
}
|
|
622
|
+
|
|
392
623
|
async function run() {
|
|
624
|
+
await testBadTablePrefix();
|
|
625
|
+
await testBadHeaderIds();
|
|
626
|
+
await testOversizeMessageDirect();
|
|
627
|
+
await testMissingFolderEveryReader();
|
|
628
|
+
await testMoveBadObjectids();
|
|
629
|
+
await testCreateFolderBadName();
|
|
630
|
+
await testQuotaAndThreadEmptyStates();
|
|
631
|
+
await testHardExpungeEdgeCases();
|
|
632
|
+
await testSearchColumnFiltersAndPagination();
|
|
633
|
+
await testSearchPaginationSinceModseq();
|
|
634
|
+
await testSearchFtsUnavailableFallback();
|
|
393
635
|
await testByteCapMultibyte();
|
|
394
636
|
testSurface();
|
|
395
637
|
await testBootstrap();
|