@blamejs/core 0.15.12 → 0.15.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/index.js +2 -0
- package/lib/a2a-tasks.js +45 -29
- package/lib/acme.js +6 -5
- package/lib/agent-event-bus.js +18 -4
- package/lib/agent-idempotency.js +7 -6
- package/lib/agent-orchestrator.js +2 -5
- package/lib/agent-saga.js +3 -5
- package/lib/agent-snapshot.js +32 -2
- package/lib/agent-tenant.js +2 -5
- package/lib/ai-adverse-decision.js +2 -15
- package/lib/ai-aedt-bias-audit.js +2 -1
- package/lib/ai-capability.js +1 -6
- package/lib/ai-content-detect.js +1 -3
- package/lib/ai-dp.js +1 -5
- package/lib/ai-frontier-protocol.js +1 -1
- package/lib/ai-input.js +2 -2
- package/lib/ai-model-manifest.js +1 -1
- package/lib/ai-output.js +16 -7
- package/lib/ai-pref.js +3 -8
- package/lib/ai-quota.js +3 -14
- package/lib/api-key.js +37 -28
- package/lib/api-snapshot.js +4 -1
- package/lib/app-shutdown.js +7 -1
- package/lib/archive-adapters.js +2 -4
- package/lib/archive-entry-policy.js +32 -0
- package/lib/archive-gz.js +9 -0
- package/lib/archive-read.js +14 -24
- package/lib/archive-tar-read.js +56 -24
- package/lib/archive.js +6 -12
- package/lib/arg-parser.js +7 -6
- package/lib/asn1-der.js +70 -22
- package/lib/asyncapi-traits.js +2 -6
- package/lib/atomic-file.js +312 -33
- package/lib/audit-chain.js +183 -54
- package/lib/audit-daily-review.js +36 -16
- package/lib/audit-emit.js +82 -0
- package/lib/audit-sign.js +258 -0
- package/lib/audit-tools.js +108 -23
- package/lib/audit.js +91 -2
- package/lib/auth/access-lock.js +7 -29
- package/lib/auth/bot-challenge.js +1 -1
- package/lib/auth/ciba.js +43 -4
- package/lib/auth/dpop.js +29 -36
- package/lib/auth/fido-mds3.js +14 -16
- package/lib/auth/jwt-external.js +26 -8
- package/lib/auth/jwt.js +15 -17
- package/lib/auth/lockout.js +24 -27
- package/lib/auth/oauth.js +67 -45
- package/lib/auth/oid4vci.js +55 -32
- package/lib/auth/oid4vp.js +3 -2
- package/lib/auth/openid-federation.js +6 -6
- package/lib/auth/passkey.js +4 -4
- package/lib/auth/password.js +8 -2
- package/lib/auth/saml.js +70 -40
- package/lib/auth/sd-jwt-vc-holder.js +2 -14
- package/lib/auth/sd-jwt-vc-issuer.js +2 -14
- package/lib/auth/sd-jwt-vc.js +25 -5
- package/lib/auth/status-list.js +21 -9
- package/lib/auth/step-up.js +15 -13
- package/lib/auth-bot-challenge.js +27 -39
- package/lib/backup/bundle.js +18 -20
- package/lib/backup/crypto.js +23 -8
- package/lib/backup/index.js +55 -67
- package/lib/backup/manifest.js +7 -1
- package/lib/bounded-map.js +112 -1
- package/lib/breach-deadline.js +1 -11
- package/lib/break-glass.js +41 -22
- package/lib/cache.js +7 -18
- package/lib/cbor.js +36 -12
- package/lib/cdn-cache-control.js +15 -12
- package/lib/cert.js +8 -13
- package/lib/chain-writer.js +162 -47
- package/lib/cli.js +10 -2
- package/lib/client-hints.js +7 -9
- package/lib/cloud-events.js +43 -33
- package/lib/cluster-storage.js +9 -41
- package/lib/cms-codec.js +2 -1
- package/lib/codepoint-class.js +84 -1
- package/lib/compliance-ai-act-logging.js +1 -6
- package/lib/compliance-ai-act-transparency.js +2 -4
- package/lib/compliance-eaa.js +2 -12
- package/lib/compliance-sanctions-fetcher.js +21 -28
- package/lib/compliance-sanctions.js +11 -21
- package/lib/compliance.js +3 -10
- package/lib/config-drift.js +24 -20
- package/lib/content-credentials.js +11 -8
- package/lib/content-digest.js +21 -12
- package/lib/cookies.js +15 -13
- package/lib/cose.js +39 -11
- package/lib/cra-report.js +1 -11
- package/lib/crdt.js +2 -1
- package/lib/crypto-field.js +34 -33
- package/lib/crypto.js +138 -7
- package/lib/csp.js +239 -3
- package/lib/daemon.js +46 -42
- package/lib/data-act.js +46 -13
- package/lib/db-file-lifecycle.js +14 -6
- package/lib/db-query.js +75 -49
- package/lib/db.js +66 -27
- package/lib/dbsc.js +5 -6
- package/lib/ddl-change-control.js +18 -14
- package/lib/deprecate.js +4 -5
- package/lib/did.js +6 -2
- package/lib/dora.js +43 -13
- package/lib/dr-runbook.js +1 -1
- package/lib/dsa.js +2 -1
- package/lib/dsr.js +30 -20
- package/lib/early-hints.js +19 -0
- package/lib/eat.js +5 -1
- package/lib/external-db-migrate.js +21 -22
- package/lib/external-db.js +74 -30
- package/lib/fda-21cfr11.js +42 -13
- package/lib/fdx.js +22 -18
- package/lib/file-upload.js +80 -66
- package/lib/flag-evaluation-context.js +5 -8
- package/lib/flag-providers.js +6 -2
- package/lib/forms.js +1 -1
- package/lib/framework-error.js +12 -0
- package/lib/framework-schema.js +19 -0
- package/lib/fsm.js +7 -12
- package/lib/gate-contract.js +911 -39
- package/lib/gdpr-ropa.js +22 -22
- package/lib/graphql-federation.js +18 -5
- package/lib/guard-agent-registry.js +2 -1
- package/lib/guard-all.js +3 -2
- package/lib/guard-archive.js +9 -30
- package/lib/guard-auth.js +23 -80
- package/lib/guard-cidr.js +20 -96
- package/lib/guard-csv.js +135 -196
- package/lib/guard-domain.js +23 -106
- package/lib/guard-dsn.js +17 -14
- package/lib/guard-email.js +46 -53
- package/lib/guard-envelope.js +2 -2
- package/lib/guard-event-bus-topic.js +2 -1
- package/lib/guard-filename.js +12 -60
- package/lib/guard-graphql.js +28 -75
- package/lib/guard-html-wcag.js +15 -2
- package/lib/guard-html.js +74 -128
- package/lib/guard-idempotency-key.js +2 -1
- package/lib/guard-image.js +280 -77
- package/lib/guard-imap-command.js +9 -10
- package/lib/guard-jmap.js +1 -1
- package/lib/guard-json.js +101 -109
- package/lib/guard-jsonpath.js +20 -88
- package/lib/guard-jwt.js +32 -114
- package/lib/guard-list-id.js +2 -7
- package/lib/guard-list-unsubscribe.js +2 -7
- package/lib/guard-mail-compose.js +5 -6
- package/lib/guard-mail-move.js +3 -2
- package/lib/guard-mail-query.js +5 -3
- package/lib/guard-mail-sieve.js +6 -7
- package/lib/guard-managesieve-command.js +6 -5
- package/lib/guard-markdown.js +76 -110
- package/lib/guard-message-id.js +5 -6
- package/lib/guard-mime.js +20 -99
- package/lib/guard-oauth.js +19 -73
- package/lib/guard-pdf.js +65 -72
- package/lib/guard-pop3-command.js +13 -14
- package/lib/guard-posture-chain.js +2 -1
- package/lib/guard-regex.js +24 -99
- package/lib/guard-saga-config.js +2 -1
- package/lib/guard-shell.js +22 -87
- package/lib/guard-smtp-command.js +9 -12
- package/lib/guard-sql.js +15 -13
- package/lib/guard-stream-args.js +2 -1
- package/lib/guard-svg.js +103 -149
- package/lib/guard-template.js +23 -80
- package/lib/guard-tenant-id.js +2 -1
- package/lib/guard-text.js +592 -0
- package/lib/guard-time.js +27 -95
- package/lib/guard-uuid.js +21 -93
- package/lib/guard-xml.js +76 -106
- package/lib/guard-yaml.js +24 -60
- package/lib/html-balance.js +7 -3
- package/lib/http-client-cache.js +5 -12
- package/lib/http-client-cookie-jar.js +35 -16
- package/lib/http-client.js +233 -74
- package/lib/http-message-signature.js +3 -2
- package/lib/i18n-messageformat.js +5 -7
- package/lib/i18n.js +83 -26
- package/lib/iab-tcf.js +3 -2
- package/lib/importmap-integrity.js +41 -1
- package/lib/inbox.js +8 -8
- package/lib/incident-report.js +12 -27
- package/lib/ip-utils.js +49 -6
- package/lib/jobs.js +3 -2
- package/lib/json-patch.js +1 -1
- package/lib/json-path.js +24 -3
- package/lib/jtd.js +2 -2
- package/lib/keychain.js +6 -18
- package/lib/legal-hold.js +30 -23
- package/lib/log-stream-cloudwatch.js +44 -112
- package/lib/log-stream-otlp-grpc.js +17 -14
- package/lib/log-stream-otlp.js +16 -80
- package/lib/log-stream-webhook.js +20 -92
- package/lib/log.js +2 -2
- package/lib/mail-agent.js +2 -2
- package/lib/mail-arc-sign.js +8 -3
- package/lib/mail-arf.js +4 -3
- package/lib/mail-auth.js +43 -69
- package/lib/mail-bimi.js +35 -55
- package/lib/mail-bounce.js +3 -3
- package/lib/mail-crypto-pgp.js +3 -2
- package/lib/mail-crypto-smime.js +71 -6
- package/lib/mail-dav.js +8 -35
- package/lib/mail-deploy.js +15 -14
- package/lib/mail-dkim.js +19 -38
- package/lib/mail-greylist.js +17 -30
- package/lib/mail-helo.js +4 -7
- package/lib/mail-journal.js +13 -9
- package/lib/mail-mdn.js +12 -7
- package/lib/mail-rbl.js +7 -12
- package/lib/mail-scan.js +5 -7
- package/lib/mail-send-deliver.js +33 -20
- package/lib/mail-server-imap.js +32 -87
- package/lib/mail-server-jmap.js +39 -52
- package/lib/mail-server-managesieve.js +29 -83
- package/lib/mail-server-mx.js +33 -74
- package/lib/mail-server-net.js +177 -0
- package/lib/mail-server-pop3.js +30 -83
- package/lib/mail-server-rate-limit.js +30 -6
- package/lib/mail-server-registry.js +1 -1
- package/lib/mail-server-submission.js +34 -73
- package/lib/mail-server-tls.js +98 -2
- package/lib/mail-spam-score.js +9 -12
- package/lib/mail-store-fts.js +1 -1
- package/lib/mail-store.js +3 -2
- package/lib/mail.js +28 -13
- package/lib/markup-escape.js +31 -0
- package/lib/markup-tokenizer.js +78 -0
- package/lib/mcp-tool-registry.js +26 -23
- package/lib/mcp.js +7 -5
- package/lib/mdoc.js +36 -14
- package/lib/metrics.js +46 -33
- package/lib/middleware/age-gate.js +3 -23
- package/lib/middleware/api-encrypt.js +13 -24
- package/lib/middleware/assetlinks.js +2 -7
- package/lib/middleware/bearer-auth.js +2 -1
- package/lib/middleware/body-parser.js +41 -52
- package/lib/middleware/bot-disclose.js +7 -10
- package/lib/middleware/bot-guard.js +28 -28
- package/lib/middleware/clear-site-data.js +5 -1
- package/lib/middleware/compression.js +9 -0
- package/lib/middleware/cors.js +32 -23
- package/lib/middleware/csrf-protect.js +73 -23
- package/lib/middleware/daily-byte-quota.js +12 -30
- package/lib/middleware/deny-response.js +19 -1
- package/lib/middleware/fetch-metadata.js +35 -4
- package/lib/middleware/idempotency-key.js +4 -20
- package/lib/middleware/network-allowlist.js +61 -30
- package/lib/middleware/rate-limit.js +45 -44
- package/lib/middleware/scim-server.js +5 -3
- package/lib/middleware/security-headers.js +33 -7
- package/lib/middleware/security-txt.js +2 -6
- package/lib/middleware/speculation-rules.js +6 -3
- package/lib/middleware/tus-upload.js +14 -29
- package/lib/middleware/web-app-manifest.js +2 -7
- package/lib/migrations.js +4 -13
- package/lib/mime-parse.js +34 -17
- package/lib/module-loader.js +44 -0
- package/lib/money.js +105 -0
- package/lib/mtls-ca.js +125 -41
- package/lib/network-byte-quota.js +4 -18
- package/lib/network-dane.js +8 -6
- package/lib/network-dns-resolver.js +98 -7
- package/lib/network-dns.js +9 -2
- package/lib/network-dnssec.js +18 -17
- package/lib/network-heartbeat.js +3 -2
- package/lib/network-smtp-policy.js +52 -46
- package/lib/network-tls.js +67 -47
- package/lib/network-tsig.js +2 -2
- package/lib/nis2-report.js +2 -12
- package/lib/nist-crosswalk.js +1 -1
- package/lib/nonce-store.js +81 -3
- package/lib/ntp-check.js +28 -0
- package/lib/numeric-bounds.js +31 -8
- package/lib/object-store/azure-blob-bucket-ops.js +2 -6
- package/lib/object-store/azure-blob.js +6 -47
- package/lib/object-store/gcs-bucket-ops.js +4 -2
- package/lib/object-store/gcs.js +14 -75
- package/lib/object-store/http-put.js +2 -7
- package/lib/object-store/http-request.js +157 -0
- package/lib/object-store/local.js +37 -17
- package/lib/object-store/sigv4-bucket-ops.js +2 -1
- package/lib/object-store/sigv4.js +10 -79
- package/lib/observability-otlp-exporter.js +29 -29
- package/lib/observability.js +95 -0
- package/lib/openapi-paths-builder.js +7 -3
- package/lib/otel-export.js +7 -10
- package/lib/outbox.js +54 -41
- package/lib/pagination.js +11 -15
- package/lib/parsers/safe-env.js +5 -4
- package/lib/parsers/safe-ini.js +10 -4
- package/lib/parsers/safe-toml.js +11 -9
- package/lib/parsers/safe-xml.js +3 -3
- package/lib/parsers/safe-yaml.js +28 -9
- package/lib/pick.js +63 -5
- package/lib/pipl-cn.js +69 -59
- package/lib/privacy-pass.js +8 -6
- package/lib/problem-details.js +2 -5
- package/lib/pubsub.js +4 -8
- package/lib/queue-local.js +10 -3
- package/lib/redact.js +9 -4
- package/lib/render.js +4 -2
- package/lib/request-helpers.js +334 -29
- package/lib/resource-access-lock.js +3 -3
- package/lib/restore-bundle.js +46 -18
- package/lib/restore-rollback.js +10 -4
- package/lib/restore.js +24 -22
- package/lib/retention.js +23 -9
- package/lib/router.js +17 -4
- package/lib/safe-async.js +457 -0
- package/lib/safe-buffer.js +137 -6
- package/lib/safe-decompress.js +2 -1
- package/lib/safe-dns.js +2 -1
- package/lib/safe-ical.js +14 -28
- package/lib/safe-icap.js +1 -1
- package/lib/safe-json.js +51 -8
- package/lib/safe-jsonpath.js +6 -5
- package/lib/safe-mime.js +25 -29
- package/lib/safe-redirect.js +2 -5
- package/lib/safe-schema.js +7 -6
- package/lib/safe-sieve.js +1 -1
- package/lib/safe-sql.js +126 -0
- package/lib/safe-vcard.js +13 -27
- package/lib/sandbox-worker.js +15 -2
- package/lib/sandbox.js +4 -3
- package/lib/scheduler.js +22 -13
- package/lib/sec-cyber.js +82 -37
- package/lib/seeders.js +4 -11
- package/lib/self-update-standalone-verifier.js +16 -0
- package/lib/self-update.js +92 -69
- package/lib/session-device-binding.js +112 -66
- package/lib/session.js +219 -7
- package/lib/sql.js +228 -81
- package/lib/sse.js +6 -10
- package/lib/static.js +201 -111
- package/lib/storage.js +4 -2
- package/lib/structured-fields.js +275 -16
- package/lib/template.js +7 -5
- package/lib/tenant-quota.js +53 -38
- package/lib/tsa.js +16 -17
- package/lib/validate-opts.js +154 -8
- package/lib/vault/index.js +5 -0
- package/lib/vault/passphrase-ops.js +22 -26
- package/lib/vault/passphrase-source.js +8 -3
- package/lib/vault/rotate.js +13 -18
- package/lib/vault/seal-pem-file.js +34 -49
- package/lib/vault-aad.js +3 -2
- package/lib/vc.js +3 -8
- package/lib/vendor/MANIFEST.json +10 -10
- package/lib/vendor/public-suffix-list.dat +23 -10
- package/lib/vendor/public-suffix-list.data.js +5498 -5494
- package/lib/vex.js +35 -13
- package/lib/web-push-vapid.js +23 -20
- package/lib/webhook-dispatcher.js +706 -0
- package/lib/webhook.js +59 -19
- package/lib/websocket-channels.js +9 -7
- package/lib/websocket.js +8 -4
- package/lib/worm.js +3 -4
- package/lib/ws-client.js +65 -56
- package/lib/x509-chain.js +44 -0
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/file-upload.js
CHANGED
|
@@ -259,73 +259,87 @@ function _validateUploadId(id) {
|
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
function _validateCreateOpts(opts) {
|
|
262
|
-
validateOpts.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
"
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
(
|
|
290
|
-
|
|
291
|
-
"fileUpload.create: allowedFileTypes is set but fileType primitive is not wired " +
|
|
292
|
-
"(pass fileType: b.fileType so the framework can sniff magic bytes at finalize)");
|
|
293
|
-
}
|
|
294
|
-
// permissions — when set, must expose check(actor, scope) → boolean.
|
|
295
|
-
validateOpts.optionalObjectWithMethod(opts.permissions, "check",
|
|
296
|
-
"fileUpload.create: permissions", FileUploadError, "BAD_OPT",
|
|
297
|
-
"must be a b.permissions instance (check fn)");
|
|
298
|
-
// contentSafety — extension-keyed gate map for per-extension content
|
|
299
|
-
// validation. Default behaviour: when undefined, the framework wires
|
|
300
|
-
// b.guardAll.byExtension({ profile: "strict" }) automatically so every
|
|
301
|
-
// shipped guard is ON by default. Explicit opt-out: contentSafety:
|
|
302
|
-
// null (audited at create() time so a security review can reconstruct
|
|
303
|
-
// which deploys disabled the default-on protection).
|
|
304
|
-
// Example: contentSafety: { ".csv": b.guardCsv.gate({ profile: "strict" }) }
|
|
305
|
-
if (opts.contentSafety !== undefined && opts.contentSafety !== null) {
|
|
306
|
-
validateOpts.optionalPlainObject(opts.contentSafety,
|
|
307
|
-
"fileUpload.create: contentSafety", FileUploadError, "BAD_OPT",
|
|
308
|
-
"must be a plain { ext: gate } object, null to opt out, or " +
|
|
309
|
-
"undefined for the default-on b.guardAll wiring");
|
|
310
|
-
var safetyKeys = Object.keys(opts.contentSafety);
|
|
311
|
-
for (var sk = 0; sk < safetyKeys.length; sk++) {
|
|
312
|
-
var ext = safetyKeys[sk];
|
|
313
|
-
var g = opts.contentSafety[ext];
|
|
314
|
-
if (!g || typeof g.check !== "function") {
|
|
262
|
+
validateOpts.shape(opts, {
|
|
263
|
+
stagingDir: function (v, label) {
|
|
264
|
+
validateOpts.requireNonEmptyString(v, label, FileUploadError);
|
|
265
|
+
if (!nodePath.isAbsolute(v)) {
|
|
266
|
+
throw _err("BAD_OPT", "fileUpload.create: stagingDir must be an absolute path, got " +
|
|
267
|
+
JSON.stringify(v));
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
onFinalize: "optional-function",
|
|
271
|
+
onChunk: "optional-function",
|
|
272
|
+
// Byte / count caps — finite positive ints; TTL/idle windows allow 0.
|
|
273
|
+
maxFileBytes: "optional-positive-finite-int",
|
|
274
|
+
maxChunkBytes: "optional-positive-finite-int",
|
|
275
|
+
maxStreamReassemblyBytes: "optional-positive-finite-int",
|
|
276
|
+
maxStagingBytes: "optional-positive-finite-int",
|
|
277
|
+
maxActiveUploadsPerActor: "optional-positive-finite-int",
|
|
278
|
+
maxChunks: "optional-positive-finite-int",
|
|
279
|
+
incompleteTtlMs: "optional-non-negative-finite-int",
|
|
280
|
+
maxIdleMs: "optional-non-negative-finite-int",
|
|
281
|
+
audit: function (v) { validateOpts.auditShape(v, "fileUpload.create", FileUploadError); },
|
|
282
|
+
observability: function (v) { validateOpts.observabilityShape(v, "fileUpload.create", FileUploadError); },
|
|
283
|
+
clock: "optional-function",
|
|
284
|
+
// allowedFileTypes — operator's MIME allowlist. Empty / undefined
|
|
285
|
+
// disables the gate. Setting it without wiring a fileType primitive
|
|
286
|
+
// is a misconfig — the gate would have nothing to enforce against.
|
|
287
|
+
allowedFileTypes: function (v, label) {
|
|
288
|
+
validateOpts.optionalNonEmptyStringArray(v, label, FileUploadError, "BAD_OPT");
|
|
289
|
+
if (Array.isArray(v) && v.length > 0 &&
|
|
290
|
+
(!opts.fileType || typeof opts.fileType.detect !== "function")) {
|
|
315
291
|
throw _err("BAD_OPT",
|
|
316
|
-
"fileUpload.create:
|
|
317
|
-
"
|
|
292
|
+
"fileUpload.create: allowedFileTypes is set but fileType primitive is not wired " +
|
|
293
|
+
"(pass fileType: b.fileType so the framework can sniff magic bytes at finalize)");
|
|
318
294
|
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
295
|
+
},
|
|
296
|
+
// permissions — when set, must expose check(actor, scope) → boolean.
|
|
297
|
+
permissions: function (v, label) {
|
|
298
|
+
validateOpts.optionalObjectWithMethod(v, "check", label, FileUploadError, "BAD_OPT",
|
|
299
|
+
"must be a b.permissions instance (check fn)");
|
|
300
|
+
},
|
|
301
|
+
// contentSafety — extension-keyed gate map for per-extension content
|
|
302
|
+
// validation. Default behaviour: when undefined, the framework wires
|
|
303
|
+
// b.guardAll.byExtension({ profile: "strict" }) automatically so every
|
|
304
|
+
// shipped guard is ON by default. Explicit opt-out: contentSafety:
|
|
305
|
+
// null (audited at create() time so a security review can reconstruct
|
|
306
|
+
// which deploys disabled the default-on protection).
|
|
307
|
+
// Example: contentSafety: { ".csv": b.guardCsv.gate({ profile: "strict" }) }
|
|
308
|
+
contentSafety: function (v, label) {
|
|
309
|
+
if (v === undefined || v === null) return;
|
|
310
|
+
validateOpts.optionalPlainObject(v, label, FileUploadError, "BAD_OPT",
|
|
311
|
+
"must be a plain { ext: gate } object, null to opt out, or " +
|
|
312
|
+
"undefined for the default-on b.guardAll wiring");
|
|
313
|
+
var safetyKeys = Object.keys(v);
|
|
314
|
+
for (var sk = 0; sk < safetyKeys.length; sk++) {
|
|
315
|
+
var ext = safetyKeys[sk];
|
|
316
|
+
var g = v[ext];
|
|
317
|
+
if (!g || typeof g.check !== "function") {
|
|
318
|
+
throw _err("BAD_OPT",
|
|
319
|
+
"fileUpload.create: contentSafety[" + JSON.stringify(ext) +
|
|
320
|
+
"] must be a gate (b.guardCsv.gate / b.guardHtml.gate / etc.)");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
// filenameSafety — single gate for filename validation. Default: on.
|
|
325
|
+
// Operator opts out with filenameSafety: null (audited).
|
|
326
|
+
filenameSafety: function (v, label) {
|
|
327
|
+
if (v === undefined || v === null) return;
|
|
328
|
+
validateOpts.optionalObjectWithMethod(v, "check", label, FileUploadError, "BAD_OPT",
|
|
329
|
+
"must be a gate (b.guardFilename.gate(...)), null to opt out, or " +
|
|
330
|
+
"undefined for the default-on wiring");
|
|
331
|
+
},
|
|
332
|
+
// fileType — magic-byte sniffer (b.fileType) consumed at finalize when
|
|
333
|
+
// allowedFileTypes is set; validated here so it can't be passed un-typed.
|
|
334
|
+
fileType: function (v, label) {
|
|
335
|
+
if (v === undefined || v === null) return;
|
|
336
|
+
validateOpts.optionalObjectWithMethod(v, "detect", label, FileUploadError, "BAD_OPT",
|
|
337
|
+
"must be a b.fileType instance (detect fn)");
|
|
338
|
+
},
|
|
339
|
+
// Reason strings recorded when a default-on safety is explicitly disabled.
|
|
340
|
+
contentSafetyDisabledReason: "optional-string",
|
|
341
|
+
filenameSafetyDisabledReason: "optional-string",
|
|
342
|
+
}, "fileUpload.create", FileUploadError, "BAD_OPT", { exhaustive: true });
|
|
329
343
|
}
|
|
330
344
|
|
|
331
345
|
/**
|
|
@@ -698,7 +712,7 @@ function create(opts) {
|
|
|
698
712
|
throw _err("EMPTY_CHUNK",
|
|
699
713
|
"fileUpload.acceptChunk: body is empty (0 bytes)");
|
|
700
714
|
}
|
|
701
|
-
if (body
|
|
715
|
+
if (safeBuffer.byteLengthOf(body) > maxChunkBytes) {
|
|
702
716
|
_emitObs("fileUpload.chunk_too_large", 1);
|
|
703
717
|
throw _err("CHUNK_TOO_LARGE",
|
|
704
718
|
"fileUpload.acceptChunk: chunk body is " + body.length +
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
var nodeCrypto = require("node:crypto");
|
|
20
|
+
var pick = require("./pick");
|
|
20
21
|
var validateOpts = require("./validate-opts");
|
|
21
22
|
var lazyRequire = require("./lazy-require");
|
|
22
23
|
var { defineClass } = require("./framework-error");
|
|
@@ -33,7 +34,7 @@ function _normalize(input, label) {
|
|
|
33
34
|
var out = {};
|
|
34
35
|
for (var key in input) {
|
|
35
36
|
if (!Object.prototype.hasOwnProperty.call(input, key)) continue;
|
|
36
|
-
if (key
|
|
37
|
+
if (pick.isPoisonedKey(key)) {
|
|
37
38
|
continue; // poisoned-keys defense
|
|
38
39
|
}
|
|
39
40
|
out[key] = input[key];
|
|
@@ -55,12 +56,8 @@ function merge(base, overlay) {
|
|
|
55
56
|
var b = _normalize(base, "merge.base");
|
|
56
57
|
var o = _normalize(overlay, "merge.overlay");
|
|
57
58
|
var out = {};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
for (var k2 in o) {
|
|
62
|
-
if (Object.prototype.hasOwnProperty.call(o, k2)) out[k2] = o[k2];
|
|
63
|
-
}
|
|
59
|
+
validateOpts.assignOwnEnumerable(out, b);
|
|
60
|
+
validateOpts.assignOwnEnumerable(out, o);
|
|
64
61
|
return Object.freeze(out);
|
|
65
62
|
}
|
|
66
63
|
|
|
@@ -110,7 +107,7 @@ function fromRequest(req, opts) {
|
|
|
110
107
|
if (opts.extra && typeof opts.extra === "object") {
|
|
111
108
|
for (var k in opts.extra) {
|
|
112
109
|
if (Object.prototype.hasOwnProperty.call(opts.extra, k)) {
|
|
113
|
-
if (k
|
|
110
|
+
if (pick.isPoisonedKey(k)) continue;
|
|
114
111
|
ctx[k] = opts.extra[k];
|
|
115
112
|
}
|
|
116
113
|
}
|
package/lib/flag-providers.js
CHANGED
|
@@ -41,6 +41,7 @@ var validateOpts = require("./validate-opts");
|
|
|
41
41
|
var lazyRequire = require("./lazy-require");
|
|
42
42
|
var safeJson = require("./safe-json");
|
|
43
43
|
var C = require("./constants");
|
|
44
|
+
var atomicFile = require("./atomic-file");
|
|
44
45
|
var { defineClass } = require("./framework-error");
|
|
45
46
|
var FlagError = defineClass("FlagError", { alwaysPermanent: true });
|
|
46
47
|
|
|
@@ -128,7 +129,10 @@ function localFile(opts) {
|
|
|
128
129
|
validateOpts.requireNonEmptyString(opts.path,
|
|
129
130
|
"providers.localFile: path", FlagError, "flag/bad-provider");
|
|
130
131
|
var raw;
|
|
131
|
-
|
|
132
|
+
// Capped fd-bound read; the cap precedes the alloc so an oversized flag file
|
|
133
|
+
// can't OOM boot. refuseSymlink stays OFF: a flag file is commonly a k8s
|
|
134
|
+
// ConfigMap mount, which is a symlink chain — refusing it would break that.
|
|
135
|
+
try { raw = atomicFile.fdSafeReadSync(opts.path, { maxBytes: C.BYTES.mib(1), encoding: "utf8" }); }
|
|
132
136
|
catch (e) {
|
|
133
137
|
throw new FlagError("flag/bad-provider",
|
|
134
138
|
"providers.localFile: cannot read file " + JSON.stringify(opts.path) +
|
|
@@ -154,7 +158,7 @@ function localFile(opts) {
|
|
|
154
158
|
try {
|
|
155
159
|
nodeFs.watch(opts.path, { persistent: false }, function () {
|
|
156
160
|
try {
|
|
157
|
-
var nextRaw =
|
|
161
|
+
var nextRaw = atomicFile.fdSafeReadSync(opts.path, { maxBytes: C.BYTES.mib(1), encoding: "utf8" });
|
|
158
162
|
var nextParsed = safeJson.parse(nextRaw, { maxBytes: C.BYTES.mib(1) });
|
|
159
163
|
if (nextParsed && nextParsed.flags) {
|
|
160
164
|
for (var k in nextParsed.flags) {
|
package/lib/forms.js
CHANGED
|
@@ -252,7 +252,7 @@ function _renderField(field) {
|
|
|
252
252
|
var control;
|
|
253
253
|
if (type === "textarea") control = _renderTextarea(field);
|
|
254
254
|
else if (type === "select") control = _renderSelect(field);
|
|
255
|
-
else if (INPUT_TYPES
|
|
255
|
+
else if (Object.prototype.hasOwnProperty.call(INPUT_TYPES, type)) control = _renderInput(field);
|
|
256
256
|
else throw new Error("forms.render: unsupported field type: " + type);
|
|
257
257
|
|
|
258
258
|
// Hidden + submit fields don't need a label wrapper
|
package/lib/framework-error.js
CHANGED
|
@@ -144,6 +144,11 @@ var SchedulerError = defineClass("SchedulerError");
|
|
|
144
144
|
var SessionError = defineClass("SessionError");
|
|
145
145
|
var SlugError = defineClass("SlugError", { alwaysPermanent: true });
|
|
146
146
|
var WebhookError = defineClass("WebhookError", { alwaysPermanent: true });
|
|
147
|
+
// WebhookDispatcherError covers the durable signed-webhook delivery store
|
|
148
|
+
// (b.webhook.dispatcher): endpoint registration, fan-out, retry/backoff, and
|
|
149
|
+
// dead-letter operations. Distinct from WebhookError (the stateless
|
|
150
|
+
// sign/verify surface) so the persistence-layer error codes stay separable.
|
|
151
|
+
var WebhookDispatcherError = defineClass("WebhookDispatcherError", { alwaysPermanent: true });
|
|
147
152
|
var ApiKeyError = defineClass("ApiKeyError", { alwaysPermanent: true });
|
|
148
153
|
var PermissionsError = defineClass("PermissionsError", { alwaysPermanent: true });
|
|
149
154
|
// CacheError is alwaysPermanent: bad opts / missing key / closed-state
|
|
@@ -196,6 +201,11 @@ var GateContractError = defineClass("GateContractError", { alwaysPermane
|
|
|
196
201
|
// validate paths. alwaysPermanent — chunk-shape errors / formula-injection
|
|
197
202
|
// attempts / schema drift are all caller-shape errors.
|
|
198
203
|
var GuardCsvError = defineClass("GuardCsvError", { alwaysPermanent: true });
|
|
204
|
+
// GuardTextError covers free-text codepoint-threat violations on the validate /
|
|
205
|
+
// sanitize / gate paths (bidi-override / control / null / zero-width /
|
|
206
|
+
// Unicode-Tags / mixed-script-confusable). alwaysPermanent — every case is a
|
|
207
|
+
// hostile-codepoint detection or a caller-shape opt error.
|
|
208
|
+
var GuardTextError = defineClass("GuardTextError", { alwaysPermanent: true });
|
|
199
209
|
// GuardAllError covers parity-check failures, exceptFor opt validation, and
|
|
200
210
|
// override opt validation in the b.guardAll registry. alwaysPermanent — every
|
|
201
211
|
// case is a config-time programming bug, not a transient runtime condition.
|
|
@@ -693,6 +703,7 @@ module.exports = {
|
|
|
693
703
|
SessionError: SessionError,
|
|
694
704
|
SlugError: SlugError,
|
|
695
705
|
WebhookError: WebhookError,
|
|
706
|
+
WebhookDispatcherError: WebhookDispatcherError,
|
|
696
707
|
ApiKeyError: ApiKeyError,
|
|
697
708
|
PermissionsError: PermissionsError,
|
|
698
709
|
CacheError: CacheError,
|
|
@@ -705,6 +716,7 @@ module.exports = {
|
|
|
705
716
|
StaticServeError: StaticServeError,
|
|
706
717
|
GateContractError: GateContractError,
|
|
707
718
|
GuardCsvError: GuardCsvError,
|
|
719
|
+
GuardTextError: GuardTextError,
|
|
708
720
|
GuardAllError: GuardAllError,
|
|
709
721
|
GuardHtmlError: GuardHtmlError,
|
|
710
722
|
GuardSvgError: GuardSvgError,
|
package/lib/framework-schema.js
CHANGED
|
@@ -116,6 +116,10 @@ var LOCAL_TO_EXTERNAL = Object.freeze({
|
|
|
116
116
|
// places — cluster-storage.execute routes the SQL to the right DB
|
|
117
117
|
// based on cluster.isClusterMode().
|
|
118
118
|
_blamejs_sessions: "_blamejs_sessions",
|
|
119
|
+
// _blamejs_session_valid_from — per-subject valid-from boundary for
|
|
120
|
+
// stateless-token revocation (b.session.bump / check / validFrom). Same
|
|
121
|
+
// dual-storage shape as _blamejs_sessions; identity-mapped.
|
|
122
|
+
_blamejs_session_valid_from: "_blamejs_session_valid_from",
|
|
119
123
|
// _blamejs_jobs — same dual-storage pattern as sessions. The local-
|
|
120
124
|
// protocol queue (lib/queue-local.js) routes through cluster-storage
|
|
121
125
|
// so writes/reads land in the leader's external-db when cluster
|
|
@@ -649,6 +653,20 @@ function _sessionsDDL(dialect) {
|
|
|
649
653
|
]);
|
|
650
654
|
}
|
|
651
655
|
|
|
656
|
+
// _blamejs_session_valid_from — monotonic per-subject valid-from boundary for
|
|
657
|
+
// stateless-token revocation. Mirrors the local-SQLite schema in db.js's
|
|
658
|
+
// FRAMEWORK_SCHEMA so single-node and cluster behavior are identical.
|
|
659
|
+
// subjectHash is the PRIMARY KEY (the plaintext subject id never lands here);
|
|
660
|
+
// validFromEpoch is the monotonic boundary (ms); updatedAt records the bump.
|
|
661
|
+
function _sessionValidFromDDL(dialect) {
|
|
662
|
+
var t = _types(dialect);
|
|
663
|
+
return _table(tableName("_blamejs_session_valid_from"), dialect, [
|
|
664
|
+
{ col: "subjectHash", def: t.KT + " PRIMARY KEY" },
|
|
665
|
+
{ col: "validFromEpoch", def: t.INT + " NOT NULL" },
|
|
666
|
+
{ col: "updatedAt", def: t.INT + " NOT NULL" },
|
|
667
|
+
], []);
|
|
668
|
+
}
|
|
669
|
+
|
|
652
670
|
// _blamejs_jobs — local-protocol queue jobs. Mirrors db.js's
|
|
653
671
|
// FRAMEWORK_SCHEMA for the same table; sealed columns (payload,
|
|
654
672
|
// lastError) are stored vault-sealed. Indexes target the lease
|
|
@@ -824,6 +842,7 @@ function _allDDLs(dialect) {
|
|
|
824
842
|
_apiEncryptNoncesDDL(dialect),
|
|
825
843
|
_apiKeysDDL(dialect),
|
|
826
844
|
_sessionsDDL(dialect),
|
|
845
|
+
_sessionValidFromDDL(dialect),
|
|
827
846
|
_jobsDDL(dialect),
|
|
828
847
|
_cacheDDL(dialect),
|
|
829
848
|
_cacheTagsDDL(dialect),
|
package/lib/fsm.js
CHANGED
|
@@ -439,18 +439,13 @@ async function _runTransition(instance, name, opts) {
|
|
|
439
439
|
// drop-silent; the additional try/catch protects against the
|
|
440
440
|
// lazy-loaded audit module throwing at first-access time.
|
|
441
441
|
try {
|
|
442
|
-
audit().
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
transition: name,
|
|
450
|
-
machine: instance._def.name,
|
|
451
|
-
callerMeta: opts.metadata || null,
|
|
452
|
-
},
|
|
453
|
-
});
|
|
442
|
+
audit().namespaced("fsm")(instance._def.name + ".transition", "success", {
|
|
443
|
+
from: fromState,
|
|
444
|
+
to: toState,
|
|
445
|
+
transition: name,
|
|
446
|
+
machine: instance._def.name,
|
|
447
|
+
callerMeta: opts.metadata || null,
|
|
448
|
+
}, { actor: opts.actor ? { id: opts.actor } : { id: "<system>" } });
|
|
454
449
|
} catch (_e) { /* drop-silent — audit best-effort */ }
|
|
455
450
|
return { from: fromState, to: toState, on: name };
|
|
456
451
|
}
|