@blamejs/core 0.9.14 → 0.9.16
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/a2a-tasks.js +2 -2
- package/lib/a2a.js +11 -11
- package/lib/acme.js +5 -5
- package/lib/ai-input.js +2 -2
- package/lib/api-key.js +4 -4
- package/lib/api-snapshot.js +6 -6
- package/lib/app-shutdown.js +2 -2
- package/lib/app.js +5 -5
- package/lib/archive.js +8 -8
- package/lib/argon2-builtin.js +2 -2
- package/lib/atomic-file.js +53 -53
- package/lib/audit-sign.js +8 -8
- package/lib/audit-tools.js +22 -22
- package/lib/auth/dpop.js +3 -3
- package/lib/auth/elevation-grant.js +3 -3
- package/lib/auth/fido-mds3.js +6 -6
- package/lib/auth/jwt-external.js +2 -2
- package/lib/auth/sd-jwt-vc.js +2 -2
- package/lib/backup/bundle.js +17 -17
- package/lib/backup/index.js +36 -36
- package/lib/budr.js +3 -3
- package/lib/bundler.js +20 -20
- package/lib/circuit-breaker.js +4 -4
- package/lib/cli.js +25 -26
- package/lib/cluster.js +2 -2
- package/lib/compliance-sanctions.js +2 -2
- package/lib/compliance.js +6 -7
- package/lib/config-drift.js +15 -15
- package/lib/config.js +6 -6
- package/lib/content-credentials.js +4 -4
- package/lib/credential-hash.js +7 -7
- package/lib/crypto-field.js +9 -9
- package/lib/daemon.js +19 -19
- package/lib/db-file-lifecycle.js +24 -24
- package/lib/db-schema.js +2 -2
- package/lib/db.js +34 -34
- package/lib/dev.js +10 -10
- package/lib/dr-runbook.js +5 -5
- package/lib/dual-control.js +2 -2
- package/lib/external-db-migrate.js +17 -17
- package/lib/external-db.js +2 -2
- package/lib/fdx.js +2 -2
- package/lib/file-upload.js +30 -30
- package/lib/flag-evaluation-context.js +2 -2
- package/lib/flag-providers.js +4 -4
- package/lib/gate-contract.js +5 -5
- package/lib/graphql-federation.js +4 -7
- package/lib/honeytoken.js +6 -6
- package/lib/http-client-cookie-jar.js +6 -6
- package/lib/http-client.js +18 -18
- package/lib/i18n.js +5 -5
- package/lib/keychain.js +5 -5
- package/lib/legal-hold.js +2 -2
- package/lib/local-db-thin.js +9 -9
- package/lib/log-stream-local.js +17 -17
- package/lib/log-stream-syslog.js +2 -2
- package/lib/log-stream.js +3 -3
- package/lib/log.js +2 -2
- package/lib/mail-bounce.js +2 -2
- package/lib/mail-mdn.js +2 -2
- package/lib/mail-srs.js +2 -2
- package/lib/mail.js +7 -7
- package/lib/mcp-tool-registry.js +6 -6
- package/lib/mcp.js +2 -2
- package/lib/metrics.js +2 -2
- package/lib/middleware/api-encrypt.js +16 -16
- package/lib/middleware/body-parser.js +18 -18
- package/lib/middleware/compression.js +3 -3
- package/lib/middleware/csp-nonce.js +4 -4
- package/lib/middleware/health.js +7 -7
- package/lib/middleware/idempotency-key.js +163 -63
- package/lib/middleware/require-bound-key.js +4 -4
- package/lib/middleware/require-mtls.js +4 -4
- package/lib/migrations.js +5 -5
- package/lib/mtls-ca.js +26 -26
- package/lib/mtls-engine-default.js +5 -5
- package/lib/network-byte-quota.js +2 -2
- package/lib/network-dns.js +2 -2
- package/lib/network-nts.js +2 -2
- package/lib/network-proxy.js +3 -3
- package/lib/network-smtp-policy.js +2 -2
- package/lib/network-tls.js +17 -17
- package/lib/network.js +25 -25
- package/lib/notify.js +11 -11
- package/lib/object-store/gcs-bucket-ops.js +2 -2
- package/lib/object-store/gcs.js +5 -5
- package/lib/object-store/index.js +6 -6
- package/lib/object-store/local.js +19 -19
- package/lib/object-store/sigv4.js +3 -3
- package/lib/observability-tracer.js +4 -4
- package/lib/otel-export.js +3 -3
- package/lib/pagination.js +5 -5
- package/lib/parsers/safe-env.js +3 -3
- package/lib/parsers/safe-xml.js +3 -3
- package/lib/pqc-gate.js +5 -5
- package/lib/pubsub-redis.js +2 -2
- package/lib/queue-local.js +3 -3
- package/lib/queue.js +2 -2
- package/lib/redis-client.js +4 -4
- package/lib/restore-bundle.js +17 -17
- package/lib/restore-rollback.js +34 -34
- package/lib/restore.js +16 -16
- package/lib/router.js +25 -25
- package/lib/sandbox.js +8 -8
- package/lib/sec-cyber.js +3 -3
- package/lib/security-assert.js +2 -2
- package/lib/seeders.js +6 -6
- package/lib/self-update.js +18 -18
- package/lib/session-device-binding.js +2 -2
- package/lib/static.js +22 -22
- package/lib/template.js +19 -19
- package/lib/testing.js +9 -9
- package/lib/tls-exporter.js +5 -5
- package/lib/tracing.js +3 -3
- package/lib/vault/index.js +11 -11
- package/lib/vault/passphrase-ops.js +37 -37
- package/lib/vault/passphrase-source.js +2 -2
- package/lib/vault/rotate.js +64 -64
- package/lib/vault/seal-pem-file.js +26 -26
- package/lib/vault-aad.js +5 -5
- package/lib/watcher.js +22 -22
- package/lib/webhook.js +10 -10
- package/lib/worker-pool.js +6 -6
- package/lib/ws-client.js +6 -6
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
*/
|
|
30
30
|
var localProto = require("./local");
|
|
31
31
|
var httpPutProto = require("./http-put");
|
|
32
|
-
var
|
|
32
|
+
var sigv4 = require("./sigv4");
|
|
33
33
|
var sigv4BucketOps = require("./sigv4-bucket-ops");
|
|
34
|
-
var
|
|
34
|
+
var gcs = require("./gcs");
|
|
35
35
|
var gcsBucketOps = require("./gcs-bucket-ops");
|
|
36
|
-
var
|
|
36
|
+
var azureBlob = require("./azure-blob");
|
|
37
37
|
var azureBlobBucketOps = require("./azure-blob-bucket-ops");
|
|
38
38
|
var retryHelper = require("../retry");
|
|
39
39
|
var protocolDispatcher = require("../protocol-dispatcher");
|
|
@@ -47,9 +47,9 @@ var dispatcher = protocolDispatcher.create({
|
|
|
47
47
|
protocols: {
|
|
48
48
|
"local": localProto,
|
|
49
49
|
"http-put": httpPutProto,
|
|
50
|
-
"sigv4":
|
|
51
|
-
"gcs":
|
|
52
|
-
"azure-blob":
|
|
50
|
+
"sigv4": sigv4,
|
|
51
|
+
"gcs": gcs,
|
|
52
|
+
"azure-blob": azureBlob,
|
|
53
53
|
},
|
|
54
54
|
deferred: {},
|
|
55
55
|
fallbackProtocol: "local",
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Implements the uniform protocol surface (put / get / getStream / delete /
|
|
6
6
|
* head / list) against a directory tree. Streaming is via Node's native
|
|
7
|
-
*
|
|
7
|
+
* nodeFs.createReadStream / createWriteStream — no in-memory buffering of
|
|
8
8
|
* full files.
|
|
9
9
|
*
|
|
10
10
|
* Path safety: every key resolves under the configured rootDir, with an
|
|
11
11
|
* alphanumeric + `_-./` charset whitelist and explicit rejection of any
|
|
12
12
|
* path that escapes rootDir after resolution.
|
|
13
13
|
*/
|
|
14
|
-
var
|
|
15
|
-
var
|
|
14
|
+
var nodeFs = require("fs");
|
|
15
|
+
var nodePath = require("path");
|
|
16
16
|
var atomicFile = require("../atomic-file");
|
|
17
17
|
var cluster = require("../cluster");
|
|
18
18
|
var { ObjectStoreError } = require("../framework-error");
|
|
@@ -24,10 +24,10 @@ function _resolveSafe(rootDir, key) {
|
|
|
24
24
|
throw _err("INVALID_KEY", "key must be a non-empty string", true);
|
|
25
25
|
}
|
|
26
26
|
if (key.includes("\0")) throw _err("INVALID_KEY", "null byte in key", true);
|
|
27
|
-
if (
|
|
27
|
+
if (nodePath.isAbsolute(key)) throw _err("INVALID_KEY", "absolute key not allowed", true);
|
|
28
28
|
if (!SAFE_KEY.test(key)) throw _err("INVALID_KEY", "invalid characters in key", true);
|
|
29
|
-
var full =
|
|
30
|
-
var withSep = rootDir.endsWith(
|
|
29
|
+
var full = nodePath.resolve(rootDir, key);
|
|
30
|
+
var withSep = rootDir.endsWith(nodePath.sep) ? rootDir : rootDir + nodePath.sep;
|
|
31
31
|
if (full !== rootDir && !full.startsWith(withSep)) {
|
|
32
32
|
throw _err("INVALID_KEY", "key escapes rootDir", true);
|
|
33
33
|
}
|
|
@@ -40,14 +40,14 @@ function create(config) {
|
|
|
40
40
|
if (!config || !config.rootDir) {
|
|
41
41
|
throw new Error("local protocol requires { rootDir }");
|
|
42
42
|
}
|
|
43
|
-
var rootDir =
|
|
44
|
-
if (!
|
|
43
|
+
var rootDir = nodePath.resolve(config.rootDir);
|
|
44
|
+
if (!nodeFs.existsSync(rootDir)) nodeFs.mkdirSync(rootDir, { recursive: true });
|
|
45
45
|
|
|
46
46
|
function put(key, body, _opts) {
|
|
47
47
|
cluster.requireLeader();
|
|
48
48
|
var full = _resolveSafe(rootDir, key);
|
|
49
|
-
var dir =
|
|
50
|
-
if (!
|
|
49
|
+
var dir = nodePath.dirname(full);
|
|
50
|
+
if (!nodeFs.existsSync(dir)) nodeFs.mkdirSync(dir, { recursive: true });
|
|
51
51
|
|
|
52
52
|
if (Buffer.isBuffer(body)) {
|
|
53
53
|
atomicFile.writeSync(full, body);
|
|
@@ -56,7 +56,7 @@ function create(config) {
|
|
|
56
56
|
if (body && typeof body.pipe === "function") {
|
|
57
57
|
// Streaming put — pipe directly to disk
|
|
58
58
|
return new Promise(function (resolve, reject) {
|
|
59
|
-
var ws =
|
|
59
|
+
var ws = nodeFs.createWriteStream(full);
|
|
60
60
|
var bytes = 0;
|
|
61
61
|
body.on("data", function (chunk) { bytes += chunk.length; });
|
|
62
62
|
body.pipe(ws);
|
|
@@ -75,26 +75,26 @@ function create(config) {
|
|
|
75
75
|
|
|
76
76
|
function get(key) {
|
|
77
77
|
var full = _resolveSafe(rootDir, key);
|
|
78
|
-
if (!
|
|
78
|
+
if (!nodeFs.existsSync(full)) {
|
|
79
79
|
return Promise.reject(_err("NOT_FOUND", "key not found: " + key, true));
|
|
80
80
|
}
|
|
81
|
-
return Promise.resolve(
|
|
81
|
+
return Promise.resolve(nodeFs.readFileSync(full));
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function getStream(key) {
|
|
85
85
|
var full = _resolveSafe(rootDir, key);
|
|
86
|
-
if (!
|
|
86
|
+
if (!nodeFs.existsSync(full)) {
|
|
87
87
|
throw _err("NOT_FOUND", "key not found: " + key, true);
|
|
88
88
|
}
|
|
89
|
-
return
|
|
89
|
+
return nodeFs.createReadStream(full);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
function head(key) {
|
|
93
93
|
var full = _resolveSafe(rootDir, key);
|
|
94
|
-
if (!
|
|
94
|
+
if (!nodeFs.existsSync(full)) {
|
|
95
95
|
return Promise.reject(_err("NOT_FOUND", "key not found: " + key, true));
|
|
96
96
|
}
|
|
97
|
-
var stat =
|
|
97
|
+
var stat = nodeFs.statSync(full);
|
|
98
98
|
return Promise.resolve({
|
|
99
99
|
size: stat.size,
|
|
100
100
|
lastModified: stat.mtimeMs,
|
|
@@ -104,8 +104,8 @@ function create(config) {
|
|
|
104
104
|
function deleteKey(key) {
|
|
105
105
|
cluster.requireLeader();
|
|
106
106
|
var full = _resolveSafe(rootDir, key);
|
|
107
|
-
if (!
|
|
108
|
-
|
|
107
|
+
if (!nodeFs.existsSync(full)) return Promise.resolve(false);
|
|
108
|
+
nodeFs.unlinkSync(full);
|
|
109
109
|
return Promise.resolve(true);
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -29,7 +29,7 @@ var { Readable } = require("stream");
|
|
|
29
29
|
var safeXml = require("../parsers/safe-xml");
|
|
30
30
|
var sharedRequest = require("./http-request");
|
|
31
31
|
var C = require("../constants");
|
|
32
|
-
var
|
|
32
|
+
var numericBounds = require("../numeric-bounds");
|
|
33
33
|
var requestHelpers = require("../request-helpers");
|
|
34
34
|
var { ObjectStoreError } = require("../framework-error");
|
|
35
35
|
var safeUrl = require("../safe-url");
|
|
@@ -821,10 +821,10 @@ function create(config) {
|
|
|
821
821
|
"POST-form policy enforces body size via the content-length-range condition; " +
|
|
822
822
|
"use presignedUploadUrl if size enforcement is not needed", true);
|
|
823
823
|
}
|
|
824
|
-
if (opts.minBytes !== undefined && !
|
|
824
|
+
if (opts.minBytes !== undefined && !numericBounds.isNonNegativeFiniteInt(opts.minBytes)) {
|
|
825
825
|
throw _err("INVALID_MIN_BYTES",
|
|
826
826
|
"presignedUploadPolicy: minBytes must be a non-negative finite integer; got " +
|
|
827
|
-
|
|
827
|
+
numericBounds.shape(opts.minBytes), true);
|
|
828
828
|
}
|
|
829
829
|
var minBytes = opts.minBytes !== undefined ? opts.minBytes : 0;
|
|
830
830
|
var expiresIn = opts.expiresIn != null ? opts.expiresIn : PRESIGN_DEFAULT_EXPIRES_SECONDS;
|
|
@@ -73,14 +73,14 @@
|
|
|
73
73
|
*/
|
|
74
74
|
|
|
75
75
|
var bCrypto = require("./crypto");
|
|
76
|
-
var
|
|
76
|
+
var C = require("./constants");
|
|
77
77
|
var lazyRequire = require("./lazy-require");
|
|
78
78
|
var safeBuffer = require("./safe-buffer");
|
|
79
79
|
var validateOpts = require("./validate-opts");
|
|
80
80
|
var { defineClass } = require("./framework-error");
|
|
81
81
|
|
|
82
|
-
var TRACE_ID_BYTES =
|
|
83
|
-
var SPAN_ID_BYTES =
|
|
82
|
+
var TRACE_ID_BYTES = C.BYTES.bytes(16); // W3C §3.2.2.3 — 128-bit trace-id
|
|
83
|
+
var SPAN_ID_BYTES = C.BYTES.bytes(8); // W3C §3.2.2.4 — 64-bit span-id
|
|
84
84
|
|
|
85
85
|
var TracerError = defineClass("TracerError", { alwaysPermanent: true });
|
|
86
86
|
|
|
@@ -168,7 +168,7 @@ function create(opts) {
|
|
|
168
168
|
var resource = Object.assign({
|
|
169
169
|
"service.name": opts.service,
|
|
170
170
|
}, opts.resource || {});
|
|
171
|
-
var scope = opts.scope || { name: "blamejs", version:
|
|
171
|
+
var scope = opts.scope || { name: "blamejs", version: C.version || null };
|
|
172
172
|
var maxAttributes = opts.maxAttributes || DEFAULT_MAX_ATTRIBUTES;
|
|
173
173
|
var maxEvents = opts.maxEvents || DEFAULT_MAX_EVENTS;
|
|
174
174
|
var maxAttrValLen = opts.maxAttributeValueLength || DEFAULT_MAX_ATTR_VALUE_LEN;
|
package/lib/otel-export.js
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
*/
|
|
42
42
|
var C = require("./constants");
|
|
43
43
|
var canonicalJson = require("./canonical-json");
|
|
44
|
-
var
|
|
44
|
+
var httpClient = require("./http-client");
|
|
45
45
|
var safeAsync = require("./safe-async");
|
|
46
46
|
var validateOpts = require("./validate-opts");
|
|
47
47
|
var { defineClass } = require("./framework-error");
|
|
@@ -110,7 +110,7 @@ function create(opts) {
|
|
|
110
110
|
throw new OtelExportError("otel-export/bad-interval",
|
|
111
111
|
"create: intervalMs must be a non-negative finite number");
|
|
112
112
|
}
|
|
113
|
-
var
|
|
113
|
+
var effectiveHttpClient = opts.httpClient || httpClient;
|
|
114
114
|
var scopeName = (opts.scope && opts.scope.name) || "blamejs";
|
|
115
115
|
var scopeVersion = (opts.scope && opts.scope.version) || "0.5.x";
|
|
116
116
|
var resourceAttrs = Object.assign({ "service.name": serviceName },
|
|
@@ -220,7 +220,7 @@ function create(opts) {
|
|
|
220
220
|
if (!payload) return { sent: false, reason: "no-data" };
|
|
221
221
|
var body = JSON.stringify(payload);
|
|
222
222
|
try {
|
|
223
|
-
var res = await
|
|
223
|
+
var res = await effectiveHttpClient.request({
|
|
224
224
|
method: "POST",
|
|
225
225
|
url: endpoint,
|
|
226
226
|
headers: Object.assign({ "Content-Type": "application/json" }, headers),
|
package/lib/pagination.js
CHANGED
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
var nodeCrypto = require("node:crypto");
|
|
50
50
|
var C = require("./constants");
|
|
51
51
|
var canonicalJson = require("./canonical-json");
|
|
52
|
-
var
|
|
53
|
-
var
|
|
52
|
+
var bCrypto = require("./crypto");
|
|
53
|
+
var numericBounds = require("./numeric-bounds");
|
|
54
54
|
var safeJson = require("./safe-json");
|
|
55
55
|
var safeSql = require("./safe-sql");
|
|
56
56
|
var { defineClass } = require("./framework-error");
|
|
@@ -185,7 +185,7 @@ function decodeCursor(token, secret) {
|
|
|
185
185
|
throw new PaginationError("pagination/bad-cursor", "cursor base64 decode failed");
|
|
186
186
|
}
|
|
187
187
|
var expected = _tag(sb, json);
|
|
188
|
-
if (!
|
|
188
|
+
if (!bCrypto.timingSafeEqual(tag, expected)) {
|
|
189
189
|
throw new PaginationError("pagination/cursor-tag-mismatch",
|
|
190
190
|
"cursor HMAC verification failed (tampered or wrong secret)");
|
|
191
191
|
}
|
|
@@ -205,9 +205,9 @@ function decodeCursor(token, secret) {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
function _resolveLimit(opts) {
|
|
208
|
-
|
|
208
|
+
numericBounds.requirePositiveFiniteIntIfPresent(opts.max,
|
|
209
209
|
"max", PaginationError, "pagination/bad-opt");
|
|
210
|
-
|
|
210
|
+
numericBounds.requirePositiveFiniteIntIfPresent(opts.default,
|
|
211
211
|
"default", PaginationError, "pagination/bad-opt");
|
|
212
212
|
var max = opts.max || DEFAULT_MAX_LIMIT;
|
|
213
213
|
var def = opts.default || DEFAULT_LIMIT;
|
package/lib/parsers/safe-env.js
CHANGED
|
@@ -68,7 +68,7 @@ var { boot } = require("../log");
|
|
|
68
68
|
// (transitively) vault, which leaves safe-env's module.exports
|
|
69
69
|
// half-built when vault first reaches readVar. Defer audit resolution
|
|
70
70
|
// until the first emit-driven call.
|
|
71
|
-
var
|
|
71
|
+
var audit = lazyRequire(function () { return require("../audit"); });
|
|
72
72
|
|
|
73
73
|
var log = boot("env");
|
|
74
74
|
|
|
@@ -519,11 +519,11 @@ function _writeAuditRows(filepath, diff) {
|
|
|
519
519
|
// we're a follower, audit.record will throw NotLeaderError. Catch
|
|
520
520
|
// explicitly: a follower's local config-load shouldn't crash because
|
|
521
521
|
// the cluster's audit chain belongs to the leader.
|
|
522
|
-
var
|
|
522
|
+
var auditInst = audit(); // resolve the lazy-required audit module
|
|
523
523
|
|
|
524
524
|
function _safeRecord(action, metadata) {
|
|
525
525
|
try {
|
|
526
|
-
|
|
526
|
+
auditInst.emit({
|
|
527
527
|
actor: { kind: "system", id: "config-loader" },
|
|
528
528
|
action: action,
|
|
529
529
|
outcome: "success",
|
package/lib/parsers/safe-xml.js
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
var C = require("../constants");
|
|
43
|
-
var
|
|
43
|
+
var numericBounds = require("../numeric-bounds");
|
|
44
44
|
var safeBuffer = require("../safe-buffer");
|
|
45
45
|
var { FrameworkError } = require("../framework-error");
|
|
46
46
|
|
|
@@ -77,10 +77,10 @@ var BUILT_IN_ENTITIES = { lt: "<", gt: ">", amp: "&", quot: "\"", apos: "'" };
|
|
|
77
77
|
|
|
78
78
|
function _validateAndCap(name, value, defaultValue, ceiling) {
|
|
79
79
|
if (value === undefined) return defaultValue;
|
|
80
|
-
if (!
|
|
80
|
+
if (!numericBounds.isPositiveFiniteInt(value)) {
|
|
81
81
|
throw new SafeXmlError("xml/bad-opt",
|
|
82
82
|
"xml.parse: " + name + " must be a positive finite integer; got " +
|
|
83
|
-
|
|
83
|
+
numericBounds.shape(value));
|
|
84
84
|
}
|
|
85
85
|
return Math.min(value, ceiling);
|
|
86
86
|
}
|
package/lib/pqc-gate.js
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
var net = require("node:net");
|
|
40
40
|
var C = require("./constants");
|
|
41
41
|
var { PQC_GROUPS } = require("./constants");
|
|
42
|
-
var
|
|
42
|
+
var numericBounds = require("./numeric-bounds");
|
|
43
43
|
var validateOpts = require("./validate-opts");
|
|
44
44
|
var { boot } = require("./log");
|
|
45
45
|
|
|
@@ -155,14 +155,14 @@ function create(opts) {
|
|
|
155
155
|
}
|
|
156
156
|
var internalHost = typeof opts.internalHost === "string" ? opts.internalHost : "127.0.0.1";
|
|
157
157
|
var bypass = Array.isArray(opts.bypass) ? opts.bypass.slice() : DEFAULT_BYPASS.slice();
|
|
158
|
-
if (opts.clientHelloTimeoutMs !== undefined && !
|
|
158
|
+
if (opts.clientHelloTimeoutMs !== undefined && !numericBounds.isPositiveFiniteInt(opts.clientHelloTimeoutMs)) {
|
|
159
159
|
throw new Error("pqc-gate: clientHelloTimeoutMs must be a positive finite integer; got " +
|
|
160
|
-
|
|
160
|
+
numericBounds.shape(opts.clientHelloTimeoutMs));
|
|
161
161
|
}
|
|
162
162
|
var clientHelloTimeoutMs = opts.clientHelloTimeoutMs || DEFAULT_CLIENTHELLO_TIMEOUT_MS;
|
|
163
|
-
if (opts.maxClientHelloBytes !== undefined && !
|
|
163
|
+
if (opts.maxClientHelloBytes !== undefined && !numericBounds.isPositiveFiniteInt(opts.maxClientHelloBytes)) {
|
|
164
164
|
throw new Error("pqc-gate: maxClientHelloBytes must be a positive finite integer; got " +
|
|
165
|
-
|
|
165
|
+
numericBounds.shape(opts.maxClientHelloBytes));
|
|
166
166
|
}
|
|
167
167
|
var maxClientHelloBytes = opts.maxClientHelloBytes || DEFAULT_MAX_CLIENTHELLO_BYTES;
|
|
168
168
|
var log = opts.log || null;
|
package/lib/pubsub-redis.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* conventions of its own.
|
|
23
23
|
*/
|
|
24
24
|
var C = require("./constants");
|
|
25
|
-
var
|
|
25
|
+
var bCrypto = require("./crypto");
|
|
26
26
|
var lazyRequire = require("./lazy-require");
|
|
27
27
|
var redisClient = require("./redis-client");
|
|
28
28
|
var safeJson = require("./safe-json");
|
|
@@ -39,7 +39,7 @@ function create(opts) {
|
|
|
39
39
|
// the local dispatch synchronously before awaiting the remote
|
|
40
40
|
// write — without this filter every same-instance publish would
|
|
41
41
|
// double-fire local handlers).
|
|
42
|
-
var instanceNonce =
|
|
42
|
+
var instanceNonce = bCrypto.generateToken(C.BYTES.bytes(8));
|
|
43
43
|
|
|
44
44
|
var clientOpts = redisClient.pickClientOpts(opts, "redis");
|
|
45
45
|
|
package/lib/queue-local.js
CHANGED
|
@@ -35,7 +35,7 @@ var C = require("./constants");
|
|
|
35
35
|
var { generateToken } = require("./crypto");
|
|
36
36
|
var cryptoField = require("./crypto-field");
|
|
37
37
|
var lazyRequire = require("./lazy-require");
|
|
38
|
-
var
|
|
38
|
+
var numericBounds = require("./numeric-bounds");
|
|
39
39
|
var safeJson = require("./safe-json");
|
|
40
40
|
var scheduler = require("./scheduler");
|
|
41
41
|
var { QueueError } = require("./framework-error");
|
|
@@ -388,10 +388,10 @@ function create(_config) {
|
|
|
388
388
|
opts = opts || {};
|
|
389
389
|
var limit = 100;
|
|
390
390
|
if (opts.limit !== undefined) {
|
|
391
|
-
if (!
|
|
391
|
+
if (!numericBounds.isPositiveFiniteInt(opts.limit)) {
|
|
392
392
|
throw new QueueError("queue/bad-opt",
|
|
393
393
|
"queue.dlqList: limit must be a positive finite integer; got " +
|
|
394
|
-
|
|
394
|
+
numericBounds.shape(opts.limit), true);
|
|
395
395
|
}
|
|
396
396
|
limit = opts.limit;
|
|
397
397
|
}
|
package/lib/queue.js
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
*/
|
|
44
44
|
var C = require("./constants");
|
|
45
45
|
var clusterStorage = require("./cluster-storage");
|
|
46
|
-
var
|
|
46
|
+
var bCrypto = require("./crypto");
|
|
47
47
|
var lazyRequire = require("./lazy-require");
|
|
48
48
|
var { boot } = require("./log");
|
|
49
49
|
var numericChecks = require("./numeric-checks");
|
|
@@ -877,7 +877,7 @@ function enqueueFlow(spec) {
|
|
|
877
877
|
return Promise.reject(e);
|
|
878
878
|
}
|
|
879
879
|
|
|
880
|
-
var flowId = "flow-" +
|
|
880
|
+
var flowId = "flow-" + bCrypto.generateToken(C.BYTES.bytes(8));
|
|
881
881
|
|
|
882
882
|
return observability.tap("queue.enqueueFlow",
|
|
883
883
|
{ queueName: spec.queueName, flowId: flowId, childCount: spec.children.length },
|
package/lib/redis-client.js
CHANGED
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
* callers can branch on transport vs server-side errors.
|
|
26
26
|
*/
|
|
27
27
|
var net = require("node:net");
|
|
28
|
-
var
|
|
29
|
-
var
|
|
28
|
+
var nodeTls = require("node:tls");
|
|
29
|
+
var nodeUrl = require("node:url");
|
|
30
30
|
var C = require("./constants");
|
|
31
31
|
var safeAsync = require("./safe-async");
|
|
32
32
|
var validateOpts = require("./validate-opts");
|
|
@@ -319,7 +319,7 @@ function create(opts) {
|
|
|
319
319
|
var tlsConnectOpts = { host: host, port: port };
|
|
320
320
|
if (servername) tlsConnectOpts.servername = servername;
|
|
321
321
|
if (caBundle) tlsConnectOpts.ca = caBundle;
|
|
322
|
-
sock =
|
|
322
|
+
sock = nodeTls.connect(tlsConnectOpts, onOk);
|
|
323
323
|
} else {
|
|
324
324
|
sock = net.connect({ host: host, port: port }, onOk);
|
|
325
325
|
}
|
|
@@ -457,7 +457,7 @@ function create(opts) {
|
|
|
457
457
|
// Empty-username + non-empty password is the legacy single-arg AUTH form.
|
|
458
458
|
function _parseRedisUrl(s) {
|
|
459
459
|
var u;
|
|
460
|
-
try { u = new
|
|
460
|
+
try { u = new nodeUrl.URL(s); }
|
|
461
461
|
catch (e) {
|
|
462
462
|
throw _err("BAD_URL", "redis url parse failed: " + ((e && e.message) || String(e)));
|
|
463
463
|
}
|
package/lib/restore-bundle.js
CHANGED
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
* Backup-bundle reader — verify the manifest signature, list bundle contents without decrypting, and cherry-pick a restore subset to a staging directory the caller atomically swaps into place.
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
|
-
var
|
|
49
|
-
var
|
|
48
|
+
var nodeFs = require("fs");
|
|
49
|
+
var nodePath = require("path");
|
|
50
50
|
var atomicFile = require("./atomic-file");
|
|
51
51
|
var backupCrypto = require("./backup/crypto");
|
|
52
52
|
var backupManifest = require("./backup/manifest");
|
|
@@ -65,7 +65,7 @@ function _cleanupStaging(stagingDir) {
|
|
|
65
65
|
// Best-effort recursive remove — if cleanup fails, surface that to
|
|
66
66
|
// the caller via stderr but never override the original error
|
|
67
67
|
// we're already throwing.
|
|
68
|
-
try {
|
|
68
|
+
try { nodeFs.rmSync(stagingDir, { recursive: true, force: true }); }
|
|
69
69
|
catch (_e) { /* best-effort */ }
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -123,12 +123,12 @@ function _cleanupStaging(stagingDir) {
|
|
|
123
123
|
async function extract(opts) {
|
|
124
124
|
var t0 = Date.now();
|
|
125
125
|
opts = opts || {};
|
|
126
|
-
if (typeof opts.bundleDir !== "string" || !
|
|
126
|
+
if (typeof opts.bundleDir !== "string" || !nodeFs.existsSync(opts.bundleDir)) {
|
|
127
127
|
throw new RestoreBundleError("restore-bundle/no-bundle",
|
|
128
128
|
"extract: opts.bundleDir is required and must exist");
|
|
129
129
|
}
|
|
130
130
|
validateOpts.requireNonEmptyString(opts.stagingDir, "extract: opts.stagingDir", RestoreBundleError, "restore-bundle/no-staging");
|
|
131
|
-
if (
|
|
131
|
+
if (nodeFs.existsSync(opts.stagingDir)) {
|
|
132
132
|
throw new RestoreBundleError("restore-bundle/staging-exists",
|
|
133
133
|
"extract: stagingDir already exists: " + opts.stagingDir +
|
|
134
134
|
" (refusing to merge into existing directory — pick a fresh path)");
|
|
@@ -145,14 +145,14 @@ async function extract(opts) {
|
|
|
145
145
|
|
|
146
146
|
// 1. Read + parse + validate manifest
|
|
147
147
|
_emit(progress, { phase: "read_manifest" });
|
|
148
|
-
var manifestPath =
|
|
149
|
-
if (!
|
|
148
|
+
var manifestPath = nodePath.join(bundleDir, "manifest.json");
|
|
149
|
+
if (!nodeFs.existsSync(manifestPath)) {
|
|
150
150
|
throw new RestoreBundleError("restore-bundle/missing-manifest",
|
|
151
151
|
"extract: bundleDir has no manifest.json — bundle is incomplete or not a blamejs backup");
|
|
152
152
|
}
|
|
153
153
|
var manifest;
|
|
154
154
|
try {
|
|
155
|
-
manifest = backupManifest.parse(
|
|
155
|
+
manifest = backupManifest.parse(nodeFs.readFileSync(manifestPath, "utf8"));
|
|
156
156
|
} catch (e) {
|
|
157
157
|
if (e && e.isBackupManifestError) throw e;
|
|
158
158
|
throw new RestoreBundleError("restore-bundle/bad-manifest",
|
|
@@ -215,13 +215,13 @@ async function extract(opts) {
|
|
|
215
215
|
continue;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
var blobPath =
|
|
219
|
-
if (!
|
|
218
|
+
var blobPath = nodePath.join(bundleDir, entry.encryptedPath);
|
|
219
|
+
if (!nodeFs.existsSync(blobPath)) {
|
|
220
220
|
throw new RestoreBundleError("restore-bundle/missing-blob",
|
|
221
221
|
"extract: manifest references '" + entry.encryptedPath +
|
|
222
222
|
"' but the bundle has no such file");
|
|
223
223
|
}
|
|
224
|
-
var blob =
|
|
224
|
+
var blob = nodeFs.readFileSync(blobPath);
|
|
225
225
|
if (blob.length !== entry.encryptedSize) {
|
|
226
226
|
throw new RestoreBundleError("restore-bundle/size-mismatch",
|
|
227
227
|
"extract: blob '" + entry.encryptedPath + "' has size " + blob.length +
|
|
@@ -257,8 +257,8 @@ async function extract(opts) {
|
|
|
257
257
|
" — bundle is corrupted or manifest tampered");
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
var destPath =
|
|
261
|
-
atomicFile.ensureDir(
|
|
260
|
+
var destPath = nodePath.join(stagingDir, entry.relativePath);
|
|
261
|
+
atomicFile.ensureDir(nodePath.dirname(destPath));
|
|
262
262
|
atomicFile.writeSync(destPath, plaintext, { fileMode: 0o600 });
|
|
263
263
|
|
|
264
264
|
fileCount++;
|
|
@@ -321,16 +321,16 @@ async function extract(opts) {
|
|
|
321
321
|
*/
|
|
322
322
|
function inspect(opts) {
|
|
323
323
|
opts = opts || {};
|
|
324
|
-
if (typeof opts.bundleDir !== "string" || !
|
|
324
|
+
if (typeof opts.bundleDir !== "string" || !nodeFs.existsSync(opts.bundleDir)) {
|
|
325
325
|
throw new RestoreBundleError("restore-bundle/no-bundle",
|
|
326
326
|
"inspect: opts.bundleDir is required and must exist");
|
|
327
327
|
}
|
|
328
|
-
var manifestPath =
|
|
329
|
-
if (!
|
|
328
|
+
var manifestPath = nodePath.join(opts.bundleDir, "manifest.json");
|
|
329
|
+
if (!nodeFs.existsSync(manifestPath)) {
|
|
330
330
|
throw new RestoreBundleError("restore-bundle/missing-manifest",
|
|
331
331
|
"inspect: bundleDir has no manifest.json");
|
|
332
332
|
}
|
|
333
|
-
return backupManifest.parse(
|
|
333
|
+
return backupManifest.parse(nodeFs.readFileSync(manifestPath, "utf8"));
|
|
334
334
|
}
|
|
335
335
|
|
|
336
336
|
module.exports = {
|