@blamejs/blamejs-shop 0.4.30 → 0.4.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/checkout.js +8 -0
- package/lib/order.js +71 -11
- package/lib/vendor/MANIFEST.json +392 -278
- package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
- package/lib/vendor/blamejs/.gitignore +6 -0
- package/lib/vendor/blamejs/CHANGELOG.md +26 -0
- package/lib/vendor/blamejs/MIGRATING.md +43 -0
- package/lib/vendor/blamejs/README.md +8 -6
- package/lib/vendor/blamejs/SECURITY.md +19 -3
- package/lib/vendor/blamejs/api-snapshot.json +2190 -664
- package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
- package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
- package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
- package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
- package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
- package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
- package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
- package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
- package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
- package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
- package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
- package/lib/vendor/blamejs/index.js +4 -0
- package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
- package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
- package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
- package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
- package/lib/vendor/blamejs/lib/api-key.js +158 -77
- package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
- package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
- package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
- package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
- package/lib/vendor/blamejs/lib/audit.js +259 -123
- package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
- package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
- package/lib/vendor/blamejs/lib/backup/index.js +45 -10
- package/lib/vendor/blamejs/lib/break-glass.js +355 -147
- package/lib/vendor/blamejs/lib/cache.js +174 -105
- package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
- package/lib/vendor/blamejs/lib/cli.js +19 -14
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
- package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
- package/lib/vendor/blamejs/lib/cluster.js +119 -71
- package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
- package/lib/vendor/blamejs/lib/compliance.js +206 -4
- package/lib/vendor/blamejs/lib/consent.js +82 -29
- package/lib/vendor/blamejs/lib/constants.js +27 -11
- package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
- package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
- package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
- package/lib/vendor/blamejs/lib/db-query.js +882 -260
- package/lib/vendor/blamejs/lib/db-schema.js +228 -44
- package/lib/vendor/blamejs/lib/db.js +249 -99
- package/lib/vendor/blamejs/lib/dsr.js +385 -55
- package/lib/vendor/blamejs/lib/error-page.js +14 -1
- package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
- package/lib/vendor/blamejs/lib/external-db.js +549 -34
- package/lib/vendor/blamejs/lib/file-upload.js +52 -7
- package/lib/vendor/blamejs/lib/framework-error.js +20 -1
- package/lib/vendor/blamejs/lib/framework-files.js +73 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
- package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
- package/lib/vendor/blamejs/lib/guard-all.js +1 -0
- package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
- package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
- package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
- package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
- package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
- package/lib/vendor/blamejs/lib/guard-email.js +47 -69
- package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
- package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
- package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
- package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
- package/lib/vendor/blamejs/lib/guard-html.js +53 -108
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
- package/lib/vendor/blamejs/lib/guard-image.js +46 -103
- package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
- package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
- package/lib/vendor/blamejs/lib/guard-json.js +38 -108
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
- package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
- package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
- package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
- package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
- package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
- package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
- package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
- package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
- package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
- package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
- package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
- package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
- package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
- package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
- package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
- package/lib/vendor/blamejs/lib/guard-template.js +35 -172
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-time.js +32 -154
- package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
- package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
- package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
- package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
- package/lib/vendor/blamejs/lib/http-client.js +37 -9
- package/lib/vendor/blamejs/lib/inbox.js +120 -107
- package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
- package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
- package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
- package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
- package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
- package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
- package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
- package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
- package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
- package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
- package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
- package/lib/vendor/blamejs/lib/mail-store.js +293 -154
- package/lib/vendor/blamejs/lib/mail.js +8 -4
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
- package/lib/vendor/blamejs/lib/migrations.js +108 -66
- package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
- package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
- package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
- package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
- package/lib/vendor/blamejs/lib/observability.js +124 -0
- package/lib/vendor/blamejs/lib/otel-export.js +12 -3
- package/lib/vendor/blamejs/lib/outbox.js +184 -83
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
- package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
- package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
- package/lib/vendor/blamejs/lib/queue-local.js +225 -140
- package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
- package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
- package/lib/vendor/blamejs/lib/queue.js +7 -0
- package/lib/vendor/blamejs/lib/redact.js +68 -11
- package/lib/vendor/blamejs/lib/redis-client.js +160 -31
- package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
- package/lib/vendor/blamejs/lib/retention.js +101 -40
- package/lib/vendor/blamejs/lib/router.js +212 -5
- package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
- package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
- package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
- package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
- package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
- package/lib/vendor/blamejs/lib/safe-url.js +170 -3
- package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
- package/lib/vendor/blamejs/lib/scheduler.js +35 -12
- package/lib/vendor/blamejs/lib/seeders.js +122 -74
- package/lib/vendor/blamejs/lib/session-stores.js +42 -14
- package/lib/vendor/blamejs/lib/session.js +175 -77
- package/lib/vendor/blamejs/lib/sql.js +3842 -0
- package/lib/vendor/blamejs/lib/sse.js +26 -0
- package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
- package/lib/vendor/blamejs/lib/static.js +177 -34
- package/lib/vendor/blamejs/lib/subject.js +96 -49
- package/lib/vendor/blamejs/lib/vault/index.js +3 -2
- package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
- package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
- package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
- package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
- package/lib/vendor/blamejs/lib/websocket.js +35 -5
- package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
- package/lib/vendor/blamejs/package.json +2 -2
- package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
- package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
- package/lib/vendor/blamejs/scripts/check-services.js +21 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
- package/lib/vendor/blamejs/scripts/release.js +398 -38
- package/lib/vendor/blamejs/test/00-primitives.js +117 -0
- package/lib/vendor/blamejs/test/10-state.js +140 -14
- package/lib/vendor/blamejs/test/20-db.js +65 -2
- package/lib/vendor/blamejs/test/helpers/db.js +9 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
- package/lib/vendor/blamejs/test/helpers/services.js +21 -0
- package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
- package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
- package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
- package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
- package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
- package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
- package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
- package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
- package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
- package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
- package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
- package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
- package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
- package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
- package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
- package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
- package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
- package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
- package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
- package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
- package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
- package/lib/vendor/blamejs/test/smoke.js +79 -21
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
- package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
- package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
- package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
- package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
- package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
- package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
- package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
- package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
- package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
- package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
- package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
- package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
- package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
- package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
- package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* (minio-tls:9443) so the framework's sigv4 signer + S3 client are
|
|
6
6
|
* exercised end-to-end against real AWS-compatible servers.
|
|
7
7
|
*
|
|
8
|
-
* No security bypass: the TLS leg
|
|
9
|
-
*
|
|
8
|
+
* No security bypass: the TLS leg trusts the test CA via the runner's
|
|
9
|
+
* NODE_EXTRA_CA_CERTS (scripts/test-integration.js), so the framework's
|
|
10
|
+
* own TLS verification stays fully on with no rejectUnauthorized override
|
|
11
|
+
* and no per-request CA threading.
|
|
10
12
|
*/
|
|
11
|
-
var fs = require("node:fs");
|
|
12
13
|
var helpers = require("../helpers");
|
|
13
14
|
var check = helpers.check;
|
|
14
15
|
var services = require("../helpers/services");
|
|
@@ -86,6 +87,29 @@ function _runOnEndpoint(label, endpoint, extraConfig) {
|
|
|
86
87
|
check("[" + label + "] list after delete: object gone",
|
|
87
88
|
!afterDelete.items.some(function (it) { return it.key === key; }));
|
|
88
89
|
|
|
90
|
+
// ---- special-character key round-trip (the v0.15.2 SigV4 single-encode
|
|
91
|
+
// fix). A key with a space / + / & / () previously double-encoded the
|
|
92
|
+
// canonical path → the signature was computed over a path the wire never
|
|
93
|
+
// carried → SignatureDoesNotMatch (403). Every prior test used ASCII keys,
|
|
94
|
+
// so the bug shipped green; this drives a real special-char key end-to-end.
|
|
95
|
+
// put() throws on a non-2xx, so reaching the asserts proves no 403. ----
|
|
96
|
+
// Includes a non-BMP code point (emoji) so the round-trip also proves the
|
|
97
|
+
// encoder iterates by code point — a UTF-16-unit split would throw URIError
|
|
98
|
+
// before signing.
|
|
99
|
+
var specialKey = "obj report (v2)+final & draft \u{1F600}-" + Math.floor(Math.random() * 1e6) + ".txt";
|
|
100
|
+
var specialPayload = Buffer.from("special-char-key payload", "utf8");
|
|
101
|
+
await backend.put(specialKey, specialPayload, { contentType: "text/plain" });
|
|
102
|
+
check("[" + label + "] special-char key put: signed + accepted (no 403)", true);
|
|
103
|
+
var specialGot = await backend.get(specialKey);
|
|
104
|
+
var specialBuf = Buffer.isBuffer(specialGot) ? specialGot : (specialGot && specialGot.body);
|
|
105
|
+
check("[" + label + "] special-char key get: bytes round-trip exactly",
|
|
106
|
+
Buffer.isBuffer(specialBuf) && Buffer.compare(specialBuf, specialPayload) === 0);
|
|
107
|
+
var specialListing = await backend.list("obj report");
|
|
108
|
+
check("[" + label + "] special-char key list: surfaces the object",
|
|
109
|
+
specialListing.items.some(function (it) { return it.key === specialKey; }));
|
|
110
|
+
await backend.delete(specialKey);
|
|
111
|
+
check("[" + label + "] special-char key delete: returned (no throw)", true);
|
|
112
|
+
|
|
89
113
|
// ---- multipart upload + round-trip (covers the v0.6.50 ?uploads
|
|
90
114
|
// wire-form fix; until now multipart had only mock-server coverage). ----
|
|
91
115
|
var bigBackendCfg = Object.assign({}, beCfg, {
|
|
@@ -359,20 +383,17 @@ async function run() {
|
|
|
359
383
|
var svcTls = await services.requireService("minioTls");
|
|
360
384
|
if (!svcTls.ok) throw new Error("minio-tls unreachable: " + svcTls.reason);
|
|
361
385
|
|
|
362
|
-
var caPath = await services.exportCaCert();
|
|
363
|
-
var caPem = fs.readFileSync(caPath, "utf8");
|
|
364
|
-
|
|
365
386
|
// ---- plain HTTP variant ----
|
|
366
387
|
await _runOnEndpoint("http", "http://127.0.0.1:9000", {
|
|
367
388
|
allowedProtocols: b.safeUrl.ALLOW_HTTP_ALL,
|
|
368
389
|
});
|
|
369
390
|
|
|
370
|
-
// ---- TLS variant —
|
|
391
|
+
// ---- TLS variant — full verification, no rejectUnauthorized override ----
|
|
392
|
+
// Trust for the test CA comes from the runner's NODE_EXTRA_CA_CERTS.
|
|
371
393
|
// Endpoint uses "localhost" so SNI works (cert SAN covers localhost +
|
|
372
|
-
// 127.0.0.1; node:tls forbids IP literals as servername).
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
});
|
|
394
|
+
// 127.0.0.1; node:tls forbids IP literals as servername). https is in
|
|
395
|
+
// the default allowedProtocols so no extra config is needed.
|
|
396
|
+
await _runOnEndpoint("tls", "https://localhost:9443", {});
|
|
376
397
|
|
|
377
398
|
// ---- Object Lock variant (HTTP only — no benefit from doing it twice
|
|
378
399
|
// and the WORM cleanup adds 2s of sleep which we don't want
|
|
@@ -383,14 +404,12 @@ async function run() {
|
|
|
383
404
|
});
|
|
384
405
|
|
|
385
406
|
// ---- Presigned response-header overrides (v0.8.53). HTTP first;
|
|
386
|
-
// TLS second to confirm signing math +
|
|
387
|
-
//
|
|
407
|
+
// TLS second to confirm the signing math + the live presigned GET
|
|
408
|
+
// stay valid over a fully-verified TLS handshake. ----
|
|
388
409
|
await _runPresignResponseHeadersOnEndpoint("http", "http://127.0.0.1:9000", {
|
|
389
410
|
allowedProtocols: b.safeUrl.ALLOW_HTTP_ALL,
|
|
390
411
|
});
|
|
391
|
-
await _runPresignResponseHeadersOnEndpoint("tls", "https://localhost:9443", {
|
|
392
|
-
ca: caPem,
|
|
393
|
-
});
|
|
412
|
+
await _runPresignResponseHeadersOnEndpoint("tls", "https://localhost:9443", {});
|
|
394
413
|
}
|
|
395
414
|
|
|
396
415
|
module.exports = { run: run };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* S3 Object Lock WORM enforcement — does COMPLIANCE-mode retention
|
|
4
|
+
* actually REFUSE a delete on real MinIO (which enforces Object Lock)?
|
|
5
|
+
*
|
|
6
|
+
* The existing object-store-sigv4 test only round-trips the retention /
|
|
7
|
+
* legal-hold CONFIG (set → get echoes the value back). It explicitly
|
|
8
|
+
* does NOT assert that a delete is blocked, with the rationale that
|
|
9
|
+
* Object-Lock buckets are versioned and an unversioned DELETE just
|
|
10
|
+
* writes a delete-marker. That leaves the headline WORM guarantee
|
|
11
|
+
* ("a record cannot be deleted before its retainUntil by anyone") never
|
|
12
|
+
* proven against a backend that enforces it.
|
|
13
|
+
*
|
|
14
|
+
* This test proves enforcement directly: it puts an object into an
|
|
15
|
+
* Object-Lock-enabled bucket, applies a COMPLIANCE retention with
|
|
16
|
+
* retainUntil in the future, then attempts to delete the PROTECTED
|
|
17
|
+
* VERSION and asserts MinIO refuses. A control object with no retention
|
|
18
|
+
* has its version deleted successfully, proving the refusal is the lock
|
|
19
|
+
* and not a blanket failure.
|
|
20
|
+
*
|
|
21
|
+
* Why the versioned delete matters — and what it exposes about the
|
|
22
|
+
* framework: WORM protects a specific object VERSION. An unversioned
|
|
23
|
+
* `DELETE /key` on a versioned bucket always succeeds (it writes a
|
|
24
|
+
* delete-marker; the protected version survives untouched). The
|
|
25
|
+
* framework's object-store delete (`backend.delete(key)` /
|
|
26
|
+
* `bucketOps.delete`) issues ONLY the unversioned form — there is no
|
|
27
|
+
* versionId surface anywhere in lib/object-store. So:
|
|
28
|
+
*
|
|
29
|
+
* (a) the framework's own delete() on a retained object SUCCEEDS and
|
|
30
|
+
* returns a clean result, masking the fact that the data version
|
|
31
|
+
* is still there — the framework delete path is not WORM-aware;
|
|
32
|
+
* (b) the operation WORM actually blocks (delete the protected version)
|
|
33
|
+
* can only be issued by hand-signing `DELETE /key?versionId=<v>`.
|
|
34
|
+
*
|
|
35
|
+
* This test hand-signs that versioned delete with the framework's OWN
|
|
36
|
+
* SigV4 signer (lib/object-store/sigv4.signRequest) so the proof is that
|
|
37
|
+
* MinIO enforces the lock under a request the framework signed correctly
|
|
38
|
+
* — no security bypass, real handshake, real signature.
|
|
39
|
+
*
|
|
40
|
+
* Observed MinIO behaviour (ground truth, captured live): the versioned
|
|
41
|
+
* delete of a COMPLIANCE-retained version is refused with HTTP 400
|
|
42
|
+
* InvalidRequest, body "Object is WORM protected and cannot be
|
|
43
|
+
* overwritten" — both with and without x-amz-bypass-governance-retention
|
|
44
|
+
* (COMPLIANCE cannot be bypassed by anyone). A no-retention version
|
|
45
|
+
* deletes with HTTP 204. AWS S3 uses 403 AccessDenied for the same
|
|
46
|
+
* refusal; the assertion accepts any 4xx refusal carrying the WORM
|
|
47
|
+
* signal so it holds on both backends.
|
|
48
|
+
*
|
|
49
|
+
* MinIO note: an Object-Lock bucket MUST be created with the
|
|
50
|
+
* x-amz-bucket-object-lock-enabled:true header at create time (object
|
|
51
|
+
* lock cannot be added later). bucketOps.create({ objectLockEnabled:true })
|
|
52
|
+
* sends that header. MinIO genuinely ENFORCES COMPLIANCE retention; it is
|
|
53
|
+
* the right backend for this proof. LocalStack's community S3 does not
|
|
54
|
+
* verify SigV4 and its Object-Lock enforcement is not authoritative — we
|
|
55
|
+
* target MinIO only.
|
|
56
|
+
*/
|
|
57
|
+
var helpers = require("../helpers");
|
|
58
|
+
var check = helpers.check;
|
|
59
|
+
var services = require("../helpers/services");
|
|
60
|
+
var b = require("../../");
|
|
61
|
+
var sigv4 = require("../../lib/object-store/sigv4");
|
|
62
|
+
|
|
63
|
+
var REGION = "us-east-1";
|
|
64
|
+
var ACCESS = "blamejs";
|
|
65
|
+
var SECRET = "blamejs_test_password";
|
|
66
|
+
|
|
67
|
+
// Hand-sign a raw S3 request with the framework's signer and send it via
|
|
68
|
+
// the framework's httpClient in always-resolve mode, so EVERY HTTP
|
|
69
|
+
// response — including a 4xx WORM refusal — comes back as
|
|
70
|
+
// { statusCode, headers, body } rather than a thrown error. Only a
|
|
71
|
+
// transport-level failure rejects. extraHeaders lets a caller add e.g.
|
|
72
|
+
// x-amz-bypass-governance-retention into the signed set.
|
|
73
|
+
function _rawSigned(method, urlStr, bodyBuf, extraHeaders) {
|
|
74
|
+
var payloadHash = sigv4.sha256Hex(bodyBuf || Buffer.alloc(0));
|
|
75
|
+
var extra = Object.assign({}, extraHeaders || {});
|
|
76
|
+
if (bodyBuf && bodyBuf.length > 0) {
|
|
77
|
+
extra["Content-Length"] = String(bodyBuf.length);
|
|
78
|
+
if (!extra["Content-Type"]) extra["Content-Type"] = "application/octet-stream";
|
|
79
|
+
}
|
|
80
|
+
var signed = sigv4.signRequest({
|
|
81
|
+
method: method,
|
|
82
|
+
url: urlStr,
|
|
83
|
+
headers: extra,
|
|
84
|
+
payloadHash: payloadHash,
|
|
85
|
+
region: REGION,
|
|
86
|
+
accessKeyId: ACCESS,
|
|
87
|
+
secretAccessKey: SECRET,
|
|
88
|
+
allowedProtocols: ["http:", "https:"],
|
|
89
|
+
});
|
|
90
|
+
return b.httpClient.request({
|
|
91
|
+
method: method,
|
|
92
|
+
url: urlStr,
|
|
93
|
+
headers: signed.headers,
|
|
94
|
+
body: bodyBuf && bodyBuf.length > 0 ? bodyBuf : null,
|
|
95
|
+
allowedProtocols: ["http:", "https:"],
|
|
96
|
+
allowInternal: true,
|
|
97
|
+
responseMode: "always-resolve",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function _objUrl(endpoint, bucket, key, versionId) {
|
|
102
|
+
var u = endpoint + "/" + bucket + "/" + encodeURIComponent(key);
|
|
103
|
+
if (versionId) u += "?versionId=" + encodeURIComponent(versionId);
|
|
104
|
+
return u;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function _bodyText(res) {
|
|
108
|
+
return res && res.body ? Buffer.from(res.body).toString("utf8") : "";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// A genuine WORM refusal: a 4xx whose body carries the lock signal.
|
|
112
|
+
// MinIO → 400 InvalidRequest "Object is WORM protected"; AWS S3 → 403
|
|
113
|
+
// AccessDenied. Accept either, but require the WORM/retention signal so a
|
|
114
|
+
// generic 400 (bad request shape) can't masquerade as enforcement.
|
|
115
|
+
function _isWormRefusal(res) {
|
|
116
|
+
if (!res || (res.statusCode !== 400 && res.statusCode !== 403)) return false;
|
|
117
|
+
var t = _bodyText(res);
|
|
118
|
+
return /WORM|retention|object lock|AccessDenied|cannot be overwritten|protected/i.test(t);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function _runWormOnEndpoint(label, endpoint, extraConfig) {
|
|
122
|
+
var bucket = "blamejs-worm-" + label + "-" + Date.now();
|
|
123
|
+
var opsCfg = Object.assign({
|
|
124
|
+
protocol: "sigv4",
|
|
125
|
+
endpoint: endpoint,
|
|
126
|
+
region: REGION,
|
|
127
|
+
accessKeyId: ACCESS,
|
|
128
|
+
secretAccessKey: SECRET,
|
|
129
|
+
allowInternal: true,
|
|
130
|
+
forcePathStyle: true,
|
|
131
|
+
}, extraConfig);
|
|
132
|
+
var ops = b.objectStore.bucketOps.create(opsCfg);
|
|
133
|
+
|
|
134
|
+
// ---- 1. Object-Lock-enabled bucket (header at create time) ----
|
|
135
|
+
await ops.create(bucket, { objectLockEnabled: true });
|
|
136
|
+
var lockCfg = await ops.getObjectLockConfiguration(bucket);
|
|
137
|
+
check("[" + label + "] bucket reports object-lock enabled", lockCfg.enabled === true);
|
|
138
|
+
|
|
139
|
+
var backend = b.objectStore.buildBackend(Object.assign({
|
|
140
|
+
name: "minio-worm-" + label,
|
|
141
|
+
protocol: "sigv4",
|
|
142
|
+
endpoint: endpoint,
|
|
143
|
+
region: REGION,
|
|
144
|
+
bucket: bucket,
|
|
145
|
+
accessKeyId: ACCESS,
|
|
146
|
+
secretAccessKey: SECRET,
|
|
147
|
+
allowInternal: true,
|
|
148
|
+
forcePathStyle: true,
|
|
149
|
+
classifications: ["operational"],
|
|
150
|
+
residencyTag: "unrestricted",
|
|
151
|
+
}, extraConfig));
|
|
152
|
+
|
|
153
|
+
// ============================================================
|
|
154
|
+
// PROTECTED OBJECT — COMPLIANCE retention in the future
|
|
155
|
+
// ============================================================
|
|
156
|
+
var key = "worm-doc-" + Math.floor(Math.random() * 1e6) + ".txt";
|
|
157
|
+
var payload = Buffer.from("immutable filing " + new Date().toISOString(), "utf8");
|
|
158
|
+
|
|
159
|
+
// Capture the versionId from a hand-signed PUT (backend.put discards
|
|
160
|
+
// x-amz-version-id; we need the version to target the protected delete).
|
|
161
|
+
var putRes = await _rawSigned("PUT", _objUrl(endpoint, bucket, key), payload);
|
|
162
|
+
check("[" + label + "] protected object PUT succeeds", putRes.statusCode === 200);
|
|
163
|
+
var versionId = putRes.headers && putRes.headers["x-amz-version-id"];
|
|
164
|
+
check("[" + label + "] PUT returned a versionId (bucket is versioned)",
|
|
165
|
+
typeof versionId === "string" && versionId.length > 0);
|
|
166
|
+
|
|
167
|
+
// Apply COMPLIANCE retention 1 hour into the future — long enough that
|
|
168
|
+
// it cannot lapse during the test. COMPLIANCE = nobody can delete the
|
|
169
|
+
// version before retainUntil, not even with bypassGovernance.
|
|
170
|
+
var retainUntil = new Date(Date.now() + b.constants.TIME.hours(1));
|
|
171
|
+
var setRet = await ops.setObjectRetention(bucket, key, {
|
|
172
|
+
mode: "COMPLIANCE",
|
|
173
|
+
retainUntil: retainUntil,
|
|
174
|
+
});
|
|
175
|
+
check("[" + label + "] setObjectRetention COMPLIANCE applied", setRet.applied === true);
|
|
176
|
+
|
|
177
|
+
var gotRet = await ops.getObjectRetention(bucket, key);
|
|
178
|
+
check("[" + label + "] retention reads back COMPLIANCE", gotRet.mode === "COMPLIANCE");
|
|
179
|
+
check("[" + label + "] retainUntil reads back in the future",
|
|
180
|
+
gotRet.retainUntil instanceof Date && gotRet.retainUntil.getTime() > Date.now());
|
|
181
|
+
|
|
182
|
+
// ---- 2. The framework's own delete() is NOT WORM-aware ----
|
|
183
|
+
// backend.delete(key) issues an unversioned DELETE → MinIO writes a
|
|
184
|
+
// delete-marker and returns success. The protected DATA version is
|
|
185
|
+
// untouched, but the framework caller is told the delete "worked".
|
|
186
|
+
// This documents that the framework delete path cannot enforce — and
|
|
187
|
+
// cannot even attempt — the WORM-blocked operation.
|
|
188
|
+
var fwDeleteResult = await backend.delete(key);
|
|
189
|
+
check("[" + label + "] framework backend.delete() returns success on a retained object " +
|
|
190
|
+
"(unversioned DELETE writes a delete-marker; data version survives)",
|
|
191
|
+
fwDeleteResult === true);
|
|
192
|
+
// Prove the data version actually survived the framework delete: a
|
|
193
|
+
// versioned GET of the protected version still returns the bytes.
|
|
194
|
+
var stillThere = await _rawSigned("GET", _objUrl(endpoint, bucket, key, versionId), null);
|
|
195
|
+
check("[" + label + "] protected DATA version still readable after framework delete() " +
|
|
196
|
+
"(framework delete only wrote a delete-marker)",
|
|
197
|
+
stillThere.statusCode === 200 &&
|
|
198
|
+
Buffer.compare(Buffer.from(stillThere.body || []), payload) === 0);
|
|
199
|
+
|
|
200
|
+
// ---- 3. THE WORM PROOF: deleting the protected VERSION is REFUSED ----
|
|
201
|
+
// This is the operation WORM exists to block. Hand-sign
|
|
202
|
+
// DELETE /key?versionId=<v> with the framework's signer. MinIO must
|
|
203
|
+
// refuse because the version is under COMPLIANCE retention.
|
|
204
|
+
var wormDel = await _rawSigned("DELETE", _objUrl(endpoint, bucket, key, versionId), null);
|
|
205
|
+
check("[" + label + "] WORM ENFORCED: delete of the COMPLIANCE-retained version is REFUSED " +
|
|
206
|
+
"(got " + wormDel.statusCode + " " + _bodyText(wormDel).replace(/\s+/g, " ").slice(0, 80) + ")",
|
|
207
|
+
_isWormRefusal(wormDel));
|
|
208
|
+
|
|
209
|
+
// ---- 3b. bypassGovernance does NOT defeat COMPLIANCE ----
|
|
210
|
+
// x-amz-bypass-governance-retention can shorten/delete GOVERNANCE
|
|
211
|
+
// retention with the right permission, but COMPLIANCE is immutable to
|
|
212
|
+
// everyone. Assert the version delete is STILL refused even with the
|
|
213
|
+
// bypass header signed in.
|
|
214
|
+
var wormDelBypass = await _rawSigned("DELETE", _objUrl(endpoint, bucket, key, versionId), null, {
|
|
215
|
+
"x-amz-bypass-governance-retention": "true",
|
|
216
|
+
});
|
|
217
|
+
check("[" + label + "] COMPLIANCE cannot be bypassed: versioned delete with " +
|
|
218
|
+
"x-amz-bypass-governance-retention is STILL refused (got " + wormDelBypass.statusCode + ")",
|
|
219
|
+
_isWormRefusal(wormDelBypass));
|
|
220
|
+
|
|
221
|
+
// And the version is verifiably still present after both refused deletes.
|
|
222
|
+
var afterRefuse = await _rawSigned("GET", _objUrl(endpoint, bucket, key, versionId), null);
|
|
223
|
+
check("[" + label + "] retained version still present after the refused deletes",
|
|
224
|
+
afterRefuse.statusCode === 200 &&
|
|
225
|
+
Buffer.compare(Buffer.from(afterRefuse.body || []), payload) === 0);
|
|
226
|
+
|
|
227
|
+
// ============================================================
|
|
228
|
+
// CONTROL — no retention: the version deletes fine
|
|
229
|
+
// ============================================================
|
|
230
|
+
var ctlKey = "control-" + Math.floor(Math.random() * 1e6) + ".txt";
|
|
231
|
+
var ctlPayload = Buffer.from("disposable", "utf8");
|
|
232
|
+
var ctlPut = await _rawSigned("PUT", _objUrl(endpoint, bucket, ctlKey), ctlPayload);
|
|
233
|
+
check("[" + label + "] control object PUT succeeds", ctlPut.statusCode === 200);
|
|
234
|
+
var ctlVersion = ctlPut.headers && ctlPut.headers["x-amz-version-id"];
|
|
235
|
+
check("[" + label + "] control PUT returned a versionId",
|
|
236
|
+
typeof ctlVersion === "string" && ctlVersion.length > 0);
|
|
237
|
+
|
|
238
|
+
var ctlDel = await _rawSigned("DELETE", _objUrl(endpoint, bucket, ctlKey, ctlVersion), null);
|
|
239
|
+
check("[" + label + "] CONTROL: no-retention version deletes fine (2xx) — the refusal above " +
|
|
240
|
+
"is the lock, not a blanket failure (got " + ctlDel.statusCode + ")",
|
|
241
|
+
ctlDel.statusCode === 204 || ctlDel.statusCode === 200);
|
|
242
|
+
var ctlGone = await _rawSigned("GET", _objUrl(endpoint, bucket, ctlKey, ctlVersion), null);
|
|
243
|
+
check("[" + label + "] control version is gone after delete (404)",
|
|
244
|
+
ctlGone.statusCode === 404);
|
|
245
|
+
|
|
246
|
+
// ---- Cleanup is impossible while COMPLIANCE retention holds: the
|
|
247
|
+
// protected version cannot be removed before retainUntil by anyone,
|
|
248
|
+
// and bucketOps.delete refuses a non-empty bucket. That is the WORM
|
|
249
|
+
// guarantee working as designed. Confirm the bucket delete refuses,
|
|
250
|
+
// then leave the bucket; the name carries Date.now() so re-runs don't
|
|
251
|
+
// collide and the MinIO container reset sweeps it. ----
|
|
252
|
+
var bucketDropped = true;
|
|
253
|
+
try {
|
|
254
|
+
await ops.delete(bucket);
|
|
255
|
+
} catch (_e) {
|
|
256
|
+
bucketDropped = false;
|
|
257
|
+
}
|
|
258
|
+
check("[" + label + "] bucket with a COMPLIANCE-retained version cannot be dropped " +
|
|
259
|
+
"(WORM holds the bytes)",
|
|
260
|
+
bucketDropped === false);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async function run() {
|
|
264
|
+
var svc = await services.requireService("minio");
|
|
265
|
+
var svcTls = await services.requireService("minioTls");
|
|
266
|
+
if (!svc.ok && !svcTls.ok) {
|
|
267
|
+
throw new Error("minio unreachable (need plain or TLS): " +
|
|
268
|
+
(svc.reason || "") + " / " + (svcTls.reason || ""));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// MinIO over the plain HTTP listener — it enforces Object Lock + verifies
|
|
272
|
+
// SigV4 (unlike LocalStack). We use the plain endpoint for the WORM proof
|
|
273
|
+
// since the enforcement, not the transport, is the subject; the runner's
|
|
274
|
+
// NODE_EXTRA_CA_CERTS covers the TLS leg if only that one is up.
|
|
275
|
+
if (svc.ok) {
|
|
276
|
+
await _runWormOnEndpoint("http", "http://127.0.0.1:9000", {
|
|
277
|
+
allowedProtocols: b.safeUrl.ALLOW_HTTP_ALL,
|
|
278
|
+
});
|
|
279
|
+
} else {
|
|
280
|
+
await _runWormOnEndpoint("tls", "https://localhost:9443", {});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
module.exports = { run: run };
|
|
285
|
+
|
|
286
|
+
if (require.main === module) {
|
|
287
|
+
run().then(
|
|
288
|
+
function () { console.log("OK — " + helpers.getChecks() + " checks passed"); process.exit(0); },
|
|
289
|
+
function (e) { console.error("FAIL:", e.stack || e); process.exit(1); }
|
|
290
|
+
);
|
|
291
|
+
}
|
|
@@ -112,6 +112,20 @@ async function run() {
|
|
|
112
112
|
check("cA has u:1", await cA.has("u:1"));
|
|
113
113
|
check("cB has u:1", await cB.has("u:1"));
|
|
114
114
|
|
|
115
|
+
// cache.create() issues cB's SUBSCRIBE on ips2 fire-and-forget; the
|
|
116
|
+
// remote SUBSCRIBE drains asynchronously. Redis PUB/SUB has no
|
|
117
|
+
// buffering for not-yet-subscribed channels — a single invalidateTag
|
|
118
|
+
// published before cB's subscription is active on the server is lost
|
|
119
|
+
// forever. Probe a no-subscriber channel on ips2's connection until
|
|
120
|
+
// Redis answers PUBLISH; that ack means ips2's queued SUBSCRIBE has
|
|
121
|
+
// drained and cB is registered for the invalidation channel. (Real
|
|
122
|
+
// deploys subscribe at boot, long before invalidations flow; this
|
|
123
|
+
// reproduces that steady state.)
|
|
124
|
+
await helpers.waitUntil(async function () {
|
|
125
|
+
var probe = await ips2.publish("cache:fanout:probe:" + Date.now(), {});
|
|
126
|
+
return probe && typeof probe.remote === "number";
|
|
127
|
+
}, { label: "cache fan-out: ips2 SUBSCRIBE drained (cB registered)" });
|
|
128
|
+
|
|
115
129
|
await cA.invalidateTag("t-user");
|
|
116
130
|
// The publish goes through redis; ips2 subscribes to the channel,
|
|
117
131
|
// forwards to cB. Poll until cB has observed the eviction.
|