@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
|
@@ -114,7 +114,6 @@ var MailHeloError = defineClass("MailHeloError", { alwaysPermanent: true });
|
|
|
114
114
|
// trailing); §2.3.5 domain: dot-joined LDH labels; total ≤ 255 octets
|
|
115
115
|
// per RFC 1035 §2.3.4.
|
|
116
116
|
var LDH_LABEL_RE = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/; // allow:regex-no-length-cap — anchored + per-label repeat cap matches RFC 5321 §2.3.5
|
|
117
|
-
var ADDR_LIT_V4_RE = /^\[((?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})\]$/; // allow:regex-no-length-cap — anchored + per-octet repeat cap
|
|
118
117
|
var ADDR_LIT_V6_RE = /^\[IPv6:([0-9a-fA-F:.]+)\]$/; // allow:regex-no-length-cap — IPv6 textual bounded by overall maxBytes
|
|
119
118
|
|
|
120
119
|
var DEFAULT_MAX_BYTES = 255; // RFC 1035 §2.3.4 cap
|
|
@@ -201,7 +200,7 @@ var LOCALHOST_REFUSED = Object.freeze({
|
|
|
201
200
|
*/
|
|
202
201
|
async function evaluate(ctx, opts) {
|
|
203
202
|
opts = opts || {};
|
|
204
|
-
var profile =
|
|
203
|
+
var profile = gateContract.resolveProfileName(opts, COMPLIANCE_POSTURES, DEFAULT_PROFILE);
|
|
205
204
|
if (!PROFILES[profile]) {
|
|
206
205
|
throw new MailHeloError("mail-helo/bad-profile",
|
|
207
206
|
"evaluate: unknown profile '" + profile + "'");
|
|
@@ -233,7 +232,7 @@ async function evaluate(ctx, opts) {
|
|
|
233
232
|
}
|
|
234
233
|
|
|
235
234
|
// Classify shape: address-literal vs domain vs invalid.
|
|
236
|
-
var v4Lit = claimed.match(
|
|
235
|
+
var v4Lit = claimed.match(ipUtils.IPV4_ADDR_LITERAL_RE);
|
|
237
236
|
var v6Lit = claimed.match(ADDR_LIT_V6_RE);
|
|
238
237
|
if (v4Lit) {
|
|
239
238
|
if (v4Lit[1] !== ctx.ip) {
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
*/
|
|
70
70
|
|
|
71
71
|
var C = require("./constants");
|
|
72
|
+
var safeBuffer = require("./safe-buffer");
|
|
72
73
|
var validateOpts = require("./validate-opts");
|
|
73
74
|
var numericBounds = require("./numeric-bounds");
|
|
74
75
|
var safeJson = require("./safe-json");
|
|
@@ -265,7 +266,7 @@ function create(opts) {
|
|
|
265
266
|
throw new MailJournalError("mail-journal/bad-body",
|
|
266
267
|
"mail.journal.record: opts.bodyBytes must be a Buffer");
|
|
267
268
|
}
|
|
268
|
-
if (req.bodyBytes
|
|
269
|
+
if (safeBuffer.byteLengthOf(req.bodyBytes) > C.BYTES.mib(256)) { // per-message cap
|
|
269
270
|
throw new MailJournalError("mail-journal/too-large",
|
|
270
271
|
"mail.journal.record: message " + req.bodyBytes.length + " bytes exceeds 256 MiB cap");
|
|
271
272
|
}
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
var bCrypto = require("./crypto");
|
|
32
32
|
var lazyRequire = require("./lazy-require");
|
|
33
33
|
var mimeParse = require("./mime-parse");
|
|
34
|
+
var structuredFields = require("./structured-fields");
|
|
34
35
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
35
36
|
var C = require("./constants");
|
|
36
37
|
var validateOpts = require("./validate-opts");
|
|
@@ -84,9 +85,9 @@ function _parseDisposition(value) {
|
|
|
84
85
|
}
|
|
85
86
|
var modePart = value.slice(0, semi).trim();
|
|
86
87
|
var typePart = value.slice(semi + 1).trim();
|
|
87
|
-
var
|
|
88
|
-
var actionMode =
|
|
89
|
-
var sendingMode =
|
|
88
|
+
var mkv = structuredFields.parseKeyValuePiece(modePart, "/");
|
|
89
|
+
var actionMode = mkv.key;
|
|
90
|
+
var sendingMode = mkv.value === null ? null : mkv.value.trim().toLowerCase();
|
|
90
91
|
var type = typePart.toLowerCase();
|
|
91
92
|
// Strip /modifier off the type token.
|
|
92
93
|
var typeSlash = type.indexOf("/");
|
|
@@ -87,15 +87,12 @@ var { defineClass } = require("./framework-error");
|
|
|
87
87
|
var lazyRequire = require("./lazy-require");
|
|
88
88
|
var ipUtils = require("./ip-utils");
|
|
89
89
|
var gateContract = require("./gate-contract");
|
|
90
|
+
var codepointClass = require("./codepoint-class");
|
|
90
91
|
|
|
91
92
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
92
93
|
|
|
93
94
|
var MailRblError = defineClass("MailRblError", { alwaysPermanent: true });
|
|
94
95
|
|
|
95
|
-
var IPV4_RE = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/; // allow:regex-no-length-cap — anchored + per-octet repeat-cap
|
|
96
|
-
var IPV6_HEX_RE = /^[0-9a-fA-F:]+$/; // allow:regex-no-length-cap — checked by length cap below
|
|
97
|
-
var IPV6_MAX_LEN = 39; // max IPv6 textual length (8 groups × 4 hex + 7 colons)
|
|
98
|
-
|
|
99
96
|
var DEFAULT_TIMEOUT_MS = C.TIME.seconds(5);
|
|
100
97
|
var DEFAULT_CONCURRENCY = 8; // concurrent-query cap, not bytes
|
|
101
98
|
var DEFAULT_PROFILE = "strict";
|
|
@@ -142,7 +139,7 @@ function create(opts) {
|
|
|
142
139
|
throw new MailRblError("mail-rbl/bad-resolver",
|
|
143
140
|
"create: opts.resolver must be a b.network.dns.resolver.create() instance");
|
|
144
141
|
}
|
|
145
|
-
var profile =
|
|
142
|
+
var profile = gateContract.resolveProfileName(opts, COMPLIANCE_POSTURES, DEFAULT_PROFILE);
|
|
146
143
|
if (!PROFILES[profile]) {
|
|
147
144
|
throw new MailRblError("mail-rbl/bad-profile",
|
|
148
145
|
"create: unknown profile '" + profile + "'");
|
|
@@ -286,11 +283,11 @@ function reverseIp(ip) {
|
|
|
286
283
|
"reverseIp: ip must be a non-empty string");
|
|
287
284
|
}
|
|
288
285
|
// IPv4 first.
|
|
289
|
-
if (
|
|
286
|
+
if (ipUtils.isIPv4(ip)) {
|
|
290
287
|
return ip.split(".").reverse().join(".");
|
|
291
288
|
}
|
|
292
289
|
// IPv6 — accept canonical / compressed forms. Expand and nibble-reverse.
|
|
293
|
-
if (
|
|
290
|
+
if (!ipUtils.looksLikeIPv6Hex(ip)) {
|
|
294
291
|
throw new MailRblError("mail-rbl/bad-input",
|
|
295
292
|
"reverseIp: '" + ip + "' is not a valid IPv4 or IPv6 address");
|
|
296
293
|
}
|
|
@@ -336,7 +333,7 @@ function _validateZoneNames(zones) {
|
|
|
336
333
|
// if non-ASCII upstream).
|
|
337
334
|
for (var c = 0; c < z.length; c += 1) {
|
|
338
335
|
var cc = z.charCodeAt(c);
|
|
339
|
-
if (cc
|
|
336
|
+
if (codepointClass.isForbiddenControlChar(cc, { forbidTab: true }) || cc > 0x7e) { // RFC 1035 ASCII zone-name shape (printable ASCII only)
|
|
340
337
|
throw new MailRblError("mail-rbl/bad-zone",
|
|
341
338
|
"list zone '" + z + "' contains non-ASCII or control chars");
|
|
342
339
|
}
|
|
@@ -173,7 +173,7 @@ function create(opts) {
|
|
|
173
173
|
validateOpts.requireNonEmptyString(service, "mail.scan.create.service",
|
|
174
174
|
MailScanError, "mail-scan/bad-service");
|
|
175
175
|
}
|
|
176
|
-
var profile =
|
|
176
|
+
var profile = gateContract.resolveProfileName(opts, COMPLIANCE_POSTURES, DEFAULT_PROFILE);
|
|
177
177
|
if (!PROFILES[profile]) {
|
|
178
178
|
throw new MailScanError("mail-scan/bad-profile",
|
|
179
179
|
"mail.scan.create.profile: unknown '" + profile + "' (valid: strict / balanced / permissive)");
|
|
@@ -194,7 +194,7 @@ function create(opts) {
|
|
|
194
194
|
throw new MailScanError("mail-scan/bad-input",
|
|
195
195
|
"mail.scan.scan: messageBytes must be non-empty");
|
|
196
196
|
}
|
|
197
|
-
if (messageBytes
|
|
197
|
+
if (safeBuffer.byteLengthOf(messageBytes) > caps.maxMessageBytes) {
|
|
198
198
|
throw new MailScanError("mail-scan/oversize-message",
|
|
199
199
|
"mail.scan.scan: messageBytes=" + messageBytes.length + " exceeds maxMessageBytes=" +
|
|
200
200
|
caps.maxMessageBytes);
|
|
@@ -441,16 +441,32 @@ function create(opts) {
|
|
|
441
441
|
validateOpts(opts,
|
|
442
442
|
["hostname", "resolver", "policy", "retry", "dsn", "timeouts", "audit", "transportFactory", "port"],
|
|
443
443
|
"mail.send.deliver.create");
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
//
|
|
448
|
-
//
|
|
449
|
-
//
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
|
|
453
|
-
|
|
444
|
+
// hostname is required; opts.port (when present) must be a valid connect
|
|
445
|
+
// port. Submission/smarthost relays listen on 587 (RFC 6409) or
|
|
446
|
+
// implicit-TLS 465 (RFC 8314) rather than the IANA SMTP port 25
|
|
447
|
+
// (RFC 5321 §2.3.4) that direct MX delivery uses. Operators routing
|
|
448
|
+
// through such a relay set opts.port; the value is range-checked here
|
|
449
|
+
// (RFC 6335 §6) so a typo fails at config time, not on the first
|
|
450
|
+
// connect attempt.
|
|
451
|
+
// The shape is the authoritative, exhaustive opts contract: every key
|
|
452
|
+
// the factory accepts is declared here. hostname + port carry their
|
|
453
|
+
// final per-field codes; the sub-object opts (policy / retry / dsn /
|
|
454
|
+
// timeouts) are shape-checked only for object-ness here, with their
|
|
455
|
+
// field-level validation (and the distinct per-field codes operators
|
|
456
|
+
// see) applied below where each sub-object is resolved.
|
|
457
|
+
validateOpts.shape(opts, {
|
|
458
|
+
hostname: { rule: "required-string", code: "deliver/bad-hostname",
|
|
459
|
+
label: "mail.send.deliver.create: hostname (local HELO/EHLO + DSN Reporting-MTA)" },
|
|
460
|
+
port: { rule: "optional-port", code: "deliver/bad-port" },
|
|
461
|
+
resolver: { rule: "optional-plain-object", code: "deliver/bad-resolver",
|
|
462
|
+
label: "mail.send.deliver.create: resolver (b.network.dns.resolver handle)" },
|
|
463
|
+
policy: { rule: "optional-plain-object", code: "deliver/bad-policy" },
|
|
464
|
+
retry: { rule: "optional-plain-object", code: "deliver/bad-retry" },
|
|
465
|
+
dsn: { rule: "optional-plain-object", code: "deliver/bad-dsn" },
|
|
466
|
+
timeouts: { rule: "optional-plain-object", code: "deliver/bad-timeouts" },
|
|
467
|
+
audit: { rule: "optional-boolean", code: "deliver/bad-audit" },
|
|
468
|
+
transportFactory: { rule: "optional-function", code: "deliver/bad-transport-factory" },
|
|
469
|
+
}, "mail.send.deliver.create", DeliverError, "deliver/bad-opts");
|
|
454
470
|
var port = opts.port || DEFAULT_PORT_SMTP;
|
|
455
471
|
|
|
456
472
|
var policy = opts.policy || {};
|
|
@@ -480,10 +496,12 @@ function create(opts) {
|
|
|
480
496
|
|
|
481
497
|
var timeouts = opts.timeouts || {};
|
|
482
498
|
validateOpts(timeouts, ["mxLookupMs", "perHostMs"], "mail.send.deliver.create.timeouts");
|
|
483
|
-
validateOpts.
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
499
|
+
validateOpts.shape(timeouts, {
|
|
500
|
+
mxLookupMs: { rule: "optional-positive-int", code: "deliver/bad-timeout-mxLookupMs",
|
|
501
|
+
label: "mail.send.deliver.create.timeouts.mxLookupMs" },
|
|
502
|
+
perHostMs: { rule: "optional-positive-int", code: "deliver/bad-timeout-perHostMs",
|
|
503
|
+
label: "mail.send.deliver.create.timeouts.perHostMs" },
|
|
504
|
+
}, "mail.send.deliver.create.timeouts", DeliverError, "deliver/bad-timeouts");
|
|
487
505
|
var mxLookupTimeoutMs = timeouts.mxLookupMs !== undefined
|
|
488
506
|
? timeouts.mxLookupMs : DEFAULT_MX_LOOKUP_TIMEOUT_MS;
|
|
489
507
|
var perHostTimeoutMs = timeouts.perHostMs !== undefined
|
|
@@ -502,12 +520,7 @@ function create(opts) {
|
|
|
502
520
|
}
|
|
503
521
|
|
|
504
522
|
var auditEnabled = opts.audit !== false;
|
|
505
|
-
|
|
506
|
-
if (!auditEnabled) return;
|
|
507
|
-
try {
|
|
508
|
-
audit().safeEmit({ action: action, outcome: outcome, metadata: metadata || {} });
|
|
509
|
-
} catch (_e) { /* drop-silent — hot-path audit */ }
|
|
510
|
-
}
|
|
523
|
+
var _auditEmit = audit().namespaced(null, { audit: auditEnabled });
|
|
511
524
|
|
|
512
525
|
async function deliver(envelope) {
|
|
513
526
|
if (!envelope || typeof envelope !== "object") {
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
*/
|
|
118
118
|
|
|
119
119
|
var net = require("node:net");
|
|
120
|
-
var
|
|
120
|
+
var safeBuffer = require("./safe-buffer");
|
|
121
121
|
var C = require("./constants");
|
|
122
122
|
var bCrypto = require("./crypto");
|
|
123
123
|
var numericBounds = require("./numeric-bounds");
|
|
@@ -126,9 +126,10 @@ var guardImapCommand = require("./guard-imap-command");
|
|
|
126
126
|
var mailServerRateLimit = require("./mail-server-rate-limit");
|
|
127
127
|
var mailServerRegistry = require("./mail-server-registry");
|
|
128
128
|
var mailServerTls = require("./mail-server-tls");
|
|
129
|
+
var mailServerNet = require("./mail-server-net");
|
|
129
130
|
var { defineClass } = require("./framework-error");
|
|
130
131
|
|
|
131
|
-
var
|
|
132
|
+
var auditEmit = require("./audit-emit");
|
|
132
133
|
|
|
133
134
|
var MailServerImapError = defineClass("MailServerImapError", { alwaysPermanent: true });
|
|
134
135
|
|
|
@@ -138,6 +139,7 @@ var DEFAULT_IDLE_TIMEOUT_MS = C.TIME.minutes(30);
|
|
|
138
139
|
var IDLE_BANDWIDTH_TIMEOUT_MS = C.TIME.minutes(29); // RFC 2177 §3 — re-issue before 30
|
|
139
140
|
var DEFAULT_GREETING_VENDOR = "blamejs IMAP4rev2";
|
|
140
141
|
var pkgVersion = require("../package.json").version;
|
|
142
|
+
var codepointClass = require("./codepoint-class");
|
|
141
143
|
|
|
142
144
|
// Error-message clamp bytes — protocol-string clamp, not a byte count.
|
|
143
145
|
// Centralized so the marker lives in one place
|
|
@@ -196,10 +198,7 @@ function _parseImapDateTime(s) {
|
|
|
196
198
|
function _validateMailboxName(name, opts) {
|
|
197
199
|
if (typeof name !== "string" || name.length === 0) return false;
|
|
198
200
|
if (name.length > 1024) return false; // mailbox name cap
|
|
199
|
-
|
|
200
|
-
var c = name.charCodeAt(i);
|
|
201
|
-
if (c < 0x20 || c === 0x7F) return false; // control-byte refusal
|
|
202
|
-
}
|
|
201
|
+
if (codepointClass.firstControlCharOffset(name, { forbidTab: true }) !== -1) return false; // control-byte refusal
|
|
203
202
|
if (name.indexOf("..") !== -1) return false;
|
|
204
203
|
if (name === "/" || name[0] === "/" || name[name.length - 1] === "/") return false;
|
|
205
204
|
// Modified-UTF7 detection — RFC 3501 §5.1.3. Sequences are
|
|
@@ -275,40 +274,18 @@ function create(opts) {
|
|
|
275
274
|
var mailStore = opts.mailStore;
|
|
276
275
|
var allowLegacyMUtf7 = profile === "permissive";
|
|
277
276
|
|
|
278
|
-
var rateLimit;
|
|
279
|
-
if (opts.rateLimit === false) {
|
|
280
|
-
rateLimit = mailServerRateLimit.create({ disabled: true });
|
|
281
|
-
} else if (opts.rateLimit && typeof opts.rateLimit.admitConnection === "function") {
|
|
282
|
-
rateLimit = opts.rateLimit;
|
|
283
|
-
} else {
|
|
284
|
-
rateLimit = mailServerRateLimit.create(opts.rateLimit || {});
|
|
285
|
-
}
|
|
277
|
+
var rateLimit = mailServerRateLimit.resolve(opts.rateLimit);
|
|
286
278
|
|
|
287
|
-
var tcpServer = null;
|
|
288
|
-
var listening = false;
|
|
289
279
|
var connections = new Set();
|
|
290
280
|
|
|
291
|
-
|
|
292
|
-
try {
|
|
293
|
-
audit().safeEmit({
|
|
294
|
-
action: action,
|
|
295
|
-
outcome: outcome || "success",
|
|
296
|
-
metadata: metadata || {},
|
|
297
|
-
});
|
|
298
|
-
} catch (_e) { /* drop-silent — audit best-effort */ }
|
|
299
|
-
}
|
|
281
|
+
var _emit = auditEmit.emit;
|
|
300
282
|
|
|
301
283
|
function _handleConnection(rawSocket) {
|
|
302
|
-
var remoteAddress = rawSocket
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
try { rawSocket.write("* BAD Too many connections from your IP\r\n"); }
|
|
308
|
-
catch (_e) { /* socket may be down */ }
|
|
309
|
-
try { rawSocket.destroy(); } catch (_e2) { /* idempotent */ }
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
284
|
+
var remoteAddress = mailServerNet.admitConnection(rawSocket, rateLimit, _emit, {
|
|
285
|
+
refusedEvent: "mail.server.imap.rate_limit_refused",
|
|
286
|
+
refusalLine: "* BAD Too many connections from your IP\r\n",
|
|
287
|
+
});
|
|
288
|
+
if (remoteAddress === null) return;
|
|
312
289
|
rawSocket.once("close", function () { rateLimit.releaseConnection(remoteAddress); });
|
|
313
290
|
|
|
314
291
|
var connectionId = "imapconn-" + bCrypto.generateToken(8); // connection-id length
|
|
@@ -389,7 +366,7 @@ function create(opts) {
|
|
|
389
366
|
}
|
|
390
367
|
var crlf = state.lineBuffer.indexOf("\r\n");
|
|
391
368
|
if (crlf === -1) {
|
|
392
|
-
if (state.lineBuffer
|
|
369
|
+
if (safeBuffer.byteLengthOf(state.lineBuffer) > maxLineBytes) {
|
|
393
370
|
_writeUntagged(socket, "BAD Line too long (cap " + maxLineBytes + ")");
|
|
394
371
|
_close(socket, state);
|
|
395
372
|
}
|
|
@@ -932,20 +909,17 @@ function create(opts) {
|
|
|
932
909
|
// would let the post-TLS state machine resume an exchange that
|
|
933
910
|
// started in plaintext, conflating cleartext + TLS-protected
|
|
934
911
|
// phases of the same SASL run.
|
|
935
|
-
//
|
|
936
|
-
//
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
912
|
+
// The pre-handshake state-drain (lineBuffer + pendingLiteral +
|
|
913
|
+
// authPending), listener-removal, idle-timeout re-arm, and the
|
|
914
|
+
// post-handshake read-pump live in the shared upgradeLineProtocol
|
|
915
|
+
// helper (b.mail.server.tls.upgradeLineProtocol).
|
|
916
|
+
mailServerTls.upgradeLineProtocol({
|
|
917
|
+
state: state,
|
|
918
|
+
socket: socket,
|
|
942
919
|
secureContext: opts.tlsContext,
|
|
943
920
|
idleTimeoutMs: idleTimeoutMs,
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
state.lineBuffer = Buffer.concat([state.lineBuffer, chunk]);
|
|
947
|
-
_drainBuffer(state, tlsSocket);
|
|
948
|
-
},
|
|
921
|
+
clearFields: ["pendingLiteral", "authPending"],
|
|
922
|
+
drain: _drainBuffer,
|
|
949
923
|
onError: function (err) {
|
|
950
924
|
_emit("mail.server.imap.tls_handshake_failed",
|
|
951
925
|
{ connectionId: state.id, error: (err && err.message) || String(err) }, "failure");
|
|
@@ -1476,7 +1450,7 @@ function create(opts) {
|
|
|
1476
1450
|
if (q && typeof q.usedBytes === "number" &&
|
|
1477
1451
|
typeof q.capBytes === "number" &&
|
|
1478
1452
|
q.capBytes > 0 &&
|
|
1479
|
-
q.usedBytes + literalBody
|
|
1453
|
+
q.usedBytes + safeBuffer.byteLengthOf(literalBody) > q.capBytes) {
|
|
1480
1454
|
var err = new Error("APPEND would exceed quota (used " + q.usedBytes +
|
|
1481
1455
|
" + " + literalBody.length + " > cap " + q.capBytes + ")");
|
|
1482
1456
|
err.code = "mail-server-imap/overquota";
|
|
@@ -1812,44 +1786,15 @@ function create(opts) {
|
|
|
1812
1786
|
}
|
|
1813
1787
|
|
|
1814
1788
|
// ---- Lifecycle ----------------------------------------------------------
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
return new Promise(function (resolve, reject) {
|
|
1825
|
-
tcpServer.once("error", reject);
|
|
1826
|
-
tcpServer.listen(port, address, function () {
|
|
1827
|
-
listening = true;
|
|
1828
|
-
tcpServer.removeListener("error", reject);
|
|
1829
|
-
_emit("mail.server.imap.listening",
|
|
1830
|
-
{ port: port, address: address });
|
|
1831
|
-
resolve({ port: tcpServer.address().port, address: address });
|
|
1832
|
-
});
|
|
1833
|
-
});
|
|
1834
|
-
}
|
|
1835
|
-
|
|
1836
|
-
async function close() {
|
|
1837
|
-
if (!listening) return;
|
|
1838
|
-
listening = false;
|
|
1839
|
-
for (var s of connections) { try { s.destroy(); } catch (_e) { /* idempotent */ } }
|
|
1840
|
-
connections.clear();
|
|
1841
|
-
return new Promise(function (resolve) {
|
|
1842
|
-
tcpServer.close(function () {
|
|
1843
|
-
_emit("mail.server.imap.closed", {});
|
|
1844
|
-
resolve();
|
|
1845
|
-
});
|
|
1846
|
-
});
|
|
1847
|
-
}
|
|
1848
|
-
|
|
1849
|
-
return {
|
|
1850
|
-
listen: listen,
|
|
1851
|
-
close: close,
|
|
1852
|
-
};
|
|
1789
|
+
return mailServerNet.createStoreServer(net, {
|
|
1790
|
+
defaultPort: 143, // RFC 9051 IMAP port (IANA)
|
|
1791
|
+
handleConnection: _handleConnection,
|
|
1792
|
+
errorClass: MailServerImapError,
|
|
1793
|
+
errorCodePrefix: "mail-server-imap/",
|
|
1794
|
+
emit: _emit,
|
|
1795
|
+
connections: connections,
|
|
1796
|
+
eventBase: "mail.server.imap",
|
|
1797
|
+
});
|
|
1853
1798
|
}
|
|
1854
1799
|
|
|
1855
1800
|
module.exports = {
|
|
@@ -129,6 +129,7 @@ var mailServerRegistry = require("./mail-server-registry");
|
|
|
129
129
|
var { defineClass } = require("./framework-error");
|
|
130
130
|
|
|
131
131
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
132
|
+
var auditEmit = require("./audit-emit");
|
|
132
133
|
|
|
133
134
|
var MailServerJmapError = defineClass("MailServerJmapError", { alwaysPermanent: true });
|
|
134
135
|
|
|
@@ -232,15 +233,7 @@ function create(opts) {
|
|
|
232
233
|
});
|
|
233
234
|
var sessionState = bCrypto.generateToken(16); // opaque session-state token length
|
|
234
235
|
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
audit().safeEmit({
|
|
238
|
-
action: action,
|
|
239
|
-
outcome: outcome || "success",
|
|
240
|
-
metadata: metadata || {},
|
|
241
|
-
});
|
|
242
|
-
} catch (_e) { /* drop-silent — audit best-effort */ }
|
|
243
|
-
}
|
|
236
|
+
var _emit = auditEmit.emit;
|
|
244
237
|
|
|
245
238
|
// ---- Back-reference resolution (RFC 8620 §3.7) -------------------------
|
|
246
239
|
//
|
|
@@ -520,7 +513,10 @@ function create(opts) {
|
|
|
520
513
|
});
|
|
521
514
|
}
|
|
522
515
|
|
|
523
|
-
|
|
516
|
+
// _requireActor(req, res) — resolve the authenticated actor; on absence,
|
|
517
|
+
// write the RFC 8620 401 forbidden Problem-Details body and return null so
|
|
518
|
+
// the caller returns. Shared by every JMAP handler that gates on actor.
|
|
519
|
+
function _requireActor(req, res) {
|
|
524
520
|
var actor = req.user || (req.actor || null);
|
|
525
521
|
if (!actor) {
|
|
526
522
|
res.statusCode = 401;
|
|
@@ -529,8 +525,28 @@ function create(opts) {
|
|
|
529
525
|
type: "urn:ietf:params:jmap:error:forbidden",
|
|
530
526
|
description: "Authentication required",
|
|
531
527
|
}));
|
|
532
|
-
return;
|
|
528
|
+
return null;
|
|
533
529
|
}
|
|
530
|
+
return actor;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// _forEachQueryParam(query, fn) — split a raw URL query string on "&" and
|
|
534
|
+
// hand each non-empty pair to fn(rawKey, rawValue): the key is the text
|
|
535
|
+
// before the first "=", the value the remainder (both still
|
|
536
|
+
// percent-encoded — the caller decodes the slices it keeps).
|
|
537
|
+
function _forEachQueryParam(query, fn) {
|
|
538
|
+
query.split("&").forEach(function (pair) {
|
|
539
|
+
if (!pair) return;
|
|
540
|
+
var eq = pair.indexOf("=");
|
|
541
|
+
var k = eq === -1 ? pair : pair.slice(0, eq);
|
|
542
|
+
var v = eq === -1 ? "" : pair.slice(eq + 1);
|
|
543
|
+
fn(k, v);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function sessionHandler(req, res) {
|
|
548
|
+
var actor = _requireActor(req, res);
|
|
549
|
+
if (!actor) return;
|
|
534
550
|
Promise.resolve().then(function () { return opts.accountsFor(actor); })
|
|
535
551
|
.then(function (accountInfo) {
|
|
536
552
|
var info = accountInfo || { primaryAccounts: {}, accounts: {} };
|
|
@@ -592,16 +608,8 @@ function create(opts) {
|
|
|
592
608
|
// closeafter=no (default) — keep open until disconnect.
|
|
593
609
|
// ping=<seconds> — keepalive interval (default 30s, min 5s, max 900s).
|
|
594
610
|
function eventSourceHandler(req, res) {
|
|
595
|
-
var actor =
|
|
596
|
-
if (!actor)
|
|
597
|
-
res.statusCode = 401;
|
|
598
|
-
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
599
|
-
res.end(JSON.stringify({
|
|
600
|
-
type: "urn:ietf:params:jmap:error:forbidden",
|
|
601
|
-
description: "Authentication required",
|
|
602
|
-
}));
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
611
|
+
var actor = _requireActor(req, res);
|
|
612
|
+
if (!actor) return;
|
|
605
613
|
if (typeof opts.mailStore.subscribePush !== "function") {
|
|
606
614
|
res.statusCode = 503;
|
|
607
615
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
@@ -618,11 +626,7 @@ function create(opts) {
|
|
|
618
626
|
var qIdx = url.indexOf("?");
|
|
619
627
|
var query = qIdx === -1 ? "" : url.slice(qIdx + 1);
|
|
620
628
|
var params = Object.create(null);
|
|
621
|
-
query
|
|
622
|
-
if (!pair) return;
|
|
623
|
-
var eq = pair.indexOf("=");
|
|
624
|
-
var k = eq === -1 ? pair : pair.slice(0, eq);
|
|
625
|
-
var v = eq === -1 ? "" : pair.slice(eq + 1);
|
|
629
|
+
_forEachQueryParam(query, function (k, v) {
|
|
626
630
|
try { params[decodeURIComponent(k)] = decodeURIComponent(v); }
|
|
627
631
|
catch (_e) { /* drop-silent — malformed % encoding */ }
|
|
628
632
|
});
|
|
@@ -797,16 +801,8 @@ function create(opts) {
|
|
|
797
801
|
}
|
|
798
802
|
|
|
799
803
|
function uploadHandler(req, res) {
|
|
800
|
-
var actor =
|
|
801
|
-
if (!actor)
|
|
802
|
-
res.statusCode = 401;
|
|
803
|
-
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
804
|
-
res.end(JSON.stringify({
|
|
805
|
-
type: "urn:ietf:params:jmap:error:forbidden",
|
|
806
|
-
description: "Authentication required",
|
|
807
|
-
}));
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
804
|
+
var actor = _requireActor(req, res);
|
|
805
|
+
if (!actor) return;
|
|
810
806
|
if (typeof opts.mailStore.uploadBlob !== "function") {
|
|
811
807
|
res.statusCode = 503;
|
|
812
808
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
@@ -938,16 +934,8 @@ function create(opts) {
|
|
|
938
934
|
// shaped buffer (Buffer or async-iterable) + the canonical MIME
|
|
939
935
|
// type; the handler pipes it to the response.
|
|
940
936
|
function downloadHandler(req, res) {
|
|
941
|
-
var actor =
|
|
942
|
-
if (!actor)
|
|
943
|
-
res.statusCode = 401;
|
|
944
|
-
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
945
|
-
res.end(JSON.stringify({
|
|
946
|
-
type: "urn:ietf:params:jmap:error:forbidden",
|
|
947
|
-
description: "Authentication required",
|
|
948
|
-
}));
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
937
|
+
var actor = _requireActor(req, res);
|
|
938
|
+
if (!actor) return;
|
|
951
939
|
if (typeof opts.mailStore.downloadBlob !== "function") {
|
|
952
940
|
res.statusCode = 503;
|
|
953
941
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
@@ -970,11 +958,7 @@ function create(opts) {
|
|
|
970
958
|
var qIdx2 = rawUrl.indexOf("?");
|
|
971
959
|
var query = qIdx2 === -1 ? "" : rawUrl.slice(qIdx2 + 1);
|
|
972
960
|
var acceptType = "";
|
|
973
|
-
query
|
|
974
|
-
if (!pair) return;
|
|
975
|
-
var eq = pair.indexOf("=");
|
|
976
|
-
var k = eq === -1 ? pair : pair.slice(0, eq);
|
|
977
|
-
var v = eq === -1 ? "" : pair.slice(eq + 1);
|
|
961
|
+
_forEachQueryParam(query, function (k, v) {
|
|
978
962
|
if (k === "accept") {
|
|
979
963
|
try { acceptType = decodeURIComponent(v); } catch (_e) { /* silent-catch: malformed % encoding */ }
|
|
980
964
|
}
|