@blamejs/blamejs-shop 0.4.56 → 0.4.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +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
|
@@ -57,7 +57,9 @@ var nodeCrypto = require("node:crypto");
|
|
|
57
57
|
var zlib = require("node:zlib");
|
|
58
58
|
var asn1 = require("./asn1-der");
|
|
59
59
|
var lazyRequire = require("./lazy-require");
|
|
60
|
+
var networkDnsResolver = lazyRequire(function () { return require("./network-dns-resolver"); });
|
|
60
61
|
var validateOpts = require("./validate-opts");
|
|
62
|
+
var structuredFields = require("./structured-fields");
|
|
61
63
|
var bCrypto = require("./crypto");
|
|
62
64
|
var safeUrl = require("./safe-url");
|
|
63
65
|
var safeJson = require("./safe-json");
|
|
@@ -91,14 +93,12 @@ function _parseStsPolicy(text) {
|
|
|
91
93
|
"MTA-STS policy text is empty");
|
|
92
94
|
}
|
|
93
95
|
var policy = { version: null, mode: null, mx: [], max_age: null };
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
var
|
|
99
|
-
|
|
100
|
-
var key = line.slice(0, colonAt).trim().toLowerCase();
|
|
101
|
-
var val = line.slice(colonAt + 1).trim();
|
|
96
|
+
// RFC 8461 §3.2 — newline-separated `key: value` lines, no quoted-string;
|
|
97
|
+
// mx may repeat, so iterate pairs (a last-wins map would drop hosts).
|
|
98
|
+
var pairs = structuredFields.parseTagList(text, { sep: /\r?\n/, kvSep: ":" });
|
|
99
|
+
for (var i = 0; i < pairs.length; i += 1) {
|
|
100
|
+
var key = pairs[i][0];
|
|
101
|
+
var val = pairs[i][1];
|
|
102
102
|
if (key === "version") policy.version = val;
|
|
103
103
|
else if (key === "mode") policy.mode = val.toLowerCase();
|
|
104
104
|
else if (key === "mx") policy.mx.push(val.toLowerCase());
|
|
@@ -123,17 +123,13 @@ function _parseStsPolicy(text) {
|
|
|
123
123
|
// cached policy forever (defeating operator rotation), and would also
|
|
124
124
|
// fetch policies from domains that don't publish one.
|
|
125
125
|
async function _fetchStsTxt(domain, dnsLookup) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
throw new SmtpPolicyError("smtp/mta-sts-txt-lookup-failed",
|
|
134
|
-
"_mta-sts." + domain + " TXT lookup failed: " +
|
|
135
|
-
((e && e.message) || String(e)));
|
|
136
|
-
}
|
|
126
|
+
// Secure DNS path — a spoofed _mta-sts TXT could downgrade mail TLS, so this
|
|
127
|
+
// must not use plaintext dnsPromises.
|
|
128
|
+
var records = await networkDnsResolver().safeResolveTxt("_mta-sts." + domain, {
|
|
129
|
+
dnsLookup: dnsLookup,
|
|
130
|
+
errorFactory: function (code, msg) { return new SmtpPolicyError(code, msg); },
|
|
131
|
+
code: "smtp/mta-sts-txt-lookup-failed",
|
|
132
|
+
});
|
|
137
133
|
if (!Array.isArray(records)) return null;
|
|
138
134
|
for (var i = 0; i < records.length; i += 1) {
|
|
139
135
|
var rec = Array.isArray(records[i]) ? records[i].join("") : records[i];
|
|
@@ -577,19 +573,14 @@ async function tlsRptFetchPolicy(domain, opts) {
|
|
|
577
573
|
}
|
|
578
574
|
opts = opts || {};
|
|
579
575
|
var qname = "_smtp._tls." + domain;
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
if (e && (e.code === "ENOTFOUND" || e.code === "ENODATA")) return null;
|
|
589
|
-
throw new SmtpPolicyError("smtp/tls-rpt-lookup-failed",
|
|
590
|
-
"TLS-RPT TXT lookup for " + qname + " failed: " +
|
|
591
|
-
((e && e.message) || String(e)));
|
|
592
|
-
}
|
|
576
|
+
// Secure DNS path — not plaintext dnsPromises (a spoofed TLS-RPT TXT could
|
|
577
|
+
// redirect failure reports).
|
|
578
|
+
var records = await networkDnsResolver().safeResolveTxt(qname, {
|
|
579
|
+
dnsLookup: opts.dnsLookup,
|
|
580
|
+
errorFactory: function (code, msg) { return new SmtpPolicyError(code, msg); },
|
|
581
|
+
code: "smtp/tls-rpt-lookup-failed",
|
|
582
|
+
});
|
|
583
|
+
if (records === null) return null;
|
|
593
584
|
// Pick the first record that begins with v=TLSRPTv1 per RFC 8460 §3.
|
|
594
585
|
var joined = "";
|
|
595
586
|
for (var i = 0; i < (records || []).length; i += 1) {
|
|
@@ -598,16 +589,13 @@ async function tlsRptFetchPolicy(domain, opts) {
|
|
|
598
589
|
if (/^v=TLSRPTv1\b/i.test(s)) { joined = s; break; }
|
|
599
590
|
}
|
|
600
591
|
if (joined.length === 0) return null;
|
|
601
|
-
|
|
592
|
+
// TLS-RPT record grammar (RFC 8460 §3): `"v=TLSRPTv1;" *(WSP) tlsrpt-rua`
|
|
593
|
+
// with token-only values, no quoted-string — the naive split is correct.
|
|
594
|
+
var pairs = structuredFields.parseTagList(joined);
|
|
602
595
|
var rua = [];
|
|
603
|
-
for (var p = 0; p <
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
if (eq === -1) continue;
|
|
607
|
-
var k = t.slice(0, eq).trim().toLowerCase();
|
|
608
|
-
var v = t.slice(eq + 1).trim();
|
|
609
|
-
if (k === "rua") {
|
|
610
|
-
var uris = v.split(","); // allow:bare-split-on-quoted-header — allow:raw-time-literal — TLS-RPT rua grammar (RFC 8460 §3): rua = tlsrpt-uri *("," tlsrpt-uri); URIs percent-encode reserved chars, no quoted-string
|
|
596
|
+
for (var p = 0; p < pairs.length; p += 1) {
|
|
597
|
+
if (pairs[p][0] === "rua") {
|
|
598
|
+
var uris = pairs[p][1].split(","); // allow:bare-split-on-quoted-header — allow:raw-time-literal — TLS-RPT rua grammar (RFC 8460 §3): rua = tlsrpt-uri *("," tlsrpt-uri); URIs percent-encode reserved chars, no quoted-string
|
|
611
599
|
for (var u = 0; u < uris.length; u += 1) {
|
|
612
600
|
var uri = uris[u].trim();
|
|
613
601
|
if (uri.length > 0) rua.push(uri);
|
|
@@ -5,6 +5,8 @@ var nodeFs = require("node:fs");
|
|
|
5
5
|
var nodePath = require("node:path");
|
|
6
6
|
var net = require("node:net");
|
|
7
7
|
var nodeCrypto = require("node:crypto");
|
|
8
|
+
var numericBounds = require("./numeric-bounds");
|
|
9
|
+
var atomicFile = require("./atomic-file");
|
|
8
10
|
|
|
9
11
|
var bCrypto = require("./crypto");
|
|
10
12
|
var C = require("./constants");
|
|
@@ -103,7 +105,7 @@ function _certMetadata(pem) {
|
|
|
103
105
|
|
|
104
106
|
function _isPathLike(s) {
|
|
105
107
|
if (s.indexOf("-----BEGIN") !== -1) return false;
|
|
106
|
-
if (s
|
|
108
|
+
if (safeBuffer.byteLengthOf(s) > C.BYTES.kib(1)) return false;
|
|
107
109
|
if (safeBuffer.hasCrlf(s)) return false;
|
|
108
110
|
return true;
|
|
109
111
|
}
|
|
@@ -115,20 +117,13 @@ function _isPathLike(s) {
|
|
|
115
117
|
// shape, where an attacker who could swap the file in-between could
|
|
116
118
|
// short-circuit the PEM marker check downstream.
|
|
117
119
|
function _readPathFile(p) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (n === 0) break;
|
|
126
|
-
read += n;
|
|
127
|
-
}
|
|
128
|
-
return buf.slice(0, read).toString("utf8");
|
|
129
|
-
} finally {
|
|
130
|
-
try { nodeFs.closeSync(fd); } catch (_c) { /* close best-effort */ }
|
|
131
|
-
}
|
|
120
|
+
// TOCTOU-safe read via atomic-file: utf8 string, slice on a short read,
|
|
121
|
+
// raw ENOENT preserved (errorFor returns undefined → rethrow).
|
|
122
|
+
return atomicFile.fdSafeReadSync(p, {
|
|
123
|
+
encoding: "utf8",
|
|
124
|
+
allowShortRead: true,
|
|
125
|
+
errorFor: function () { return undefined; },
|
|
126
|
+
});
|
|
132
127
|
}
|
|
133
128
|
|
|
134
129
|
function _readPath(p) {
|
|
@@ -198,6 +193,21 @@ function getTrustStore() {
|
|
|
198
193
|
});
|
|
199
194
|
}
|
|
200
195
|
|
|
196
|
+
// _certAuditMetadata(m) — the shared cert-identity fields stamped on every
|
|
197
|
+
// network.tls.ca.* audit event (the add / remove emitters overlay their
|
|
198
|
+
// own label / reason on top via Object.assign). Distinct from
|
|
199
|
+
// _certMetadata(pem), which PARSES a PEM into the meta object `m`.
|
|
200
|
+
function _certAuditMetadata(m) {
|
|
201
|
+
return {
|
|
202
|
+
subject: m.subject,
|
|
203
|
+
issuer: m.issuer,
|
|
204
|
+
fingerprint256: m.fingerprint256,
|
|
205
|
+
validFrom: m.validFrom,
|
|
206
|
+
validTo: m.validTo,
|
|
207
|
+
isSelfSigned: m.isSelfSigned,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
201
211
|
function _emitAuditRemove(metaList, reason) {
|
|
202
212
|
var sink;
|
|
203
213
|
try { sink = audit(); } catch (_e) { sink = null; }
|
|
@@ -208,16 +218,10 @@ function _emitAuditRemove(metaList, reason) {
|
|
|
208
218
|
sink.safeEmit({
|
|
209
219
|
action: "network.tls.ca.removed",
|
|
210
220
|
outcome: "success",
|
|
211
|
-
metadata: {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
validFrom: m.validFrom,
|
|
216
|
-
validTo: m.validTo,
|
|
217
|
-
isSelfSigned: m.isSelfSigned,
|
|
218
|
-
label: m.label,
|
|
219
|
-
reason: reason || "operator",
|
|
220
|
-
},
|
|
221
|
+
metadata: Object.assign(_certAuditMetadata(m), {
|
|
222
|
+
label: m.label,
|
|
223
|
+
reason: reason || "operator",
|
|
224
|
+
}),
|
|
221
225
|
});
|
|
222
226
|
} catch (_e) { /* audit best-effort — never break the caller */ }
|
|
223
227
|
}
|
|
@@ -515,7 +519,7 @@ var DEFAULT_PQC_KEY_SHARES = Object.freeze([
|
|
|
515
519
|
]);
|
|
516
520
|
|
|
517
521
|
function _validateKeyShare(name) {
|
|
518
|
-
if (typeof name !== "string" || name.length === 0 || name
|
|
522
|
+
if (typeof name !== "string" || name.length === 0 || safeBuffer.byteLengthOf(name) > C.BYTES.bytes(64)) { // bound
|
|
519
523
|
throw new TlsTrustError("tls/bad-key-share",
|
|
520
524
|
"tls.pqc.setKeyShares: each entry must be a non-empty string up to 64 chars");
|
|
521
525
|
}
|
|
@@ -714,15 +718,7 @@ function _emitAuditAdd(metaList, opts) {
|
|
|
714
718
|
sink.safeEmit({
|
|
715
719
|
action: "network.tls.ca.added",
|
|
716
720
|
outcome: "success",
|
|
717
|
-
metadata: {
|
|
718
|
-
subject: m.subject,
|
|
719
|
-
issuer: m.issuer,
|
|
720
|
-
fingerprint256: m.fingerprint256,
|
|
721
|
-
validFrom: m.validFrom,
|
|
722
|
-
validTo: m.validTo,
|
|
723
|
-
isSelfSigned: m.isSelfSigned,
|
|
724
|
-
label: opts.label || null,
|
|
725
|
-
},
|
|
721
|
+
metadata: Object.assign(_certAuditMetadata(m), { label: opts.label || null }),
|
|
726
722
|
});
|
|
727
723
|
} catch (_e) { /* audit best-effort — never break the caller */ }
|
|
728
724
|
}
|
|
@@ -2701,11 +2697,8 @@ function connectWithEch(opts) {
|
|
|
2701
2697
|
validateOpts.requireNonEmptyString(opts.host, "connectWithEch: host",
|
|
2702
2698
|
NetworkTlsError, "tls/ech-bad-opts");
|
|
2703
2699
|
var port = opts.port === undefined ? 443 : opts.port; // HTTPS default port
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
throw new NetworkTlsError("tls/ech-bad-opts",
|
|
2707
|
-
"connectWithEch: port must be an integer in 1..65535");
|
|
2708
|
-
}
|
|
2700
|
+
numericBounds.requirePositiveFiniteInt(port,
|
|
2701
|
+
"connectWithEch: port", NetworkTlsError, "tls/ech-bad-opts", { max: 65535 });
|
|
2709
2702
|
if (opts.alpn !== undefined && !Array.isArray(opts.alpn)) {
|
|
2710
2703
|
throw new NetworkTlsError("tls/ech-bad-opts",
|
|
2711
2704
|
"connectWithEch: alpn must be an array of strings");
|
|
@@ -2742,8 +2735,13 @@ function connectWithEch(opts) {
|
|
|
2742
2735
|
if (typeof opts.checkServerIdentity === "function") {
|
|
2743
2736
|
connectOpts.checkServerIdentity = opts.checkServerIdentity;
|
|
2744
2737
|
}
|
|
2745
|
-
|
|
2746
|
-
|
|
2738
|
+
// rejectUnauthorized defaults to true (full validation). An operator may
|
|
2739
|
+
// explicitly opt out — audited, never a framework default. Derived from
|
|
2740
|
+
// the operator's own value (operator-governed shape, mirroring mail.js /
|
|
2741
|
+
// log-stream-syslog.js), not a hardcoded literal.
|
|
2742
|
+
var rejectUnauthorized = opts.rejectUnauthorized !== false;
|
|
2743
|
+
connectOpts.rejectUnauthorized = rejectUnauthorized;
|
|
2744
|
+
if (!rejectUnauthorized) {
|
|
2747
2745
|
auditInsecureTls({ host: opts.host, port: port, source: "network.tls.connectWithEch" });
|
|
2748
2746
|
}
|
|
2749
2747
|
var echAttached = false;
|
|
@@ -66,7 +66,6 @@ function create(opts) {
|
|
|
66
66
|
var sectorAnnex = opts.sectorAnnex;
|
|
67
67
|
var csirtEndpoint = opts.csirtEndpoint || null;
|
|
68
68
|
var httpClient = opts.httpClient || null;
|
|
69
|
-
var auditOn = opts.audit !== false;
|
|
70
69
|
|
|
71
70
|
var ir = incidentReport().create({
|
|
72
71
|
audit: opts.audit,
|
|
@@ -79,16 +78,7 @@ function create(opts) {
|
|
|
79
78
|
},
|
|
80
79
|
});
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
if (!auditOn) return;
|
|
84
|
-
try {
|
|
85
|
-
audit().safeEmit({
|
|
86
|
-
action: "nis2.report." + action,
|
|
87
|
-
outcome: outcome,
|
|
88
|
-
metadata: metadata || {},
|
|
89
|
-
});
|
|
90
|
-
} catch (_e) { /* drop-silent */ }
|
|
91
|
-
}
|
|
81
|
+
var _emitAudit = audit().namespaced("nis2.report", opts.audit);
|
|
92
82
|
|
|
93
83
|
async function _submitToCsirt(payload) {
|
|
94
84
|
if (!csirtEndpoint || !httpClient) {
|
|
@@ -13,6 +13,16 @@
|
|
|
13
13
|
* inserting second would race on concurrent requests carrying
|
|
14
14
|
* the same nonce.
|
|
15
15
|
*
|
|
16
|
+
* await store.release(nonce) → boolean
|
|
17
|
+
* Un-claims a single nonce so a later checkAndInsert of the same value
|
|
18
|
+
* succeeds again — the rollback half of reserve -> commit -> rollback.
|
|
19
|
+
* A handler that claims an event id the moment a signature verifies (to
|
|
20
|
+
* win the race against a concurrent duplicate) MUST release it when
|
|
21
|
+
* downstream processing fails, otherwise the provider's at-least-once
|
|
22
|
+
* redelivery is reported as a replay and the event is dropped. Returns
|
|
23
|
+
* whether a live claim existed. Pair with checkAndInsert; without it an
|
|
24
|
+
* eager claim inverts the at-least-once contract on any failure.
|
|
25
|
+
*
|
|
16
26
|
* await store.purgeExpired() → number
|
|
17
27
|
* Removes entries past their expireAt. Called periodically by the
|
|
18
28
|
* middleware that uses the store. Returns the count purged.
|
|
@@ -32,8 +42,11 @@
|
|
|
32
42
|
* table _blamejs_api_encrypt_nonces. The PRIMARY KEY race is what
|
|
33
43
|
* makes the check + insert atomic across nodes.
|
|
34
44
|
*
|
|
35
|
-
* { checkAndInsert, purgeExpired
|
|
36
|
-
* custom backend (Redis SETNX, Memcached add, etc.).
|
|
45
|
+
* { checkAndInsert, release?, purgeExpired?, close? } — operator-supplied
|
|
46
|
+
* custom backend (Redis SETNX, Memcached add, etc.). release() is
|
|
47
|
+
* optional but required to use reserve -> rollback; a backend omitting
|
|
48
|
+
* it throws NONCE_BACKEND_NO_RELEASE the first time release() is called
|
|
49
|
+
* (a loud gap, never a silent dropped rollback). Use this
|
|
37
50
|
* for cross-process accuracy without a per-request SQL hop.
|
|
38
51
|
*
|
|
39
52
|
* Sweep cadence: memory backend sweeps every opts.sweepIntervalMs
|
|
@@ -132,6 +145,21 @@ function _memoryBackend(opts) {
|
|
|
132
145
|
return Promise.resolve(true);
|
|
133
146
|
}
|
|
134
147
|
|
|
148
|
+
// Un-claim a nonce so a future checkAndInsert of the same value succeeds
|
|
149
|
+
// again — the rollback half of reserve -> commit -> rollback. A handler
|
|
150
|
+
// that claims an event id the moment a signature verifies (to win the race
|
|
151
|
+
// against a concurrent duplicate) MUST release it when downstream processing
|
|
152
|
+
// fails, otherwise the provider's at-least-once redelivery is reported as a
|
|
153
|
+
// replay and the event is dropped. Returns whether a live claim existed.
|
|
154
|
+
function release(nonce) {
|
|
155
|
+
if (typeof nonce !== "string" || nonce.length === 0) {
|
|
156
|
+
return Promise.reject(_err("INVALID_NONCE", "nonce must be a non-empty string"));
|
|
157
|
+
}
|
|
158
|
+
var existed = seen.get(nonce) !== undefined;
|
|
159
|
+
if (existed) seen.delete(nonce);
|
|
160
|
+
return Promise.resolve(existed);
|
|
161
|
+
}
|
|
162
|
+
|
|
135
163
|
function purgeExpired() {
|
|
136
164
|
return Promise.resolve(_purgeExpiredSync());
|
|
137
165
|
}
|
|
@@ -144,6 +172,7 @@ function _memoryBackend(opts) {
|
|
|
144
172
|
return {
|
|
145
173
|
name: "memory",
|
|
146
174
|
checkAndInsert: checkAndInsert,
|
|
175
|
+
release: release,
|
|
147
176
|
purgeExpired: purgeExpired,
|
|
148
177
|
close: close,
|
|
149
178
|
// Test hooks — underlying entry count + count of capacity fail-closed
|
|
@@ -178,6 +207,19 @@ function _clusterBackend(_opts) {
|
|
|
178
207
|
return (result && result.rowCount > 0);
|
|
179
208
|
}
|
|
180
209
|
|
|
210
|
+
async function release(nonce) {
|
|
211
|
+
if (typeof nonce !== "string" || nonce.length === 0) {
|
|
212
|
+
throw _err("INVALID_NONCE", "nonce must be a non-empty string");
|
|
213
|
+
}
|
|
214
|
+
// Un-claim a single nonce (the reserve -> rollback half). The middleware
|
|
215
|
+
// hashes the raw nonce before it reaches here, so we delete by hash.
|
|
216
|
+
var built = sql.delete(frameworkSchema.tableName(NONCE_TABLE), _nonceSqlOpts())
|
|
217
|
+
.where("nonceHash", "=", nonce)
|
|
218
|
+
.toSql();
|
|
219
|
+
var result = await clusterStorage.execute(built.sql, built.params);
|
|
220
|
+
return (result && result.rowCount > 0);
|
|
221
|
+
}
|
|
222
|
+
|
|
181
223
|
async function purgeExpired() {
|
|
182
224
|
var built = sql.delete(frameworkSchema.tableName(NONCE_TABLE), _nonceSqlOpts())
|
|
183
225
|
.where("expireAt", "<=", Date.now())
|
|
@@ -191,6 +233,7 @@ function _clusterBackend(_opts) {
|
|
|
191
233
|
return {
|
|
192
234
|
name: "cluster",
|
|
193
235
|
checkAndInsert: checkAndInsert,
|
|
236
|
+
release: release,
|
|
194
237
|
purgeExpired: purgeExpired,
|
|
195
238
|
close: close,
|
|
196
239
|
};
|
|
@@ -208,6 +251,15 @@ function create(opts) {
|
|
|
208
251
|
return Object.assign({
|
|
209
252
|
name: "custom",
|
|
210
253
|
purgeExpired: function () { return Promise.resolve(0); },
|
|
254
|
+
// A custom backend that omits release() cannot participate in
|
|
255
|
+
// reserve -> rollback. Fail LOUDLY (not a silent no-op) so the gap
|
|
256
|
+
// surfaces the first time a handler tries to un-claim, rather than
|
|
257
|
+
// silently dropping the rollback and inverting the at-least-once contract.
|
|
258
|
+
release: function () {
|
|
259
|
+
return Promise.reject(_err("BACKEND_NO_RELEASE",
|
|
260
|
+
"this custom nonce backend does not implement release(nonce); " +
|
|
261
|
+
"the reserve -> commit -> rollback pattern requires it"));
|
|
262
|
+
},
|
|
211
263
|
close: function () {},
|
|
212
264
|
}, backend);
|
|
213
265
|
}
|
|
@@ -215,11 +267,37 @@ function create(opts) {
|
|
|
215
267
|
if (!backend || backend === "memory") return _memoryBackend(opts);
|
|
216
268
|
throw _err("UNKNOWN_BACKEND",
|
|
217
269
|
"nonce-store: unknown backend '" + backend +
|
|
218
|
-
"' (must be 'memory', 'cluster', or { checkAndInsert, purgeExpired
|
|
270
|
+
"' (must be 'memory', 'cluster', or { checkAndInsert, release?, purgeExpired?, close? })");
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// enforceReplay(store, jti, expireAtMs, opts) — single-use enforcement
|
|
274
|
+
// against a replay store: `await store.checkAndInsert(jti, expireAtMs)`,
|
|
275
|
+
// raising opts.errorClass(opts.storeFailedCode, …) if the store itself
|
|
276
|
+
// fails (a store outage must NOT be mistaken for a clean token) and
|
|
277
|
+
// opts.errorClass(opts.replayCode, "<opts.tokenLabel> jti='<jti>' has
|
|
278
|
+
// been seen before — replay refused") if the jti was already seen. The
|
|
279
|
+
// fail-closed anti-replay control flow every JWT / DPoP verifier repeated
|
|
280
|
+
// identically — centralised here so the contract lives in one place.
|
|
281
|
+
// Verifiers with a divergent message or store contract (e.g. an atomic
|
|
282
|
+
// back-channel-logout-token store) keep their own inline check.
|
|
283
|
+
async function enforceReplay(store, jti, expireAtMs, opts) {
|
|
284
|
+
opts = opts || {};
|
|
285
|
+
var inserted;
|
|
286
|
+
try {
|
|
287
|
+
inserted = await store.checkAndInsert(jti, expireAtMs);
|
|
288
|
+
} catch (e) {
|
|
289
|
+
throw new opts.errorClass(opts.storeFailedCode,
|
|
290
|
+
"replayStore.checkAndInsert threw: " + ((e && e.message) || String(e)));
|
|
291
|
+
}
|
|
292
|
+
if (inserted === false) {
|
|
293
|
+
throw new opts.errorClass(opts.replayCode,
|
|
294
|
+
opts.tokenLabel + " jti='" + jti + "' has been seen before — replay refused");
|
|
295
|
+
}
|
|
219
296
|
}
|
|
220
297
|
|
|
221
298
|
module.exports = {
|
|
222
299
|
create: create,
|
|
300
|
+
enforceReplay: enforceReplay,
|
|
223
301
|
NonceStoreError: NonceStoreError,
|
|
224
302
|
_memoryBackend: _memoryBackend,
|
|
225
303
|
_clusterBackend: _clusterBackend,
|
|
@@ -42,6 +42,20 @@ function shape(value) {
|
|
|
42
42
|
return (typeof value) + " " + String(value);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
// _throwInt — construct + throw a code-first defineClass error. When no
|
|
46
|
+
// errorOpts is supplied the call is the historical bare `new ErrorClass(
|
|
47
|
+
// code, message)` (byte-identical for every existing caller); pass
|
|
48
|
+
// errorOpts { permanent, statusCode } to forward the framework error's
|
|
49
|
+
// non-retryable flag / HTTP status (a config opt that's wrong on retry
|
|
50
|
+
// stays wrong; a request-shaped opt carries its 4xx). Message-FIRST
|
|
51
|
+
// classes (AtomicFileError / SafeBufferError / SafeUrlError) must NOT use
|
|
52
|
+
// the require* throwers — they use the isPositiveFiniteInt predicate + their
|
|
53
|
+
// own throw (see the module header) so code/message don't swap.
|
|
54
|
+
function _throwInt(errorClass, code, message, errorOpts) {
|
|
55
|
+
if (errorOpts) throw new errorClass(code, message, errorOpts.permanent, errorOpts.statusCode);
|
|
56
|
+
throw new errorClass(code, message);
|
|
57
|
+
}
|
|
58
|
+
|
|
45
59
|
function isPositiveFiniteInt(value) {
|
|
46
60
|
return typeof value === "number" && Number.isFinite(value) &&
|
|
47
61
|
Number.isInteger(value) && value > 0;
|
|
@@ -64,11 +78,11 @@ function isNonNegativeFiniteInt(value) {
|
|
|
64
78
|
// nb.requirePositiveFiniteIntIfPresent(opts.graceMs,
|
|
65
79
|
// "app-shutdown.create: opts.graceMs", AppShutdownError,
|
|
66
80
|
// "app-shutdown/bad-grace-ms");
|
|
67
|
-
function requirePositiveFiniteIntIfPresent(value, label, errorClass, code) {
|
|
81
|
+
function requirePositiveFiniteIntIfPresent(value, label, errorClass, code, errorOpts) {
|
|
68
82
|
if (value === undefined) return value;
|
|
69
83
|
if (!isPositiveFiniteInt(value)) {
|
|
70
|
-
|
|
71
|
-
(label || "value") + " must be a positive finite integer; got " + shape(value));
|
|
84
|
+
_throwInt(errorClass, code,
|
|
85
|
+
(label || "value") + " must be a positive finite integer; got " + shape(value), errorOpts);
|
|
72
86
|
}
|
|
73
87
|
return value;
|
|
74
88
|
}
|
|
@@ -102,13 +116,13 @@ function _rangeSuffix(range) {
|
|
|
102
116
|
if (range.min != null) return " >= " + range.min;
|
|
103
117
|
return "";
|
|
104
118
|
}
|
|
105
|
-
function requirePositiveFiniteInt(value, label, errorClass, code, range) {
|
|
119
|
+
function requirePositiveFiniteInt(value, label, errorClass, code, range, errorOpts) {
|
|
106
120
|
var inRange = !range ||
|
|
107
121
|
((range.min == null || value >= range.min) && (range.max == null || value <= range.max));
|
|
108
122
|
if (!isPositiveFiniteInt(value) || !inRange) {
|
|
109
|
-
|
|
123
|
+
_throwInt(errorClass, code,
|
|
110
124
|
(label || "value") + " must be a positive finite integer" +
|
|
111
|
-
_rangeSuffix(range) + "; got " + shape(value));
|
|
125
|
+
_rangeSuffix(range) + "; got " + shape(value), errorOpts);
|
|
112
126
|
}
|
|
113
127
|
return value;
|
|
114
128
|
}
|
|
@@ -123,12 +137,12 @@ function requirePositiveFiniteInt(value, label, errorClass, code, range) {
|
|
|
123
137
|
// nb.requireAllPositiveFiniteIntIfPresent(opts,
|
|
124
138
|
// ["maxBytes", "maxAttrValueBytes", "maxTagDepth", "maxAttrsPerTag"],
|
|
125
139
|
// "guardHtml.validate", GuardHtmlError, "html.bad-opt");
|
|
126
|
-
function requireAllPositiveFiniteIntIfPresent(opts, names, labelPrefix, errorClass, code) {
|
|
140
|
+
function requireAllPositiveFiniteIntIfPresent(opts, names, labelPrefix, errorClass, code, errorOpts) {
|
|
127
141
|
if (!opts || !Array.isArray(names)) return;
|
|
128
142
|
for (var i = 0; i < names.length; i += 1) {
|
|
129
143
|
var n = names[i];
|
|
130
144
|
requirePositiveFiniteIntIfPresent(opts[n],
|
|
131
|
-
(labelPrefix || "") + ": " + n, errorClass, code);
|
|
145
|
+
(labelPrefix || "") + ": " + n, errorClass, code, errorOpts);
|
|
132
146
|
}
|
|
133
147
|
}
|
|
134
148
|
|
|
@@ -33,6 +33,7 @@ var C = require("../constants");
|
|
|
33
33
|
var httpClient = require("../http-client");
|
|
34
34
|
var requestHelpers = require("../request-helpers");
|
|
35
35
|
var safeUrl = require("../safe-url");
|
|
36
|
+
var markupEscape = require("../markup-escape").markupEscape;
|
|
36
37
|
var { ObjectStoreError } = require("../framework-error");
|
|
37
38
|
|
|
38
39
|
var _err = ObjectStoreError.factory;
|
|
@@ -122,12 +123,7 @@ function _validateCorsRule(rule, idx) {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
function _xmlEscape(s) {
|
|
125
|
-
return
|
|
126
|
-
.replace(/&/g, "&")
|
|
127
|
-
.replace(/</g, "<")
|
|
128
|
-
.replace(/>/g, ">")
|
|
129
|
-
.replace(/"/g, """)
|
|
130
|
-
.replace(/'/g, "'");
|
|
126
|
+
return markupEscape(s, { apos: "'" });
|
|
131
127
|
}
|
|
132
128
|
|
|
133
129
|
function _buildCorsXml(rules) {
|
|
@@ -93,14 +93,6 @@ function _encodeBlobKey(key) {
|
|
|
93
93
|
|
|
94
94
|
var DEFAULT_API_VERSION = "2024-08-04";
|
|
95
95
|
|
|
96
|
-
// Service SAS expiry bounds. Azure doesn't enforce a hard max, but
|
|
97
|
-
// matching the SigV4 / V4 7-day cap keeps semantics uniform across
|
|
98
|
-
// backends and reflects best practice (long-lived SAS tokens are
|
|
99
|
-
// effectively credentials).
|
|
100
|
-
var SAS_DEFAULT_EXPIRES_SECONDS = C.TIME.minutes(15) / C.TIME.seconds(1);
|
|
101
|
-
var SAS_MAX_EXPIRES_SECONDS = C.TIME.days(7) / C.TIME.seconds(1);
|
|
102
|
-
var SAS_MIN_EXPIRES_SECONDS = 1;
|
|
103
|
-
|
|
104
96
|
var _err = ObjectStoreError.factory;
|
|
105
97
|
|
|
106
98
|
var _httpRequest = sharedRequest;
|
|
@@ -312,33 +304,13 @@ function create(config) {
|
|
|
312
304
|
function getResponse(key, opts) {
|
|
313
305
|
opts = opts || {};
|
|
314
306
|
var url = _blobUrl(key);
|
|
315
|
-
var extraHeaders = {};
|
|
316
|
-
if (opts.range) {
|
|
317
|
-
extraHeaders["x-ms-range"] = "bytes=" + opts.range.start + "-" + opts.range.end;
|
|
318
|
-
}
|
|
319
|
-
if (opts.ifNoneMatch) extraHeaders["If-None-Match"] = opts.ifNoneMatch;
|
|
320
|
-
if (opts.ifMatch) extraHeaders["If-Match"] = opts.ifMatch;
|
|
321
|
-
if (opts.ifModifiedSince) extraHeaders["If-Modified-Since"] = opts.ifModifiedSince;
|
|
322
|
-
if (opts.ifUnmodifiedSince) extraHeaders["If-Unmodified-Since"] = opts.ifUnmodifiedSince;
|
|
307
|
+
var extraHeaders = sharedRequest.applyConditionalGetHeaders({}, opts, "x-ms-range");
|
|
323
308
|
var headers = _signed("GET", url, extraHeaders);
|
|
324
309
|
return _httpRequest("GET", url, headers, null, reqOpts).then(function (res) {
|
|
325
|
-
return
|
|
326
|
-
statusCode: res.statusCode,
|
|
327
|
-
body: res.body,
|
|
328
|
-
etag: res.headers && res.headers.etag,
|
|
329
|
-
lastModified: res.headers && res.headers["last-modified"]
|
|
330
|
-
? Date.parse(res.headers["last-modified"]) : null,
|
|
331
|
-
contentRange: res.headers && res.headers["content-range"] || null,
|
|
332
|
-
size: res.headers && res.headers["content-length"]
|
|
333
|
-
? parseInt(res.headers["content-length"], 10) : null,
|
|
334
|
-
contentType: res.headers && res.headers["content-type"] || null,
|
|
335
|
-
};
|
|
310
|
+
return sharedRequest.mapGetResponse(res);
|
|
336
311
|
}, function (err) {
|
|
337
312
|
if (err && err.statusCode === requestHelpers.HTTP_STATUS.NOT_MODIFIED) {
|
|
338
|
-
return
|
|
339
|
-
statusCode: requestHelpers.HTTP_STATUS.NOT_MODIFIED,
|
|
340
|
-
body: null, etag: null, lastModified: null,
|
|
341
|
-
};
|
|
313
|
+
return sharedRequest.notModifiedGetResult();
|
|
342
314
|
}
|
|
343
315
|
throw err;
|
|
344
316
|
});
|
|
@@ -348,11 +320,7 @@ function create(config) {
|
|
|
348
320
|
var url = _blobUrl(key);
|
|
349
321
|
var headers = _signed("HEAD", url, {});
|
|
350
322
|
return _httpRequest("HEAD", url, headers, null, reqOpts).then(function (res) {
|
|
351
|
-
return
|
|
352
|
-
size: res.headers["content-length"] ? parseInt(res.headers["content-length"], 10) : null,
|
|
353
|
-
etag: res.headers.etag,
|
|
354
|
-
lastModified: res.headers["last-modified"] ? Date.parse(res.headers["last-modified"]) : null,
|
|
355
|
-
};
|
|
323
|
+
return sharedRequest.mapHeadResponse(res);
|
|
356
324
|
});
|
|
357
325
|
}
|
|
358
326
|
|
|
@@ -415,15 +383,7 @@ function create(config) {
|
|
|
415
383
|
// "Create a service SAS". We sign with the account key (HMAC-SHA256
|
|
416
384
|
// over the canonical string) and emit the token as URL query params.
|
|
417
385
|
function _buildSasToken(permissions, opts) {
|
|
418
|
-
var expiresIn = opts
|
|
419
|
-
if (typeof expiresIn !== "number" ||
|
|
420
|
-
expiresIn < SAS_MIN_EXPIRES_SECONDS ||
|
|
421
|
-
expiresIn > SAS_MAX_EXPIRES_SECONDS) {
|
|
422
|
-
throw _err("INVALID_EXPIRES",
|
|
423
|
-
"presigned URL: expiresIn must be a number of seconds between " +
|
|
424
|
-
SAS_MIN_EXPIRES_SECONDS + " and " + SAS_MAX_EXPIRES_SECONDS +
|
|
425
|
-
" (7 days)", true);
|
|
426
|
-
}
|
|
386
|
+
var expiresIn = sharedRequest.resolvePresignExpires(opts, "presigned URL", "");
|
|
427
387
|
var nowDate = opts.date || new Date();
|
|
428
388
|
var expiry = new Date(nowDate.getTime() + C.TIME.seconds(expiresIn));
|
|
429
389
|
// Azure accepts ISO 8601 with second precision; strip ms.
|