@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
|
@@ -30,6 +30,7 @@ var defineClass = require("../framework-error").defineClass;
|
|
|
30
30
|
var lazyRequire = require("../lazy-require");
|
|
31
31
|
var validateOpts = require("../validate-opts");
|
|
32
32
|
var safeBuffer = require("../safe-buffer");
|
|
33
|
+
var requestHelpers = require("../request-helpers");
|
|
33
34
|
|
|
34
35
|
var audit = lazyRequire(function () { return require("../audit"); });
|
|
35
36
|
|
|
@@ -93,17 +94,13 @@ function create(opts) {
|
|
|
93
94
|
var actionBase = typeof opts.auditAction === "string" && opts.auditAction.length > 0
|
|
94
95
|
? opts.auditAction : "middleware.bot_disclose";
|
|
95
96
|
|
|
97
|
+
// null mountPaths = apply to every route; otherwise reuse the shared
|
|
98
|
+
// segment-boundary matcher (built once).
|
|
99
|
+
var _mountMatch = mountPaths
|
|
100
|
+
? requestHelpers.makeSkipMatcher({ skipPaths: mountPaths }, "middleware.botDisclose")
|
|
101
|
+
: null;
|
|
96
102
|
function _matches(req) {
|
|
97
|
-
|
|
98
|
-
var p = req.url || "";
|
|
99
|
-
var qpos = p.indexOf("?");
|
|
100
|
-
if (qpos !== -1) p = p.slice(0, qpos);
|
|
101
|
-
for (var i = 0; i < mountPaths.length; i++) {
|
|
102
|
-
var m = mountPaths[i];
|
|
103
|
-
if (typeof m === "string" && (p === m || p.indexOf(m + "/") === 0)) return true;
|
|
104
|
-
if (m instanceof RegExp && m.test(p)) return true;
|
|
105
|
-
}
|
|
106
|
-
return false;
|
|
103
|
+
return _mountMatch ? _mountMatch(req) : true;
|
|
107
104
|
}
|
|
108
105
|
|
|
109
106
|
function _emitAudit(action, outcome, metadata) {
|
|
@@ -144,21 +144,13 @@ function create(opts) {
|
|
|
144
144
|
var blockedAgents = DEFAULT_BLOCKED_AGENTS.concat((opts.blockedAgents || []).map(function (r, i) {
|
|
145
145
|
return _coerceAgentPattern(r, "middleware.botGuard: blockedAgents[" + i + "]");
|
|
146
146
|
}));
|
|
147
|
-
var skipPaths = opts.skipPaths || [];
|
|
148
147
|
var statusOnBlock = opts.statusOnBlock || 403;
|
|
149
148
|
var bodyOnBlock = opts.bodyOnBlock !== undefined ? opts.bodyOnBlock : "Forbidden";
|
|
150
149
|
var onDeny = typeof opts.onDeny === "function" ? opts.onDeny : null;
|
|
151
150
|
var problemMode = opts.problemDetails === true;
|
|
152
151
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
for (var i = 0; i < skipPaths.length; i++) {
|
|
156
|
-
if (typeof skipPaths[i] === "string" ? path.indexOf(skipPaths[i]) === 0 : skipPaths[i].test(path)) {
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
152
|
+
// Path-exemption predicate (string-prefix or RegExp), validated at create().
|
|
153
|
+
var _shouldSkip = requestHelpers.makeSkipMatcher(opts, "middleware.botGuard");
|
|
162
154
|
|
|
163
155
|
function _looksLikeApi(req) {
|
|
164
156
|
var path = req.pathname || req.url || "/";
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
* }
|
|
68
68
|
*/
|
|
69
69
|
var lazyRequire = require("../lazy-require");
|
|
70
|
+
var pick = require("../pick");
|
|
70
71
|
var forms = require("../forms");
|
|
71
72
|
var requestHelpers = require("../request-helpers");
|
|
72
73
|
var validateOpts = require("../validate-opts");
|
|
@@ -111,7 +112,7 @@ function _parseCookieHeader(header) {
|
|
|
111
112
|
if (eq === -1) continue;
|
|
112
113
|
var k = p.slice(0, eq).trim();
|
|
113
114
|
if (k.length === 0) continue;
|
|
114
|
-
if (k
|
|
115
|
+
if (pick.isPoisonedKey(k)) continue;
|
|
115
116
|
if (seen.has(k)) continue; // first-occurrence wins
|
|
116
117
|
seen.add(k);
|
|
117
118
|
var v = p.slice(eq + 1).trim();
|
|
@@ -296,7 +297,7 @@ function create(opts) {
|
|
|
296
297
|
validateOpts(opts, [
|
|
297
298
|
"cookie", "tokenLookup", "fieldName", "headerName", "methods", "audit",
|
|
298
299
|
"trustProxy", "checkOrigin", "allowedOrigins", "requireJsonContentType",
|
|
299
|
-
"requireOrigin", "skipStateless", "onDeny", "problemDetails",
|
|
300
|
+
"requireOrigin", "skipStateless", "skipPaths", "skip", "onDeny", "problemDetails",
|
|
300
301
|
], "middleware.csrfProtect");
|
|
301
302
|
var onDeny = typeof opts.onDeny === "function" ? opts.onDeny : null;
|
|
302
303
|
var problemMode = opts.problemDetails === true;
|
|
@@ -368,6 +369,13 @@ function create(opts) {
|
|
|
368
369
|
// request always carries a Cookie header and is validated.
|
|
369
370
|
var skipStateless = opts.skipStateless === true;
|
|
370
371
|
|
|
372
|
+
// Per-path exemption (string-prefix / RegExp / skip predicate), validated at
|
|
373
|
+
// create(). Lets one route (an RFC 8058 List-Unsubscribe-Post endpoint, a
|
|
374
|
+
// webhook, a bearer-token API path on the same app) opt out of the
|
|
375
|
+
// double-submit check while the app-level mount stays in place — the token is
|
|
376
|
+
// still issued for any later browser flow.
|
|
377
|
+
var _shouldSkip = requestHelpers.makeSkipMatcher(opts, "middleware.csrfProtect");
|
|
378
|
+
|
|
371
379
|
// Cookie issuance config (only when opts.cookie is set).
|
|
372
380
|
var cookieCfg = null;
|
|
373
381
|
if (hasCookie) {
|
|
@@ -480,6 +488,9 @@ function create(opts) {
|
|
|
480
488
|
// (e.g. error response) still need req.csrfToken populated.
|
|
481
489
|
var expected = _issueIfNeeded(req, res);
|
|
482
490
|
|
|
491
|
+
// Exempt routes skip the double-submit check (token still issued above).
|
|
492
|
+
if (_shouldSkip(req)) return next();
|
|
493
|
+
|
|
483
494
|
if (methods.indexOf(req.method) === -1) return next();
|
|
484
495
|
|
|
485
496
|
// Stateless / token-authenticated requests are not CSRF-able — the
|
|
@@ -107,7 +107,6 @@ function create(opts) {
|
|
|
107
107
|
}
|
|
108
108
|
var bytesPerDay = opts.bytesPerDay;
|
|
109
109
|
var getKey = typeof opts.getKey === "function" ? opts.getKey : _defaultGetKey;
|
|
110
|
-
var auditOn = opts.audit !== false;
|
|
111
110
|
// onDeny is the canonical hook across the deny-path middleware
|
|
112
111
|
// family; onExceeded is the original name kept working as an alias.
|
|
113
112
|
var onDeny = typeof opts.onDeny === "function" ? opts.onDeny
|
|
@@ -127,33 +126,14 @@ function create(opts) {
|
|
|
127
126
|
});
|
|
128
127
|
var backend = quota._backend;
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (qpos !== -1) p = p.slice(0, qpos);
|
|
135
|
-
for (var i = 0; i < skipPaths.length; i++) {
|
|
136
|
-
if (typeof skipPaths[i] === "string" && p === skipPaths[i]) return true;
|
|
137
|
-
if (skipPaths[i] instanceof RegExp && skipPaths[i].test(p)) return true;
|
|
138
|
-
}
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
129
|
+
// exact:true preserves this guard's whole-path skip semantics (no descendant
|
|
130
|
+
// match); makeSkipMatcher strips the query + resolves url || originalUrl.
|
|
131
|
+
var _shouldSkip = requestHelpers().makeSkipMatcher(
|
|
132
|
+
{ skipPaths: skipPaths, exact: true }, "middleware.dailyByteQuota");
|
|
141
133
|
|
|
142
|
-
|
|
143
|
-
if (!auditOn) return;
|
|
144
|
-
try {
|
|
145
|
-
audit().safeEmit({
|
|
146
|
-
action: "middleware.daily_byte_quota." + action,
|
|
147
|
-
outcome: outcome,
|
|
148
|
-
metadata: metadata || {},
|
|
149
|
-
});
|
|
150
|
-
} catch (_e) { /* drop-silent — audit is best-effort */ }
|
|
151
|
-
}
|
|
134
|
+
var _emitAudit = audit().namespaced("middleware.daily_byte_quota", opts.audit);
|
|
152
135
|
|
|
153
|
-
|
|
154
|
-
try { observability().safeEvent("middleware.daily_byte_quota." + verb, n || 1, labels || {}); }
|
|
155
|
-
catch (_e) { /* drop-silent */ }
|
|
156
|
-
}
|
|
136
|
+
var _emitMetric = observability().namespaced("middleware.daily_byte_quota");
|
|
157
137
|
|
|
158
138
|
return async function dailyByteQuotaMiddleware(req, res, next) {
|
|
159
139
|
if (_shouldSkip(req)) return next();
|
|
@@ -147,6 +147,24 @@ function denyResponse(req, res, ctx) {
|
|
|
147
147
|
return undefined;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
// methodNotAllowed(res, allow) — write the bare HTTP 405 refusal the
|
|
151
|
+
// single-file static-content middlewares (assetlinks / security.txt / web-app-
|
|
152
|
+
// manifest) share: an `Allow` header plus a `text/plain` "Method Not Allowed"
|
|
153
|
+
// body with an explicit Content-Length. Kept separate from denyResponse() (the
|
|
154
|
+
// hook-aware, problem+json-capable refusal path) so the static handlers emit a
|
|
155
|
+
// fixed, minimal response — `allow` is the comma-joined method list (e.g.
|
|
156
|
+
// "GET, HEAD").
|
|
157
|
+
function methodNotAllowed(res, allow) {
|
|
158
|
+
var bodyMsg = "Method Not Allowed";
|
|
159
|
+
res.writeHead(405, { // HTTP 405 status
|
|
160
|
+
"Allow": allow,
|
|
161
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
162
|
+
"Content-Length": Buffer.byteLength(bodyMsg),
|
|
163
|
+
});
|
|
164
|
+
res.end(bodyMsg);
|
|
165
|
+
}
|
|
166
|
+
|
|
150
167
|
module.exports = {
|
|
151
|
-
denyResponse:
|
|
168
|
+
denyResponse: denyResponse,
|
|
169
|
+
methodNotAllowed: methodNotAllowed,
|
|
152
170
|
};
|
|
@@ -165,6 +165,7 @@ function create(opts) {
|
|
|
165
165
|
"allowSameSite", "allowCrossSite", "allowMissing",
|
|
166
166
|
"allowedDest", "deniedDest", "allowStorageAccess", "strictDest",
|
|
167
167
|
"allowedNavigate", "methods", "audit", "onDeny", "problemDetails",
|
|
168
|
+
"skipPaths", "skip",
|
|
168
169
|
], "middleware.fetchMetadata");
|
|
169
170
|
validateOpts.optionalBoolean(opts.allowStorageAccess, "middleware.fetchMetadata: allowStorageAccess");
|
|
170
171
|
validateOpts.optionalBoolean(opts.strictDest, "middleware.fetchMetadata: strictDest");
|
|
@@ -174,6 +175,11 @@ function create(opts) {
|
|
|
174
175
|
_validateDestList(opts.deniedDest, "deniedDest");
|
|
175
176
|
}
|
|
176
177
|
|
|
178
|
+
// Per-path exemption (string-prefix / RegExp / skip predicate), validated at
|
|
179
|
+
// create() — exempt a webhook / cookieless edge-cached route from the
|
|
180
|
+
// fetch-metadata gate without disabling the app-level mount.
|
|
181
|
+
var _shouldSkip = requestHelpers.makeSkipMatcher(opts, "middleware.fetchMetadata");
|
|
182
|
+
|
|
177
183
|
var onDeny = typeof opts.onDeny === "function" ? opts.onDeny : null;
|
|
178
184
|
var problemMode = opts.problemDetails === true;
|
|
179
185
|
var allowSameSite = opts.allowSameSite !== false;
|
|
@@ -220,6 +226,7 @@ function create(opts) {
|
|
|
220
226
|
// Idempotent: a second fetch-metadata mount this request is a no-op.
|
|
221
227
|
if (req._fetchMetadataChecked) return next();
|
|
222
228
|
req._fetchMetadataChecked = true;
|
|
229
|
+
if (_shouldSkip(req)) return next();
|
|
223
230
|
if (methods.indexOf(req.method) === -1) return next();
|
|
224
231
|
|
|
225
232
|
var headers = req.headers || {};
|
|
@@ -53,7 +53,7 @@ var cryptoField = require("../crypto-field");
|
|
|
53
53
|
var vault = require("../vault");
|
|
54
54
|
var { defineClass } = require("../framework-error");
|
|
55
55
|
|
|
56
|
-
var
|
|
56
|
+
var auditEmit = require("../audit-emit");
|
|
57
57
|
var problemDetails = lazyRequire(function () { return require("../problem-details"); });
|
|
58
58
|
var C = require("../constants");
|
|
59
59
|
|
|
@@ -533,16 +533,8 @@ function dbStore(opts) {
|
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
function _validateStore(store, where) {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
where + ": store must be an object", true);
|
|
539
|
-
}
|
|
540
|
-
if (typeof store.get !== "function" ||
|
|
541
|
-
typeof store.set !== "function" ||
|
|
542
|
-
typeof store.delete !== "function") {
|
|
543
|
-
throw new IdempotencyError("idempotency/bad-store",
|
|
544
|
-
where + ": store must implement { get, set, delete }", true);
|
|
545
|
-
}
|
|
536
|
+
validateOpts.requireMethods(store, ["get", "set", "delete"],
|
|
537
|
+
where + ": store", IdempotencyError, "idempotency/bad-store", true);
|
|
546
538
|
}
|
|
547
539
|
|
|
548
540
|
function _fingerprintRequest(req, bodyBytes, store) {
|
|
@@ -568,15 +560,7 @@ function _fingerprintRequest(req, bodyBytes, store) {
|
|
|
568
560
|
return nodeCrypto.createHash("sha3-256").update(preimage).digest("hex");
|
|
569
561
|
}
|
|
570
562
|
|
|
571
|
-
|
|
572
|
-
try {
|
|
573
|
-
audit().safeEmit({
|
|
574
|
-
action: action,
|
|
575
|
-
outcome: outcome || "success",
|
|
576
|
-
metadata: metadata,
|
|
577
|
-
});
|
|
578
|
-
} catch (_e) { /* best-effort */ }
|
|
579
|
-
}
|
|
563
|
+
var _emitAudit = auditEmit.emit;
|
|
580
564
|
|
|
581
565
|
/**
|
|
582
566
|
* @primitive b.middleware.idempotencyKey
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
*
|
|
57
57
|
* Audit: every limit hit emits system.ratelimit.block with the key + path.
|
|
58
58
|
*/
|
|
59
|
+
var boundedMap = require("../bounded-map");
|
|
59
60
|
var C = require("../constants");
|
|
60
61
|
var frameworkSchema = require("../framework-schema");
|
|
61
62
|
var lazyRequire = require("../lazy-require");
|
|
@@ -178,11 +179,14 @@ function _memoryTokenBucketBackend(opts) {
|
|
|
178
179
|
// microtask cost per request.
|
|
179
180
|
function take(key, _cost) {
|
|
180
181
|
var now = Date.now();
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
182
|
+
// Insert a fresh full bucket on first sight; only an already-present
|
|
183
|
+
// bucket refills (a brand-new bucket starts at `burst`, so refilling
|
|
184
|
+
// it would be a no-op clamped to `burst` anyway).
|
|
185
|
+
var existed = buckets.has(key);
|
|
186
|
+
var b = boundedMap.getOrInsert(buckets, key, function () {
|
|
187
|
+
return { tokens: burst, lastRefillAt: now };
|
|
188
|
+
});
|
|
189
|
+
if (existed) {
|
|
186
190
|
var elapsed = (now - b.lastRefillAt) / C.TIME.seconds(1);
|
|
187
191
|
b.tokens = Math.min(burst, b.tokens + elapsed * refillPerSecond);
|
|
188
192
|
b.lastRefillAt = now;
|
|
@@ -254,10 +258,15 @@ function _memoryFixedWindowBackend(opts) {
|
|
|
254
258
|
function take(key, _cost) {
|
|
255
259
|
var now = Date.now();
|
|
256
260
|
var windowStart = Math.floor(now / windowMs) * windowMs;
|
|
257
|
-
var c =
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
+
var c = boundedMap.getOrInsert(counters, key, function () {
|
|
262
|
+
return { windowStart: windowStart, count: 0 };
|
|
263
|
+
});
|
|
264
|
+
// A key carried over from a prior window re-seeds to the current
|
|
265
|
+
// window (count restarts) — getOrInsert only handles first-sight, so
|
|
266
|
+
// the rollover case resets the existing record in place.
|
|
267
|
+
if (c.windowStart !== windowStart) {
|
|
268
|
+
c.windowStart = windowStart;
|
|
269
|
+
c.count = 0;
|
|
261
270
|
}
|
|
262
271
|
c.count += 1;
|
|
263
272
|
if (c.count <= max) {
|
|
@@ -489,29 +498,12 @@ function create(opts) {
|
|
|
489
498
|
? opts.headerPrefix : "X-RateLimit-";
|
|
490
499
|
var limitHeader = headerPrefix + "Limit"; // allow:hand-rolled-sql — HTTP response-header name (X-RateLimit-Limit), not a SQL LIMIT clause
|
|
491
500
|
var remainingHeader = headerPrefix + "Remaining";
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
// Anything else would crash _shouldSkip with TypeError on the first request.
|
|
495
|
-
for (var sp = 0; sp < skipPaths.length; sp++) {
|
|
496
|
-
if (typeof skipPaths[sp] !== "string" && !(skipPaths[sp] instanceof RegExp)) {
|
|
497
|
-
throw new Error("middleware.rateLimit: skipPaths[" + sp +
|
|
498
|
-
"] must be a string prefix or RegExp, got " + typeof skipPaths[sp]);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
+
// Path-exemption predicate (string-prefix or RegExp), validated at create().
|
|
502
|
+
var _shouldSkip = requestHelpers.makeSkipMatcher(opts, "middleware.rateLimit");
|
|
501
503
|
var scope = opts.scope || "global";
|
|
502
504
|
|
|
503
505
|
var backend = _resolveBackend(opts);
|
|
504
506
|
|
|
505
|
-
function _shouldSkip(req) {
|
|
506
|
-
var path = req.pathname || req.url || "/";
|
|
507
|
-
for (var i = 0; i < skipPaths.length; i++) {
|
|
508
|
-
if (typeof skipPaths[i] === "string" ? path.indexOf(skipPaths[i]) === 0 : skipPaths[i].test(path)) {
|
|
509
|
-
return true;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
return false;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
507
|
function _writeBlocked(req, res, k, verdict) {
|
|
516
508
|
if (emitHeaders && typeof res.setHeader === "function") {
|
|
517
509
|
res.setHeader(limitHeader, String(verdict.limit));
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// + /Schemas surfaces backed by operator-supplied CRUD callbacks.
|
|
5
5
|
|
|
6
6
|
var framework_error = require("../framework-error");
|
|
7
|
+
var pick = require("../pick");
|
|
7
8
|
var validateOpts = require("../validate-opts");
|
|
8
9
|
var safeJson = require("../safe-json");
|
|
9
10
|
var safeBuffer = require("../safe-buffer");
|
|
@@ -516,7 +517,7 @@ function _walkBulkIdRefs(value, out) {
|
|
|
516
517
|
if (value && typeof value === "object") {
|
|
517
518
|
var keys = Object.keys(value);
|
|
518
519
|
for (var k = 0; k < keys.length; k++) {
|
|
519
|
-
if (keys[k]
|
|
520
|
+
if (pick.isPoisonedKey(keys[k])) continue;
|
|
520
521
|
_walkBulkIdRefs(value[keys[k]], out);
|
|
521
522
|
}
|
|
522
523
|
}
|
|
@@ -753,7 +754,7 @@ function _resolveBulkIdRefs(value, bulkIdMap) {
|
|
|
753
754
|
var out = {};
|
|
754
755
|
var keys = Object.keys(value);
|
|
755
756
|
for (var k = 0; k < keys.length; k++) {
|
|
756
|
-
if (keys[k]
|
|
757
|
+
if (pick.isPoisonedKey(keys[k])) continue;
|
|
757
758
|
out[keys[k]] = _resolveBulkIdRefs(value[keys[k]], bulkIdMap);
|
|
758
759
|
}
|
|
759
760
|
return out;
|
|
@@ -151,7 +151,15 @@ var PP_POLICY_RE =
|
|
|
151
151
|
/^[a-z][a-z0-9-]*=(?:\*|\([^)]*\)|self)$/;
|
|
152
152
|
function _validatePermissionsPolicy(value) {
|
|
153
153
|
if (typeof value !== "string" || value.length === 0) return;
|
|
154
|
-
|
|
154
|
+
// Split on the literal comma, then strip whitespace adjacent to each comma —
|
|
155
|
+
// the semantics of /\s*,\s*/ without that pattern's O(n^2) backtracking on a
|
|
156
|
+
// long comma-less run of whitespace. trimStart/trimEnd use the same Unicode
|
|
157
|
+
// whitespace set as \s.
|
|
158
|
+
var parts = String(value).split(",");
|
|
159
|
+
for (var s = 0; s < parts.length; s += 1) {
|
|
160
|
+
if (s > 0) parts[s] = parts[s].trimStart();
|
|
161
|
+
if (s < parts.length - 1) parts[s] = parts[s].trimEnd();
|
|
162
|
+
}
|
|
155
163
|
for (var i = 0; i < parts.length; i += 1) {
|
|
156
164
|
var p = parts[i];
|
|
157
165
|
if (!p) continue;
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
var lazyRequire = require("../lazy-require");
|
|
29
29
|
var validateOpts = require("../validate-opts");
|
|
30
|
+
var denyResponse = require("./deny-response");
|
|
30
31
|
var { defineClass } = require("../framework-error");
|
|
31
32
|
|
|
32
33
|
var SecurityTxtError = defineClass("SecurityTxtError", { alwaysPermanent: true });
|
|
@@ -143,12 +144,7 @@ function create(opts) {
|
|
|
143
144
|
(alsoAtRoot && path === "/security.txt");
|
|
144
145
|
if (!matches) return next();
|
|
145
146
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
146
|
-
|
|
147
|
-
"Allow": "GET, HEAD",
|
|
148
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
149
|
-
"Content-Length": 18, // len of "Method Not Allowed"
|
|
150
|
-
});
|
|
151
|
-
res.end("Method Not Allowed");
|
|
147
|
+
denyResponse.methodNotAllowed(res, "GET, HEAD");
|
|
152
148
|
return;
|
|
153
149
|
}
|
|
154
150
|
res.writeHead(200, { // HTTP 200 status
|
|
@@ -150,10 +150,10 @@ function _parseChecksumHeader(headerValue, allowedSet) {
|
|
|
150
150
|
// alphabet); refuse those on the RAW value BEFORE the slice/trim
|
|
151
151
|
// normalisation (same v0.8.90 trim-before-validate bug class).
|
|
152
152
|
if (structuredFields.containsControlBytes(headerValue)) return { error: "malformed" };
|
|
153
|
-
var
|
|
154
|
-
if (
|
|
155
|
-
var algo =
|
|
156
|
-
var digestB64 =
|
|
153
|
+
var kvp = structuredFields.parseKeyValuePiece(headerValue, " ");
|
|
154
|
+
if (kvp.value === null) return { error: "malformed" };
|
|
155
|
+
var algo = kvp.key;
|
|
156
|
+
var digestB64 = kvp.value.trim();
|
|
157
157
|
if (algo.length === 0 || digestB64.length === 0) return { error: "malformed" };
|
|
158
158
|
if (!allowedSet[algo]) return { error: "algo-unsupported" };
|
|
159
159
|
if (!/^[A-Za-z0-9+/=]+$/.test(digestB64)) return { error: "malformed" };
|
|
@@ -311,19 +311,11 @@ function _emitTusBaseHeaders(res, extra) {
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
function _readChunk(req, maxChunkSize) {
|
|
314
|
-
return
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
sizeMessage: "PATCH body exceeded maxChunkSize",
|
|
320
|
-
});
|
|
321
|
-
req.on("data", function (c) {
|
|
322
|
-
try { collector.push(c); }
|
|
323
|
-
catch (e) { req.removeAllListeners("data"); reject(e); }
|
|
324
|
-
});
|
|
325
|
-
req.on("end", function () { resolve(collector.result()); });
|
|
326
|
-
req.on("error", function (e) { reject(e); });
|
|
314
|
+
return safeBuffer.collectStream(req, {
|
|
315
|
+
maxBytes: maxChunkSize,
|
|
316
|
+
errorClass: TusError,
|
|
317
|
+
sizeCode: "tus/chunk-too-large",
|
|
318
|
+
sizeMessage: "PATCH body exceeded maxChunkSize",
|
|
327
319
|
});
|
|
328
320
|
}
|
|
329
321
|
|
|
@@ -388,11 +380,8 @@ function create(opts) {
|
|
|
388
380
|
}
|
|
389
381
|
|
|
390
382
|
var store = opts.store;
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
throw new TusError("tus/bad-store",
|
|
394
|
-
"middleware.tusUpload: store must implement { create, head, append, terminate }");
|
|
395
|
-
}
|
|
383
|
+
validateOpts.requireMethods(store, ["create", "head", "append", "terminate"],
|
|
384
|
+
"middleware.tusUpload: store", TusError, "tus/bad-store");
|
|
396
385
|
|
|
397
386
|
var maxSize = opts.maxSize;
|
|
398
387
|
if (maxSize !== undefined && (typeof maxSize !== "number" || !isFinite(maxSize) || maxSize <= 0)) {
|
|
@@ -451,11 +440,7 @@ function create(opts) {
|
|
|
451
440
|
return new Date(rec.expireAt).toUTCString();
|
|
452
441
|
}
|
|
453
442
|
|
|
454
|
-
|
|
455
|
-
if (!auditOn) return;
|
|
456
|
-
try { observability().safeEvent("middleware.tusUpload." + verb, 1, {}); }
|
|
457
|
-
catch (_e) { /* drop-silent — observability sink */ }
|
|
458
|
-
}
|
|
443
|
+
var _emitMetric = observability().namespaced("middleware.tusUpload", auditOn);
|
|
459
444
|
|
|
460
445
|
async function _handleOptions(req, res) {
|
|
461
446
|
var headers = _emitTusBaseHeaders(res, {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
var lazyRequire = require("../lazy-require");
|
|
30
30
|
var safeJson = require("../safe-json");
|
|
31
31
|
var validateOpts = require("../validate-opts");
|
|
32
|
+
var denyResponse = require("./deny-response");
|
|
32
33
|
var { defineClass } = require("../framework-error");
|
|
33
34
|
|
|
34
35
|
var WebAppManifestError = defineClass("WebAppManifestError", { alwaysPermanent: true });
|
|
@@ -135,13 +136,7 @@ function create(opts) {
|
|
|
135
136
|
(alsoAtJsonPath && path === "/manifest.json");
|
|
136
137
|
if (!matches) return next();
|
|
137
138
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
138
|
-
|
|
139
|
-
res.writeHead(405, { // HTTP 405 status
|
|
140
|
-
"Allow": "GET, HEAD",
|
|
141
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
142
|
-
"Content-Length": Buffer.byteLength(bodyMsg),
|
|
143
|
-
});
|
|
144
|
-
res.end(bodyMsg);
|
|
139
|
+
denyResponse.methodNotAllowed(res, "GET, HEAD");
|
|
145
140
|
return;
|
|
146
141
|
}
|
|
147
142
|
res.writeHead(200, { // HTTP 200 status
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
41
|
var nodePath = require("node:path");
|
|
42
|
+
var moduleLoader = require("./module-loader");
|
|
42
43
|
var atomicFile = require("./atomic-file");
|
|
43
44
|
var dbSchema = require("./db-schema");
|
|
44
45
|
var frameworkSchema = require("./framework-schema");
|
|
@@ -269,21 +270,11 @@ function _resolveDb(opts) {
|
|
|
269
270
|
}
|
|
270
271
|
|
|
271
272
|
function _loadMigration(file, dir) {
|
|
272
|
-
var
|
|
273
|
-
|
|
274
|
-
// changes a migration file between calls picks up the new content.
|
|
275
|
-
// Production deployments would always restart the process, but this
|
|
276
|
-
// keeps test fixtures sane.
|
|
277
|
-
try { delete require.cache[require.resolve(fullPath)]; } catch (_e) { /* not yet cached */ }
|
|
278
|
-
var mod;
|
|
279
|
-
// Operator-supplied migration — dynamic by design, can't be bundle-
|
|
280
|
-
// traced. Host-CLI scope; deploying via SEA / pkg drops this surface.
|
|
281
|
-
try { mod = require(fullPath); } // allow:dynamic-require — operator-supplied migration
|
|
282
|
-
catch (e) {
|
|
283
|
-
throw new MigrationError("migrations/load-failed",
|
|
273
|
+
var mod = moduleLoader.requireFresh(nodePath.join(dir, file), function (e) {
|
|
274
|
+
return new MigrationError("migrations/load-failed",
|
|
284
275
|
"migration '" + file + "' failed to load: " + ((e && e.message) || String(e)),
|
|
285
276
|
true);
|
|
286
|
-
}
|
|
277
|
+
});
|
|
287
278
|
if (!mod || typeof mod.up !== "function") {
|
|
288
279
|
throw new MigrationError("migrations/missing-up",
|
|
289
280
|
"migration '" + file + "' must export an `up(db)` function", true);
|
|
@@ -37,32 +37,48 @@
|
|
|
37
37
|
* mdn: 1 MiB) so this module's hot-path doesn't add its own cap.
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
-
function
|
|
41
|
-
// RFC 5322 §2.2
|
|
42
|
-
//
|
|
43
|
-
// the
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
function classifyHeaderBlock(text) {
|
|
41
|
+
// RFC 5322 §2.2 — every line of a header section is either a header field
|
|
42
|
+
// (`name: value`), a folding continuation (leading WSP), or the empty line
|
|
43
|
+
// that ends the section. Anything else is MALFORMED — and a colon-less line
|
|
44
|
+
// sitting in the header section is the header-injection / SMTP-smuggling
|
|
45
|
+
// signal (attacker content on a bare line followed by an injected
|
|
46
|
+
// Bcc/To/From header). `fields` is the parsed headers (boundary-aware,
|
|
47
|
+
// continuation-unfolded); `malformed` is the injection/structure evidence the
|
|
48
|
+
// silent-skip parsers (email, mime, dsn, arc) all dropped on the floor.
|
|
49
|
+
var lines = String(text == null ? "" : text).split(/\r?\n/);
|
|
50
|
+
var unfolded = []; // [{ line, lineIndex }]
|
|
46
51
|
for (var i = 0; i < lines.length; i += 1) {
|
|
47
52
|
var line = lines[i];
|
|
48
|
-
if (line.length === 0) break;
|
|
53
|
+
if (line.length === 0) break; // header/body boundary
|
|
49
54
|
if ((line.charAt(0) === " " || line.charAt(0) === "\t") && unfolded.length > 0) {
|
|
50
|
-
unfolded[unfolded.length - 1] += " " + line.replace(/^\s+/, "");
|
|
55
|
+
unfolded[unfolded.length - 1].line += " " + line.replace(/^\s+/, "");
|
|
51
56
|
} else {
|
|
52
|
-
unfolded.push(line);
|
|
57
|
+
unfolded.push({ line: line, lineIndex: i });
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
|
-
var
|
|
60
|
+
var fields = [];
|
|
61
|
+
var malformed = [];
|
|
56
62
|
for (var j = 0; j < unfolded.length; j += 1) {
|
|
57
|
-
var
|
|
58
|
-
var colonAt =
|
|
59
|
-
if (colonAt === -1)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
var entry = unfolded[j];
|
|
64
|
+
var colonAt = entry.line.indexOf(":");
|
|
65
|
+
if (colonAt === -1) {
|
|
66
|
+
malformed.push({ lineIndex: entry.lineIndex, line: entry.line, reason: "no-colon" });
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
fields.push({
|
|
70
|
+
name: entry.line.slice(0, colonAt).trim(),
|
|
71
|
+
value: entry.line.slice(colonAt + 1).trim(),
|
|
63
72
|
});
|
|
64
73
|
}
|
|
65
|
-
return
|
|
74
|
+
return { fields: fields, malformed: malformed };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function parseHeaderBlock(text) {
|
|
78
|
+
// The fields view of the shared classifier — kept for every caller that only
|
|
79
|
+
// wants the parsed headers (the malformed lines are reached via
|
|
80
|
+
// classifyHeaderBlock for structure/injection validation).
|
|
81
|
+
return classifyHeaderBlock(text).fields;
|
|
66
82
|
}
|
|
67
83
|
|
|
68
84
|
function splitHeadersAndBody(text) {
|
|
@@ -189,6 +205,7 @@ function addressType(addr) {
|
|
|
189
205
|
|
|
190
206
|
module.exports = {
|
|
191
207
|
parseHeaderBlock: parseHeaderBlock,
|
|
208
|
+
classifyHeaderBlock: classifyHeaderBlock,
|
|
192
209
|
splitHeadersAndBody: splitHeadersAndBody,
|
|
193
210
|
findHeader: findHeader,
|
|
194
211
|
parseContentType: parseContentType,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* lib/module-loader.js — the single audited entry point for loading an
|
|
4
|
+
* operator-supplied module file (a migration or a seed) by path.
|
|
5
|
+
*
|
|
6
|
+
* Operator modules execute arbitrary code on `require`, so the dynamic
|
|
7
|
+
* `require()` lives here behind ONE `allow:dynamic-require` marker rather
|
|
8
|
+
* than scattered across every host-CLI loader (`b.migrations`,
|
|
9
|
+
* `b.seeders`, `b.externalDb.migrate`). The require cache is busted first
|
|
10
|
+
* so a dev / test rewriting a fixture between calls picks up the new
|
|
11
|
+
* content (production deployments restart the process). The dynamic
|
|
12
|
+
* require does not survive SEA / esbuild bundling — operator migrations
|
|
13
|
+
* and seeds are host-CLI scope, not framework-internal scope.
|
|
14
|
+
*
|
|
15
|
+
* The caller owns path construction (it knows its own directory layout)
|
|
16
|
+
* and the typed, domain-specific error it throws on a load failure
|
|
17
|
+
* (parse error, throwing top-level code), so resolution stays identical
|
|
18
|
+
* to the per-loader form it replaces.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* requireFresh(absPath, onLoadError) — bust the require cache for
|
|
23
|
+
* `absPath`, then require it fresh. `absPath` MUST be absolute (a bare
|
|
24
|
+
* relative path would resolve against node_modules, which is never an
|
|
25
|
+
* operator file). On a load failure, `onLoadError(err)` builds the
|
|
26
|
+
* caller's typed error, which is thrown.
|
|
27
|
+
*
|
|
28
|
+
* var mod = moduleLoader.requireFresh(path.join(dir, file), function (e) {
|
|
29
|
+
* return new MigrationError("migrations/load-failed",
|
|
30
|
+
* "migration '" + file + "' failed to load: " + ((e && e.message) || String(e)), true);
|
|
31
|
+
* });
|
|
32
|
+
*/
|
|
33
|
+
function requireFresh(absPath, onLoadError) {
|
|
34
|
+
try { delete require.cache[require.resolve(absPath)]; } catch (_e) { /* not yet cached */ }
|
|
35
|
+
try {
|
|
36
|
+
return require(absPath); // allow:dynamic-require — operator-supplied module (migration / seed)
|
|
37
|
+
} catch (e) {
|
|
38
|
+
throw onLoadError(e);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
requireFresh: requireFresh,
|
|
44
|
+
};
|