@blamejs/blamejs-shop 0.4.56 → 0.4.58
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/affiliates.js +35 -4
- package/lib/api-keys.js +17 -2
- package/lib/asset-manifest.json +1 -1
- package/lib/backorder.js +21 -4
- package/lib/click-and-collect.js +11 -2
- package/lib/credit-limits.js +132 -84
- package/lib/vendor/MANIFEST.json +426 -366
- package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
- package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/CHANGELOG.md +2 -0
- package/lib/vendor/blamejs/api-snapshot.json +1381 -4
- package/lib/vendor/blamejs/eslint.config.mjs +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
- package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
- package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
- package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
- package/lib/vendor/blamejs/index.js +2 -0
- package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
- package/lib/vendor/blamejs/lib/acme.js +6 -5
- package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
- package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
- package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
- package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
- package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
- package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
- package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
- package/lib/vendor/blamejs/lib/ai-input.js +2 -2
- package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
- package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
- package/lib/vendor/blamejs/lib/api-key.js +37 -28
- package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
- package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
- package/lib/vendor/blamejs/lib/archive-read.js +5 -17
- package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
- package/lib/vendor/blamejs/lib/archive.js +2 -10
- package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
- package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
- package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
- package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
- package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
- package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
- package/lib/vendor/blamejs/lib/audit.js +84 -0
- package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
- package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
- package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
- package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
- package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
- package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
- package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
- package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
- package/lib/vendor/blamejs/lib/auth/password.js +7 -1
- package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
- package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
- package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
- package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
- package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
- package/lib/vendor/blamejs/lib/backup/index.js +14 -47
- package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
- package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
- package/lib/vendor/blamejs/lib/cache.js +7 -18
- package/lib/vendor/blamejs/lib/cbor.js +2 -1
- package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
- package/lib/vendor/blamejs/lib/cert.js +3 -10
- package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
- package/lib/vendor/blamejs/lib/cli.js +5 -1
- package/lib/vendor/blamejs/lib/client-hints.js +7 -9
- package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
- package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
- package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
- package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
- package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
- package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
- package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
- package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
- package/lib/vendor/blamejs/lib/compliance.js +2 -9
- package/lib/vendor/blamejs/lib/config-drift.js +2 -12
- package/lib/vendor/blamejs/lib/content-digest.js +10 -8
- package/lib/vendor/blamejs/lib/cookies.js +5 -11
- package/lib/vendor/blamejs/lib/cose.js +19 -11
- package/lib/vendor/blamejs/lib/cra-report.js +1 -11
- package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
- package/lib/vendor/blamejs/lib/crypto.js +120 -3
- package/lib/vendor/blamejs/lib/csp.js +235 -3
- package/lib/vendor/blamejs/lib/daemon.js +42 -41
- package/lib/vendor/blamejs/lib/data-act.js +19 -9
- package/lib/vendor/blamejs/lib/db-query.js +6 -40
- package/lib/vendor/blamejs/lib/db.js +34 -12
- package/lib/vendor/blamejs/lib/dbsc.js +5 -6
- package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
- package/lib/vendor/blamejs/lib/deprecate.js +4 -5
- package/lib/vendor/blamejs/lib/did.js +6 -2
- package/lib/vendor/blamejs/lib/dsr.js +8 -12
- package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
- package/lib/vendor/blamejs/lib/external-db.js +14 -26
- package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
- package/lib/vendor/blamejs/lib/fdx.js +22 -18
- package/lib/vendor/blamejs/lib/file-upload.js +80 -66
- package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
- package/lib/vendor/blamejs/lib/framework-error.js +12 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
- package/lib/vendor/blamejs/lib/fsm.js +7 -12
- package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
- package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
- package/lib/vendor/blamejs/lib/guard-all.js +1 -0
- package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
- package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
- package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
- package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
- package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
- package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
- package/lib/vendor/blamejs/lib/guard-email.js +46 -53
- package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
- package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
- package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
- package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
- package/lib/vendor/blamejs/lib/guard-html.js +65 -117
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
- package/lib/vendor/blamejs/lib/guard-image.js +280 -77
- package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
- package/lib/vendor/blamejs/lib/guard-json.js +87 -103
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
- package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
- package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
- package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
- package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
- package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
- package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
- package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
- package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
- package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
- package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
- package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
- package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
- package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
- package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
- package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
- package/lib/vendor/blamejs/lib/guard-template.js +23 -80
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
- package/lib/vendor/blamejs/lib/guard-text.js +592 -0
- package/lib/vendor/blamejs/lib/guard-time.js +27 -95
- package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
- package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
- package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
- package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
- package/lib/vendor/blamejs/lib/http-client.js +8 -21
- package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
- package/lib/vendor/blamejs/lib/i18n.js +83 -26
- package/lib/vendor/blamejs/lib/inbox.js +8 -8
- package/lib/vendor/blamejs/lib/incident-report.js +3 -21
- package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
- package/lib/vendor/blamejs/lib/jobs.js +3 -2
- package/lib/vendor/blamejs/lib/keychain.js +6 -18
- package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
- package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
- package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
- package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
- package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
- package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
- package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
- package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
- package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
- package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
- package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
- package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
- package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
- package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
- package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
- package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
- package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
- package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
- package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
- package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
- package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
- package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
- package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
- package/lib/vendor/blamejs/lib/mail-store.js +3 -2
- package/lib/vendor/blamejs/lib/mail.js +6 -11
- package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
- package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
- package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
- package/lib/vendor/blamejs/lib/mcp.js +1 -1
- package/lib/vendor/blamejs/lib/mdoc.js +11 -12
- package/lib/vendor/blamejs/lib/metrics.js +32 -30
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
- package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
- package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
- package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
- package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
- package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
- package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
- package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
- package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
- package/lib/vendor/blamejs/lib/migrations.js +4 -13
- package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
- package/lib/vendor/blamejs/lib/module-loader.js +44 -0
- package/lib/vendor/blamejs/lib/money.js +105 -0
- package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
- package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
- package/lib/vendor/blamejs/lib/network-dane.js +8 -6
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
- package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
- package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
- package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
- package/lib/vendor/blamejs/lib/network-tls.js +40 -42
- package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
- package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
- package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
- package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
- package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
- package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
- package/lib/vendor/blamejs/lib/observability.js +95 -0
- package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
- package/lib/vendor/blamejs/lib/otel-export.js +7 -10
- package/lib/vendor/blamejs/lib/outbox.js +43 -37
- package/lib/vendor/blamejs/lib/pagination.js +11 -15
- package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
- package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
- package/lib/vendor/blamejs/lib/pick.js +63 -5
- package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
- package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
- package/lib/vendor/blamejs/lib/problem-details.js +2 -5
- package/lib/vendor/blamejs/lib/pubsub.js +4 -8
- package/lib/vendor/blamejs/lib/redact.js +2 -1
- package/lib/vendor/blamejs/lib/render.js +4 -2
- package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
- package/lib/vendor/blamejs/lib/restore.js +5 -22
- package/lib/vendor/blamejs/lib/retention.js +3 -5
- package/lib/vendor/blamejs/lib/safe-async.js +457 -0
- package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
- package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
- package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
- package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
- package/lib/vendor/blamejs/lib/safe-json.js +7 -8
- package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
- package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
- package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
- package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
- package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
- package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
- package/lib/vendor/blamejs/lib/sandbox.js +3 -2
- package/lib/vendor/blamejs/lib/scheduler.js +5 -12
- package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
- package/lib/vendor/blamejs/lib/seeders.js +4 -11
- package/lib/vendor/blamejs/lib/self-update.js +92 -69
- package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
- package/lib/vendor/blamejs/lib/session.js +194 -6
- package/lib/vendor/blamejs/lib/sql.js +225 -78
- package/lib/vendor/blamejs/lib/sse.js +6 -10
- package/lib/vendor/blamejs/lib/static.js +136 -98
- package/lib/vendor/blamejs/lib/storage.js +4 -2
- package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
- package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
- package/lib/vendor/blamejs/lib/tsa.js +11 -15
- package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
- package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
- package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
- package/lib/vendor/blamejs/lib/vc.js +2 -7
- package/lib/vendor/blamejs/lib/vex.js +35 -13
- package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
- package/lib/vendor/blamejs/lib/webhook.js +43 -18
- package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
- package/lib/vendor/blamejs/lib/websocket.js +7 -3
- package/lib/vendor/blamejs/lib/worm.js +2 -3
- package/lib/vendor/blamejs/lib/ws-client.js +8 -10
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
- package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
- package/lib/vendor/blamejs/test/00-primitives.js +136 -7
- package/lib/vendor/blamejs/test/10-state.js +9 -3
- package/lib/vendor/blamejs/test/30-chain.js +40 -0
- package/lib/vendor/blamejs/test/helpers/check.js +18 -0
- package/lib/vendor/blamejs/test/helpers/db.js +4 -0
- package/lib/vendor/blamejs/test/helpers/index.js +1 -0
- package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
- package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
- package/package.json +1 -1
|
@@ -52,7 +52,12 @@
|
|
|
52
52
|
var nodeCrypto = require("node:crypto");
|
|
53
53
|
var validateOpts = require("./validate-opts");
|
|
54
54
|
var bCrypto = require("./crypto");
|
|
55
|
+
var pick = require("./pick");
|
|
55
56
|
var { defineClass } = require("./framework-error");
|
|
57
|
+
// The strict framework defaults the per-route merge derives from. One-
|
|
58
|
+
// directional edge: security-headers requires only request-helpers +
|
|
59
|
+
// validate-opts, never csp, so this is not a cycle (§9 top-of-file require).
|
|
60
|
+
var securityHeaderDefaults = require("./middleware/security-headers");
|
|
56
61
|
|
|
57
62
|
var CspError = defineClass("CspError", { alwaysPermanent: true });
|
|
58
63
|
|
|
@@ -78,6 +83,61 @@ var ALL_DIRECTIVES = [
|
|
|
78
83
|
var UNSAFE_KEYWORDS = ["'unsafe-inline'", "'unsafe-eval'", "'unsafe-hashes'"];
|
|
79
84
|
var CATCH_ALL_SOURCES = ["*", "https:"];
|
|
80
85
|
|
|
86
|
+
// _parseCspString — split a CSP header value into an ordered
|
|
87
|
+
// { directive: [sources] } map. Tolerant reader (defensive tier): a
|
|
88
|
+
// malformed base yields whatever directives DO parse. The merge never
|
|
89
|
+
// re-validates these base sources (they are the trusted default), so the
|
|
90
|
+
// parser only needs to be faithful, not strict. First write wins on a
|
|
91
|
+
// duplicate directive (matches UA "honor the first").
|
|
92
|
+
function _parseCspString(value) {
|
|
93
|
+
var out = {};
|
|
94
|
+
if (typeof value !== "string") return out;
|
|
95
|
+
var segments = value.split(";");
|
|
96
|
+
for (var i = 0; i < segments.length; i += 1) {
|
|
97
|
+
var tokens = segments[i].trim().split(/\s+/);
|
|
98
|
+
var name = tokens[0];
|
|
99
|
+
if (!name) continue;
|
|
100
|
+
if (Object.prototype.hasOwnProperty.call(out, name)) continue;
|
|
101
|
+
out[name] = tokens.slice(1);
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// _parsePermissionsPolicyString — split a Permissions-Policy header value
|
|
107
|
+
// into a { feature: "allowlist" } map plus the feature order, preserving
|
|
108
|
+
// each feature's RFC-9651 value-list verbatim ("()" / "*" / "(self ...)").
|
|
109
|
+
function _parsePermissionsPolicyString(value) {
|
|
110
|
+
var out = {};
|
|
111
|
+
var order = [];
|
|
112
|
+
if (typeof value !== "string") return { map: out, order: order };
|
|
113
|
+
// Split on the literal comma (linear) — the per-item .trim() below handles
|
|
114
|
+
// the surrounding whitespace, so the prior `/\s*,\s*/` was redundant and
|
|
115
|
+
// ran in O(n^2) on a comma-less run of whitespace (js/polynomial-redos).
|
|
116
|
+
var parts = value.split(",");
|
|
117
|
+
for (var i = 0; i < parts.length; i += 1) {
|
|
118
|
+
var p = parts[i].trim();
|
|
119
|
+
if (!p) continue;
|
|
120
|
+
var eq = p.indexOf("=");
|
|
121
|
+
if (eq === -1) continue;
|
|
122
|
+
var feature = p.slice(0, eq).trim();
|
|
123
|
+
var allow = p.slice(eq + 1).trim();
|
|
124
|
+
if (!feature) continue;
|
|
125
|
+
if (!Object.prototype.hasOwnProperty.call(out, feature)) order.push(feature);
|
|
126
|
+
out[feature] = allow;
|
|
127
|
+
}
|
|
128
|
+
return { map: out, order: order };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// RFC-9651 value-list shape for ONE Permissions-Policy feature value (no
|
|
132
|
+
// leading "feature=" — just the allowlist): "*", "()", "self", or a
|
|
133
|
+
// parenthesised origin list "(self \"https://x\")". A hostile value with a
|
|
134
|
+
// comma / CRLF can't pass (no comma inside, the parens are balanced-only).
|
|
135
|
+
var PP_VALUE_RE = /^(?:\*|self|\([^),\r\n]*\))$/;
|
|
136
|
+
// Permissions-Policy feature names are RFC-9651 structured-field tokens —
|
|
137
|
+
// ASCII lowercase, hyphenated. Reject anything else so a hostile key can't
|
|
138
|
+
// inject a comma / CRLF into the header.
|
|
139
|
+
var PP_FEATURE_RE = /^[a-z][a-z0-9-]*$/; // allow:duplicate-regex — generic ASCII lowercase-hyphen token shape; shared shape, distinct domain (Permissions-Policy feature name)
|
|
140
|
+
|
|
81
141
|
/**
|
|
82
142
|
* @primitive b.csp.build
|
|
83
143
|
* @signature b.csp.build(directives, opts?)
|
|
@@ -184,9 +244,15 @@ function build(directives, opts) {
|
|
|
184
244
|
directives["trusted-types"] = opts.trustedTypesPolicies;
|
|
185
245
|
}
|
|
186
246
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
247
|
+
return _emitCanonical(directives);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Emit a directive map as a CSP header string in canonical (ALL_DIRECTIVES)
|
|
251
|
+
// order so operators diffing two policies see structural diffs rather than
|
|
252
|
+
// ordering noise. Pure serializer — it does NOT validate sources (build()
|
|
253
|
+
// and mergeDirectives() validate before calling it), so a trusted base
|
|
254
|
+
// policy round-trips through it untouched.
|
|
255
|
+
function _emitCanonical(directives) {
|
|
190
256
|
var out = [];
|
|
191
257
|
for (var di = 0; di < ALL_DIRECTIVES.length; di += 1) {
|
|
192
258
|
var d = ALL_DIRECTIVES[di];
|
|
@@ -264,8 +330,174 @@ function hash(scriptBody, alg) {
|
|
|
264
330
|
return "'" + algName + "-" + digest + "'";
|
|
265
331
|
}
|
|
266
332
|
|
|
333
|
+
/**
|
|
334
|
+
* @primitive b.csp.mergeDirectives
|
|
335
|
+
* @signature b.csp.mergeDirectives(base, additions, opts?)
|
|
336
|
+
* @since 0.15.13
|
|
337
|
+
* @status stable
|
|
338
|
+
* @related b.csp.build, b.csp.mergePermissionsPolicy
|
|
339
|
+
*
|
|
340
|
+
* Derive a per-route CSP from a strict base by ADDING hosts to named
|
|
341
|
+
* directives, leaving every other directive exactly as the base. The fix for
|
|
342
|
+
* the "load a third-party SDK on one route" case: take the framework's strict
|
|
343
|
+
* default (pass `base` omitted / `undefined`) and add `https://js.stripe.com`
|
|
344
|
+
* to `script-src` + `frame-src` for the checkout route only, without
|
|
345
|
+
* re-typing the whole policy or relaxing `frame-ancestors` / `object-src` /
|
|
346
|
+
* `base-uri`.
|
|
347
|
+
*
|
|
348
|
+
* Additive only: each `additions[directive]` array is APPENDED (de-duped) to
|
|
349
|
+
* that directive's existing sources; a directive absent from the base is
|
|
350
|
+
* seeded from `default-src` (or `'self'`) first so it never lands wide-open.
|
|
351
|
+
* Only the ADDED sources are validated (CR/LF/NUL, catch-all `*`/`https:`,
|
|
352
|
+
* `data:` in img/media/font, unsafe-* in script directives) — the trusted
|
|
353
|
+
* base round-trips untouched. Returns a policy string for the middleware
|
|
354
|
+
* `csp:` opt. Throws `CspError` on an unknown directive, a hostile directive
|
|
355
|
+
* name, or a rejected added source.
|
|
356
|
+
*
|
|
357
|
+
* @opts
|
|
358
|
+
* acknowledgeUnsafe: boolean, // allow an added 'unsafe-*' in a script directive
|
|
359
|
+
* allowDataImages: boolean, // allow an added data: in img-src/media-src/font-src
|
|
360
|
+
*
|
|
361
|
+
* @example
|
|
362
|
+
* // Admit Stripe on the checkout route's script + frame directives only.
|
|
363
|
+
* var routeCsp = b.csp.mergeDirectives(undefined, {
|
|
364
|
+
* "script-src": ["https://js.stripe.com"],
|
|
365
|
+
* "frame-src": ["https://js.stripe.com"],
|
|
366
|
+
* });
|
|
367
|
+
* // -> the strict default with those two hosts appended; everything else unchanged
|
|
368
|
+
*/
|
|
369
|
+
function mergeDirectives(base, additions, opts) {
|
|
370
|
+
var baseString = base === undefined ? securityHeaderDefaults.DEFAULT_CSP : base;
|
|
371
|
+
if (typeof baseString !== "string" || baseString.length === 0) {
|
|
372
|
+
throw new CspError("csp/bad-base",
|
|
373
|
+
"csp.mergeDirectives: base must be a non-empty CSP string (or undefined to " +
|
|
374
|
+
"derive from the framework DEFAULT_CSP)");
|
|
375
|
+
}
|
|
376
|
+
if (!additions || typeof additions !== "object" || Array.isArray(additions)) {
|
|
377
|
+
throw new CspError("csp/bad-additions",
|
|
378
|
+
"csp.mergeDirectives: additions must be an object keyed by CSP directive name, " +
|
|
379
|
+
"each value a non-empty array of source strings to ADD");
|
|
380
|
+
}
|
|
381
|
+
opts = opts || {};
|
|
382
|
+
validateOpts(opts, ["acknowledgeUnsafe", "allowDataImages"], "csp.mergeDirectives");
|
|
383
|
+
|
|
384
|
+
var addKeys = Object.keys(additions);
|
|
385
|
+
// Validate directive names (proto-safe) + that each addition is a
|
|
386
|
+
// non-empty array, before touching the base.
|
|
387
|
+
for (var ki = 0; ki < addKeys.length; ki += 1) {
|
|
388
|
+
var nm = addKeys[ki];
|
|
389
|
+
if (pick.isPoisonedKey(nm)) {
|
|
390
|
+
throw new CspError("csp/bad-directive-name",
|
|
391
|
+
"csp.mergeDirectives: '" + nm + "' is not a valid directive name");
|
|
392
|
+
}
|
|
393
|
+
if (ALL_DIRECTIVES.indexOf(nm) === -1) {
|
|
394
|
+
throw new CspError("csp/unknown-directive",
|
|
395
|
+
"csp.mergeDirectives: '" + nm + "' is not a recognized CSP3 directive");
|
|
396
|
+
}
|
|
397
|
+
if (!Array.isArray(additions[nm]) || additions[nm].length === 0) {
|
|
398
|
+
throw new CspError("csp/bad-directive-value",
|
|
399
|
+
"csp.mergeDirectives: additions['" + nm + "'] must be a non-empty array of sources");
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
// Validate ONLY the added sources by routing a throwaway additions-only
|
|
403
|
+
// map through build() (reuses every per-source rule). build() may seed
|
|
404
|
+
// Trusted-Types into the copy; we discard its output and keep the original
|
|
405
|
+
// additions for the merge.
|
|
406
|
+
var validationMap = {};
|
|
407
|
+
for (var vk = 0; vk < addKeys.length; vk += 1) validationMap[addKeys[vk]] = additions[addKeys[vk]].slice();
|
|
408
|
+
build(validationMap, { acknowledgeUnsafe: opts.acknowledgeUnsafe === true,
|
|
409
|
+
allowDataImages: opts.allowDataImages === true,
|
|
410
|
+
requireTrustedTypes: false });
|
|
411
|
+
|
|
412
|
+
var directives = _parseCspString(baseString);
|
|
413
|
+
for (var ai = 0; ai < addKeys.length; ai += 1) {
|
|
414
|
+
var name = addKeys[ai];
|
|
415
|
+
var existing = Object.prototype.hasOwnProperty.call(directives, name)
|
|
416
|
+
? directives[name].slice()
|
|
417
|
+
: (directives["default-src"] ? directives["default-src"].slice() : ["'self'"]);
|
|
418
|
+
var added = additions[name];
|
|
419
|
+
for (var si = 0; si < added.length; si += 1) {
|
|
420
|
+
if (existing.indexOf(added[si]) === -1) existing.push(added[si]);
|
|
421
|
+
}
|
|
422
|
+
directives[name] = existing;
|
|
423
|
+
}
|
|
424
|
+
return _emitCanonical(directives);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* @primitive b.csp.mergePermissionsPolicy
|
|
429
|
+
* @signature b.csp.mergePermissionsPolicy(base, overrides, opts?)
|
|
430
|
+
* @since 0.15.13
|
|
431
|
+
* @status stable
|
|
432
|
+
* @related b.csp.mergeDirectives, b.csp.build
|
|
433
|
+
*
|
|
434
|
+
* Derive a per-route Permissions-Policy from a strict base by replacing the
|
|
435
|
+
* allowlist of NAMED features only, leaving every other feature at its `()`
|
|
436
|
+
* deny default. The companion to `mergeDirectives` for the Permissions-Policy
|
|
437
|
+
* header: re-enable `payment` to `(self "https://js.stripe.com")` on the
|
|
438
|
+
* checkout route while `camera` / `microphone` / `geolocation` stay denied.
|
|
439
|
+
*
|
|
440
|
+
* Each override value is validated as an RFC-9651 feature value-list (`*`,
|
|
441
|
+
* `()`, `self`, or a parenthesised origin list) — a value carrying a comma or
|
|
442
|
+
* CR/LF is refused so it can't inject a second feature or a header break. A
|
|
443
|
+
* feature not present in the base is added (opting it in); one present is
|
|
444
|
+
* replaced. Returns a header string for the middleware `permissionsPolicy:`
|
|
445
|
+
* opt. Throws `CspError` on a hostile feature name or a malformed value.
|
|
446
|
+
*
|
|
447
|
+
* @opts
|
|
448
|
+
* (none)
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* var routePp = b.csp.mergePermissionsPolicy(undefined, {
|
|
452
|
+
* payment: '(self "https://js.stripe.com")',
|
|
453
|
+
* });
|
|
454
|
+
* // -> the strict default with payment re-enabled to that allowlist; all else denied
|
|
455
|
+
*/
|
|
456
|
+
function mergePermissionsPolicy(base, overrides, opts) {
|
|
457
|
+
var baseString = base === undefined
|
|
458
|
+
? securityHeaderDefaults.DEFAULT_PERMISSIONS.join(", ")
|
|
459
|
+
: base;
|
|
460
|
+
if (typeof baseString !== "string" || baseString.length === 0) {
|
|
461
|
+
throw new CspError("csp/bad-base",
|
|
462
|
+
"csp.mergePermissionsPolicy: base must be a non-empty Permissions-Policy string " +
|
|
463
|
+
"(or undefined to derive from the framework default)");
|
|
464
|
+
}
|
|
465
|
+
if (!overrides || typeof overrides !== "object" || Array.isArray(overrides)) {
|
|
466
|
+
throw new CspError("csp/bad-overrides",
|
|
467
|
+
"csp.mergePermissionsPolicy: overrides must be an object keyed by feature name, " +
|
|
468
|
+
"each value an RFC-9651 allowlist string");
|
|
469
|
+
}
|
|
470
|
+
if (opts !== undefined) validateOpts(opts || {}, [], "csp.mergePermissionsPolicy");
|
|
471
|
+
|
|
472
|
+
var parsed = _parsePermissionsPolicyString(baseString);
|
|
473
|
+
var map = parsed.map;
|
|
474
|
+
var order = parsed.order;
|
|
475
|
+
var keys = Object.keys(overrides);
|
|
476
|
+
for (var ki = 0; ki < keys.length; ki += 1) {
|
|
477
|
+
var feature = keys[ki];
|
|
478
|
+
if (pick.isPoisonedKey(feature) ||
|
|
479
|
+
!PP_FEATURE_RE.test(feature)) { // allow:regex-no-length-cap — anchored token shape (no backtracking); a feature name is a short RFC-9651 token
|
|
480
|
+
throw new CspError("csp/bad-feature-name",
|
|
481
|
+
"csp.mergePermissionsPolicy: '" + feature + "' is not a valid feature name");
|
|
482
|
+
}
|
|
483
|
+
var value = overrides[feature];
|
|
484
|
+
if (typeof value !== "string" || !PP_VALUE_RE.test(value)) { // allow:regex-no-length-cap — anchored alternation (no backtracking); a feature value is a short RFC-9651 value-list
|
|
485
|
+
throw new CspError("csp/bad-feature-value",
|
|
486
|
+
"csp.mergePermissionsPolicy: " + feature + " value must be one of *, (), self, or a " +
|
|
487
|
+
"parenthesised origin list (got " + JSON.stringify(value) + ")");
|
|
488
|
+
}
|
|
489
|
+
if (!Object.prototype.hasOwnProperty.call(map, feature)) order.push(feature);
|
|
490
|
+
map[feature] = value;
|
|
491
|
+
}
|
|
492
|
+
var out = [];
|
|
493
|
+
for (var oi = 0; oi < order.length; oi += 1) out.push(order[oi] + "=" + map[order[oi]]);
|
|
494
|
+
return out.join(", ");
|
|
495
|
+
}
|
|
496
|
+
|
|
267
497
|
module.exports = {
|
|
268
498
|
build: build,
|
|
499
|
+
mergeDirectives: mergeDirectives,
|
|
500
|
+
mergePermissionsPolicy: mergePermissionsPolicy,
|
|
269
501
|
nonce: nonce,
|
|
270
502
|
hash: hash,
|
|
271
503
|
CspError: CspError,
|
|
@@ -42,7 +42,6 @@ var nodePath = require("node:path");
|
|
|
42
42
|
var numericBounds = require("./numeric-bounds");
|
|
43
43
|
var appShutdown = require("./app-shutdown");
|
|
44
44
|
var processSpawn = require("./process-spawn");
|
|
45
|
-
var lazyRequire = require("./lazy-require");
|
|
46
45
|
var safeAsync = require("./safe-async");
|
|
47
46
|
var atomicFile = require("./atomic-file");
|
|
48
47
|
var validateOpts = require("./validate-opts");
|
|
@@ -50,7 +49,7 @@ var C = require("./constants");
|
|
|
50
49
|
var { boot } = require("./log");
|
|
51
50
|
var { defineClass } = require("./framework-error");
|
|
52
51
|
|
|
53
|
-
var
|
|
52
|
+
var auditEmit = require("./audit-emit");
|
|
54
53
|
|
|
55
54
|
var DaemonError = defineClass("DaemonError", { alwaysPermanent: true });
|
|
56
55
|
var log = boot("daemon");
|
|
@@ -63,13 +62,7 @@ var DEFAULT_POLL_MS = 100;
|
|
|
63
62
|
var DEFAULT_LOG_FILE_MODE = 0o600;
|
|
64
63
|
|
|
65
64
|
function _safeAuditEmit(action, outcome, metadata) {
|
|
66
|
-
|
|
67
|
-
audit().safeEmit({
|
|
68
|
-
action: action,
|
|
69
|
-
outcome: outcome || "success",
|
|
70
|
-
metadata: metadata || {},
|
|
71
|
-
});
|
|
72
|
-
} catch (_e) { /* drop-silent — by design */ }
|
|
65
|
+
auditEmit.emit(action, metadata, outcome);
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
function _isLivePid(pid) {
|
|
@@ -87,41 +80,49 @@ function _readPidFile(pidFile) {
|
|
|
87
80
|
}
|
|
88
81
|
|
|
89
82
|
function _validateStartOpts(opts) {
|
|
90
|
-
validateOpts.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
83
|
+
validateOpts.shape(opts, {
|
|
84
|
+
pidFile: { rule: "required-string", code: "daemon/bad-pid-file",
|
|
85
|
+
label: "daemon.start: opts.pidFile (absolute path recommended)" },
|
|
86
|
+
logFile: { rule: "optional-string", code: "daemon/bad-log-file",
|
|
87
|
+
label: "daemon.start: opts.logFile" },
|
|
88
|
+
signals: function (value) {
|
|
89
|
+
validateOpts.optionalNonEmptyStringArray(value,
|
|
90
|
+
"daemon.start: opts.signals", DaemonError, "daemon/bad-signals");
|
|
91
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
92
|
+
throw new DaemonError("daemon/bad-signals",
|
|
93
|
+
"daemon.start: opts.signals must be a non-empty array of POSIX signal names");
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
command: { rule: "optional-string", code: "daemon/bad-command",
|
|
97
|
+
label: "daemon.start: opts.command (path to executable)" },
|
|
98
|
+
args: function (value) {
|
|
99
|
+
if (value !== undefined && !Array.isArray(value)) {
|
|
100
|
+
throw new DaemonError("daemon/bad-args",
|
|
101
|
+
"daemon.start: opts.args must be an array of strings when present");
|
|
102
|
+
}
|
|
103
|
+
if (opts.command === undefined && value !== undefined) {
|
|
104
|
+
throw new DaemonError("daemon/bad-args",
|
|
105
|
+
"daemon.start: opts.args requires opts.command");
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
}, "daemon.start", DaemonError, "daemon/bad-opts");
|
|
113
109
|
}
|
|
114
110
|
|
|
115
111
|
function _validateStopOpts(opts) {
|
|
116
|
-
validateOpts.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
validateOpts.shape(opts, {
|
|
113
|
+
pidFile: { rule: "required-string", code: "daemon/bad-pid-file",
|
|
114
|
+
label: "daemon.stop: opts.pidFile" },
|
|
115
|
+
signal: { rule: "optional-string", code: "daemon/bad-signal",
|
|
116
|
+
label: "daemon.stop: opts.signal" },
|
|
117
|
+
timeoutMs: function (value) {
|
|
118
|
+
numericBounds.requirePositiveFiniteIntIfPresent(value,
|
|
119
|
+
"daemon.stop: opts.timeoutMs", DaemonError, "daemon/bad-timeout");
|
|
120
|
+
},
|
|
121
|
+
pollMs: function (value) {
|
|
122
|
+
numericBounds.requirePositiveFiniteIntIfPresent(value,
|
|
123
|
+
"daemon.stop: opts.pollMs", DaemonError, "daemon/bad-poll");
|
|
124
|
+
},
|
|
125
|
+
}, "daemon.stop", DaemonError, "daemon/bad-opts");
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
function _maybeReapStale(pidFile) {
|
|
@@ -116,9 +116,12 @@ var DESIGNATED_GATEKEEPERS = Object.freeze([
|
|
|
116
116
|
* });
|
|
117
117
|
*/
|
|
118
118
|
function declareProduct(opts) {
|
|
119
|
-
validateOpts.
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
validateOpts.shape(opts, {
|
|
120
|
+
productId: { rule: "required-string", label: "productId", code: "dataact/no-product-id" },
|
|
121
|
+
dataHolder: { rule: "required-string", label: "dataHolder", code: "dataact/no-data-holder" },
|
|
122
|
+
productKind: "optional-string",
|
|
123
|
+
dataScope: "optional-string",
|
|
124
|
+
}, "dataAct.declareProduct", DataActError, "dataact/bad-opts");
|
|
122
125
|
var kind = opts.productKind || "connected-product";
|
|
123
126
|
if (kind !== "connected-product" && kind !== "related-service") {
|
|
124
127
|
throw new DataActError("dataact/bad-kind",
|
|
@@ -218,9 +221,13 @@ function recordUserAccess(opts) {
|
|
|
218
221
|
function shareWithThirdParty(opts) {
|
|
219
222
|
validateOpts.requireObject(opts, "dataAct.shareWithThirdParty", DataActError, "dataact/bad-opts");
|
|
220
223
|
_requireProduct(opts.productId, "shareWithThirdParty");
|
|
221
|
-
validateOpts.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
+
validateOpts.shape(opts, {
|
|
225
|
+
productId: { rule: "required-string", label: "productId", code: "dataact/no-product-id" },
|
|
226
|
+
userId: { rule: "required-string", label: "userId", code: "dataact/no-user-id" },
|
|
227
|
+
recipient: { rule: "required-string", label: "recipient", code: "dataact/no-recipient" },
|
|
228
|
+
scope: { rule: "required-string", label: "scope", code: "dataact/no-scope" },
|
|
229
|
+
acceptGatekeeper: "optional-plain-object",
|
|
230
|
+
}, "dataAct.shareWithThirdParty", DataActError, "dataact/bad-opts");
|
|
224
231
|
|
|
225
232
|
var recipientLower = opts.recipient.toLowerCase();
|
|
226
233
|
var isGatekeeper = DESIGNATED_GATEKEEPERS.some(function (g) {
|
|
@@ -291,9 +298,12 @@ function shareWithThirdParty(opts) {
|
|
|
291
298
|
* });
|
|
292
299
|
*/
|
|
293
300
|
function recordSwitchRequest(opts) {
|
|
294
|
-
validateOpts.
|
|
295
|
-
|
|
296
|
-
|
|
301
|
+
validateOpts.shape(opts, {
|
|
302
|
+
customerId: { rule: "required-string", label: "customerId", code: "dataact/no-customer-id" },
|
|
303
|
+
targetProvider: { rule: "required-string", label: "targetProvider", code: "dataact/no-target" },
|
|
304
|
+
dataSlices: "optional-string-array",
|
|
305
|
+
noticePeriodDays: "optional-non-negative",
|
|
306
|
+
}, "dataAct.recordSwitchRequest", DataActError, "dataact/bad-opts");
|
|
297
307
|
if (!Array.isArray(opts.dataSlices) || opts.dataSlices.length === 0) {
|
|
298
308
|
throw new DataActError("dataact/no-data-slices",
|
|
299
309
|
"recordSwitchRequest: dataSlices must be a non-empty array");
|
|
@@ -51,6 +51,7 @@ var sql = require("./sql");
|
|
|
51
51
|
var audit = require("./audit");
|
|
52
52
|
var lazyRequire = require("./lazy-require");
|
|
53
53
|
var { DbQueryError } = require("./framework-error");
|
|
54
|
+
var numericBounds = require("./numeric-bounds");
|
|
54
55
|
|
|
55
56
|
// Circular load — db.js requires db-query at module scope, so the
|
|
56
57
|
// residency gate reaches back for getDataResidency() lazily.
|
|
@@ -682,11 +683,8 @@ class Query {
|
|
|
682
683
|
var dbModule = require("./db"); // allow:inline-require — circular-load defense (db imports db-query)
|
|
683
684
|
perCallLimit = dbModule.getStreamLimit();
|
|
684
685
|
if (opts && opts.streamLimit !== undefined) {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
throw new Error("Query.stream: opts.streamLimit must be a positive finite integer; got " +
|
|
688
|
-
JSON.stringify(opts.streamLimit));
|
|
689
|
-
}
|
|
686
|
+
numericBounds.requirePositiveFiniteIntIfPresent(opts.streamLimit,
|
|
687
|
+
"Query.stream: opts.streamLimit", DbQueryError, "db-query/bad-stream-limit");
|
|
690
688
|
perCallLimit = opts.streamLimit;
|
|
691
689
|
}
|
|
692
690
|
var stmt = this._db.prepare(built.sql);
|
|
@@ -1299,41 +1297,9 @@ class WhereBuilder {
|
|
|
1299
1297
|
// Single linear pass, no backtracking regex; shares the scan shape with
|
|
1300
1298
|
// b.safeSql.countPlaceholders.
|
|
1301
1299
|
function _assertRawNoStringLiteral(rawSql, where) {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
var ch = rawSql.charAt(i);
|
|
1306
|
-
var next = i + 1 < len ? rawSql.charAt(i + 1) : "";
|
|
1307
|
-
if (ch === '"') {
|
|
1308
|
-
i += 1;
|
|
1309
|
-
while (i < len) {
|
|
1310
|
-
if (rawSql.charAt(i) === '"') {
|
|
1311
|
-
if (rawSql.charAt(i + 1) === '"') { i += 2; continue; }
|
|
1312
|
-
i += 1; break;
|
|
1313
|
-
}
|
|
1314
|
-
i += 1;
|
|
1315
|
-
}
|
|
1316
|
-
continue;
|
|
1317
|
-
}
|
|
1318
|
-
if (ch === "-" && next === "-") {
|
|
1319
|
-
while (i < len && rawSql.charAt(i) !== "\n") i += 1;
|
|
1320
|
-
continue;
|
|
1321
|
-
}
|
|
1322
|
-
if (ch === "/" && next === "*") {
|
|
1323
|
-
i += 2;
|
|
1324
|
-
while (i < len && !(rawSql.charAt(i) === "*" && rawSql.charAt(i + 1) === "/")) i += 1;
|
|
1325
|
-
i += 2;
|
|
1326
|
-
continue;
|
|
1327
|
-
}
|
|
1328
|
-
if (ch === "'") {
|
|
1329
|
-
throw new safeSql.SafeSqlError(
|
|
1330
|
-
where + ": raw SQL must not contain a string literal ('...') — bind every " +
|
|
1331
|
-
"value with a ? placeholder, or pass { allowLiterals: true } when the literal " +
|
|
1332
|
-
"is static and operator-controlled.",
|
|
1333
|
-
"sql/raw-literal");
|
|
1334
|
-
}
|
|
1335
|
-
i += 1;
|
|
1336
|
-
}
|
|
1300
|
+
// Routes through the shared safeSql scanner; the default error reproduces
|
|
1301
|
+
// this module's exact SafeSqlError("sql/raw-literal") message.
|
|
1302
|
+
safeSql.assertNoRawStringLiteral(rawSql, where);
|
|
1337
1303
|
}
|
|
1338
1304
|
|
|
1339
1305
|
// Apply one recorded WhereBuilder part onto a b.sql Predicate. `or`
|
|
@@ -161,6 +161,14 @@ var statfsProbe = null; // free-space reader (fs.statfsSync; injectable f
|
|
|
161
161
|
var _exitHandlerRegistered = false;
|
|
162
162
|
var dataDir = null;
|
|
163
163
|
var initialized = false;
|
|
164
|
+
// Monotonic identity of the live `database` handle. Bumped on every (re)open,
|
|
165
|
+
// close, and reset so a deferred operation that captured the generation while
|
|
166
|
+
// one database was live can detect — before it writes — that the handle has
|
|
167
|
+
// since changed (closed / replaced). Anchors the fix for a fire-and-forget
|
|
168
|
+
// audit.checkpoint() launched by close() whose deferred insert would otherwise
|
|
169
|
+
// land in whatever database is live when its continuation resumes.
|
|
170
|
+
var _dbGenerationCounter = 0;
|
|
171
|
+
function dbGeneration() { return _dbGenerationCounter; }
|
|
164
172
|
var dataResidency = null; // operator's declared region config (validated by storage backends)
|
|
165
173
|
var subjectTables = []; // [{ name, subjectField, personalDataCategories }] — for subject.export/erase
|
|
166
174
|
var tableMetadata = {}; // table name → metadata snapshot (PK/FK/sealed/derived) for getTableMetadata
|
|
@@ -193,6 +201,7 @@ var RESERVED_TABLE_NAMES = new Set([
|
|
|
193
201
|
"_blamejs_subject_restrictions", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
194
202
|
"_blamejs_subject_erasures", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
195
203
|
"_blamejs_sessions", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
204
|
+
"_blamejs_session_valid_from", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
196
205
|
"_blamejs_jobs", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
197
206
|
"_blamejs_migrations", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
198
207
|
"_blamejs_counters", // allow:hand-rolled-sql — canonical reserved local table-name declaration
|
|
@@ -480,6 +489,23 @@ var FRAMEWORK_SCHEMA = [
|
|
|
480
489
|
sealedFields: ["userId", "data"],
|
|
481
490
|
derivedHashes: { userIdHash: { from: "userId" } },
|
|
482
491
|
},
|
|
492
|
+
{
|
|
493
|
+
// _blamejs_session_valid_from — per-subject valid-from boundary for
|
|
494
|
+
// stateless-token revocation (b.session.bump / check / validFrom). Same
|
|
495
|
+
// dual-storage pattern as _blamejs_sessions: mirrors the cluster-mode DDL
|
|
496
|
+
// in framework-schema.js so cluster-storage routes to either backend.
|
|
497
|
+
// subjectHash is the PRIMARY KEY — the plaintext subject id never lands
|
|
498
|
+
// here. No sealed columns: the hash is non-reversible and the epoch is not
|
|
499
|
+
// personal data.
|
|
500
|
+
name: "_blamejs_session_valid_from", // allow:hand-rolled-sql — canonical local-schema table-name declaration
|
|
501
|
+
columns: {
|
|
502
|
+
subjectHash: "TEXT PRIMARY KEY",
|
|
503
|
+
validFromEpoch: "INTEGER NOT NULL",
|
|
504
|
+
updatedAt: "INTEGER NOT NULL",
|
|
505
|
+
},
|
|
506
|
+
indexes: [],
|
|
507
|
+
sealedFields: [],
|
|
508
|
+
},
|
|
483
509
|
{
|
|
484
510
|
// _blamejs_api_keys — operator-facing API-key registry. Sealed
|
|
485
511
|
// columns: ownerId / scopes / metadata. The secret never lands
|
|
@@ -1043,12 +1069,8 @@ async function init(opts) {
|
|
|
1043
1069
|
// on bad shape so a typo surfaces at boot rather than as an
|
|
1044
1070
|
// unbounded stream at first export.
|
|
1045
1071
|
if (opts.streamLimit !== undefined) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
throw new DbError("db/bad-init",
|
|
1049
|
-
"db.init: streamLimit must be a positive finite integer; got " +
|
|
1050
|
-
JSON.stringify(opts.streamLimit));
|
|
1051
|
-
}
|
|
1072
|
+
require("./numeric-bounds").requirePositiveFiniteIntIfPresent(opts.streamLimit,
|
|
1073
|
+
"db.init: streamLimit", DbError, "db/bad-init");
|
|
1052
1074
|
streamLimit = opts.streamLimit;
|
|
1053
1075
|
}
|
|
1054
1076
|
// Column-membership gate mode — throw at config-time on a typo so it
|
|
@@ -1171,6 +1193,7 @@ async function init(opts) {
|
|
|
1171
1193
|
sqlLength: C.BYTES.mib(1),
|
|
1172
1194
|
},
|
|
1173
1195
|
});
|
|
1196
|
+
_dbGenerationCounter++; // a new live handle — see dbGeneration()
|
|
1174
1197
|
|
|
1175
1198
|
// Performance pragmas
|
|
1176
1199
|
runSql(database, "PRAGMA journal_mode=WAL");
|
|
@@ -1813,12 +1836,8 @@ function stream(sql) {
|
|
|
1813
1836
|
// typo surfaces instead of an unbounded stream.
|
|
1814
1837
|
var perCallLimit = streamLimit;
|
|
1815
1838
|
if (opts && opts.streamLimit !== undefined) {
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
throw new DbError("db/bad-stream-limit",
|
|
1819
|
-
"db.stream: opts.streamLimit must be a positive finite integer; got " +
|
|
1820
|
-
JSON.stringify(opts.streamLimit));
|
|
1821
|
-
}
|
|
1839
|
+
require("./numeric-bounds").requirePositiveFiniteIntIfPresent(opts.streamLimit,
|
|
1840
|
+
"db.stream: opts.streamLimit", DbError, "db/bad-stream-limit");
|
|
1822
1841
|
perCallLimit = opts.streamLimit;
|
|
1823
1842
|
}
|
|
1824
1843
|
|
|
@@ -2355,6 +2374,7 @@ function close() {
|
|
|
2355
2374
|
// boot (integrity-probed, falling back to db.enc if it is itself corrupt).
|
|
2356
2375
|
if (atRest === "encrypted" && encryptOk) removePlaintextFiles();
|
|
2357
2376
|
database = null;
|
|
2377
|
+
_dbGenerationCounter++; // handle gone — invalidate any deferred op that captured the prior generation
|
|
2358
2378
|
initialized = false;
|
|
2359
2379
|
}
|
|
2360
2380
|
|
|
@@ -2879,6 +2899,7 @@ function _resetForTest() {
|
|
|
2879
2899
|
try { if (database) database.close(); }
|
|
2880
2900
|
catch (e) { log.debug("test-reset close failed", { error: e.message }); }
|
|
2881
2901
|
database = null;
|
|
2902
|
+
_dbGenerationCounter++; // handle gone — see dbGeneration()
|
|
2882
2903
|
dbPath = null;
|
|
2883
2904
|
encPath = null;
|
|
2884
2905
|
encKey = null;
|
|
@@ -3308,6 +3329,7 @@ function getActivePosture() { return _activePosture; }
|
|
|
3308
3329
|
|
|
3309
3330
|
module.exports = {
|
|
3310
3331
|
init: init,
|
|
3332
|
+
_dbGeneration: dbGeneration,
|
|
3311
3333
|
applyPosture: applyPosture,
|
|
3312
3334
|
getActivePosture: getActivePosture,
|
|
3313
3335
|
vacuumAfterErase: vacuumAfterErase,
|
|
@@ -198,12 +198,11 @@ function verifyBindingAssertion(assertion, opts) {
|
|
|
198
198
|
// import boundary (alg-confusion defense — JWT_KEY_CONFUSION-class
|
|
199
199
|
// attacks pass an HS256 jwk for an ES256-claimed token).
|
|
200
200
|
jwtExternal._assertAlgKtyMatch(headerJson.alg, headerJson.jwk);
|
|
201
|
-
var pubKey
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
201
|
+
var pubKey = bCrypto.importPublicJwk(headerJson.jwk, {
|
|
202
|
+
errorClass: DbscError,
|
|
203
|
+
code: "dbsc/bad-jwk",
|
|
204
|
+
messagePrefix: "verifyBindingAssertion: jwk could not be imported: ",
|
|
205
|
+
});
|
|
207
206
|
var signingInput = parts[0] + "." + parts[1];
|
|
208
207
|
var sigBytes = Buffer.from(parts[2], "base64url");
|
|
209
208
|
var ok;
|