@camstack/system 1.2.429 → 1.2.431
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/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/file-host-client.d.ts +11 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +34 -4
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +34 -4
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +74 -10
- package/dist/builtins/system-config/system-config.addon.mjs +74 -11
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-SYtYuAgh.mjs → composition-sources-Cw_TXEq9.mjs} +1 -1
- package/dist/{composition-sources-C2VNX6tF.js → composition-sources-o5MPSlk6.js} +1 -1
- package/dist/{constants-RI-hGP5S.js → constants-BcNaVkvI.js} +1 -1
- package/dist/{constants-CKuWoWvc.mjs → constants-CttE77VF.mjs} +1 -1
- package/dist/{device-ca-R7DKKZL6.mjs → device-ca-B-BTxeCj.mjs} +1 -1
- package/dist/{device-ca-BWfdDB3k.js → device-ca-CKiqh2Iu.js} +1 -1
- package/dist/{dist-CSSfTM18.mjs → dist-CXG6muCR.mjs} +545 -34
- package/dist/{dist-Bgy_AmwX.js → dist-DxJdci75.js} +545 -34
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/index.js +203 -53
- package/dist/index.mjs +198 -55
- package/dist/kernel/index.d.ts +4 -2
- package/dist/kernel/moleculer/broker-factory.d.ts +28 -2
- package/dist/kernel/moleculer/broker-transport-swap.d.ts +43 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-certificate-registry.d.ts +10 -0
- package/dist/kernel/moleculer/mesh-mtls/mesh-peer-transport.d.ts +7 -3
- package/dist/kernel/moleculer/mesh-mtls/mesh-renewal.d.ts +8 -1
- package/dist/{restore-archive-BYUEMsog.js → restore-archive-CQJNoqRK.js} +1 -1
- package/dist/{restore-archive-AIwMHO5_.mjs → restore-archive-D_wBL1OO.mjs} +1 -1
- package/dist/{retired-settings-keys-H0rYXT27.mjs → retired-settings-keys-EmDe11cP.mjs} +1 -1
- package/dist/{retired-settings-keys-BTPkRLTS.js → retired-settings-keys-g1oifXxR.js} +1 -1
- package/dist/{wal-maintenance-BSGsxKW7.js → wal-maintenance-BW1LIHi0.js} +0 -0
- package/dist/{wal-maintenance-DW0FfGV7.mjs → wal-maintenance-vhPZLYuA.mjs} +0 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $n as vectorStoreCapability, Sr as RUNTIME_DEFAULTS, _ as DATABASE_SNAPSHOT_TIMEOUT_MS, _r as BaseAddon, bt as databaseSnapshotCapability, et as bareAddonId, g as DATABASE_SNAPSHOT_SUFFIX, gr as errMsg, h as DATABASE_SNAPSHOT_PARTIAL_SUFFIX, v as DATA_STORE_DATABASES, yt as dataStoreProviderCapability } from "../../dist-
|
|
2
|
-
import { r as retiredKeyStoreOf, t as purgeRetiredSettingsKeys } from "../../retired-settings-keys-
|
|
3
|
-
import { C as callControl, E as controlTargetOf, S as trustResult, T as callVector, _ as collectTransferables, a as WalMaintenance, c as SqliteSettingsBackend, d as CrossDatabaseTransactError, f as DatabaseBusyError, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callData } from "../../wal-maintenance-
|
|
1
|
+
import { $n as vectorStoreCapability, Sr as RUNTIME_DEFAULTS, _ as DATABASE_SNAPSHOT_TIMEOUT_MS, _r as BaseAddon, bt as databaseSnapshotCapability, et as bareAddonId, g as DATABASE_SNAPSHOT_SUFFIX, gr as errMsg, h as DATABASE_SNAPSHOT_PARTIAL_SUFFIX, v as DATA_STORE_DATABASES, yt as dataStoreProviderCapability } from "../../dist-CXG6muCR.mjs";
|
|
2
|
+
import { r as retiredKeyStoreOf, t as purgeRetiredSettingsKeys } from "../../retired-settings-keys-EmDe11cP.mjs";
|
|
3
|
+
import { C as callControl, E as controlTargetOf, S as trustResult, T as callVector, _ as collectTransferables, a as WalMaintenance, c as SqliteSettingsBackend, d as CrossDatabaseTransactError, f as DatabaseBusyError, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callData } from "../../wal-maintenance-vhPZLYuA.mjs";
|
|
4
4
|
import { r as isSnapshotWorkerMessage } from "../../sqlite-snapshot-protocol-2QaTouWV.mjs";
|
|
5
5
|
import { a as isWorkerMessage, t as WAL_CHECKPOINT_LARGE_PASS_FRAMES } from "../../wal-checkpoint-policy-BahrTtyD.mjs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
@@ -21,6 +21,8 @@ function defaultFileHostWorkerPath() {
|
|
|
21
21
|
const packageRoot = path.dirname(require_.resolve("@camstack/system/package.json"));
|
|
22
22
|
return path.join(packageRoot, "dist", "file-host-worker.js");
|
|
23
23
|
}
|
|
24
|
+
/** How long a stopped thread has to end on its own before it is terminated. */
|
|
25
|
+
var FILE_HOST_EXIT_GRACE_MS = 5e3;
|
|
24
26
|
var FileHostClient = class {
|
|
25
27
|
spec;
|
|
26
28
|
logger;
|
|
@@ -32,6 +34,8 @@ var FileHostClient = class {
|
|
|
32
34
|
nextId = 1;
|
|
33
35
|
lastOp = "(none yet)";
|
|
34
36
|
stopping = false;
|
|
37
|
+
/** Settles when the thread's event loop has ended and its isolate is gone. */
|
|
38
|
+
exited;
|
|
35
39
|
dead = false;
|
|
36
40
|
lastBusyLogAt = -Infinity;
|
|
37
41
|
declared = /* @__PURE__ */ new Set();
|
|
@@ -56,8 +60,14 @@ var FileHostClient = class {
|
|
|
56
60
|
});
|
|
57
61
|
this.thread.on("message", (message) => this.onMessage(message));
|
|
58
62
|
this.thread.on("error", (err) => this.die(`worker error: ${errMsg(err)}`));
|
|
63
|
+
this.exited = new Promise((resolve) => {
|
|
64
|
+
this.thread.on("exit", () => resolve());
|
|
65
|
+
});
|
|
59
66
|
this.thread.on("exit", (code) => {
|
|
60
|
-
if (this.stopping)
|
|
67
|
+
if (this.stopping) {
|
|
68
|
+
for (const pending of this.pending.values()) if (pending.op === "stop") pending.resolve(void 0);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
61
71
|
this.die(`worker exited with code ${code}`);
|
|
62
72
|
});
|
|
63
73
|
}
|
|
@@ -116,6 +126,26 @@ var FileHostClient = class {
|
|
|
116
126
|
});
|
|
117
127
|
});
|
|
118
128
|
} finally {
|
|
129
|
+
await this.awaitExit();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Let the thread END ITSELF after it answered `stop`: it has closed every
|
|
134
|
+
* statement and the connection and closed its port, so its loop drains and
|
|
135
|
+
* the isolate is disposed from inside. `terminate()` straight after the
|
|
136
|
+
* answer races that disposal and, on macOS, took the whole process down with
|
|
137
|
+
* a SIGSEGV in the isolate's teardown GC. Terminate is only the fallback for
|
|
138
|
+
* a thread that does not leave in time.
|
|
139
|
+
*/
|
|
140
|
+
async awaitExit() {
|
|
141
|
+
let timer;
|
|
142
|
+
const timedOut = new Promise((resolve) => {
|
|
143
|
+
timer = setTimeout(() => resolve("timeout"), FILE_HOST_EXIT_GRACE_MS);
|
|
144
|
+
});
|
|
145
|
+
const outcome = await Promise.race([this.exited.then(() => "exited"), timedOut]);
|
|
146
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
147
|
+
if (outcome === "timeout") {
|
|
148
|
+
this.logger.warn("database worker did not leave after stop — terminating it", { tags: { database: this.spec.databaseId } });
|
|
119
149
|
await this.thread.terminate();
|
|
120
150
|
}
|
|
121
151
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-DxJdci75.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as evictionPolicyOfLocation, G as StorageLocationTypeSchema, Gr as isSecretMarker, Hn as storageMigrationCapability, Jt as isLocationEnabled, K as StorageMigrationJobSchema, P as LegacyStorageLocationDefaultSchema, Rn as settingsStoreCapability, U as StorageCleanupJobSchema, Ut as gbToBytes, Vn as storageCapability, W as StorageLocationModeSchema, Xr as parseJsonObject, _r as BaseAddon, ci as transformSecretWrite, cn as mayReadLocation, er as withLocationMode, fn as modeMayWrite, jn as resolveLocationMode, jr as collectSecretConfigKeys, li as EventCategory, ln as mayWriteToLocation, ri as secretTreeFromPaths, ti as resolveSecretMarkers, tn as legacyModeOf, xr as REDACTED_SECRET } from "../../dist-
|
|
1
|
+
import { Ft as evictionPolicyOfLocation, G as StorageLocationTypeSchema, Gr as isSecretMarker, Hn as storageMigrationCapability, Jt as isLocationEnabled, K as StorageMigrationJobSchema, P as LegacyStorageLocationDefaultSchema, Rn as settingsStoreCapability, U as StorageCleanupJobSchema, Ut as gbToBytes, Vn as storageCapability, W as StorageLocationModeSchema, Xr as parseJsonObject, _r as BaseAddon, ci as transformSecretWrite, cn as mayReadLocation, er as withLocationMode, fn as modeMayWrite, jn as resolveLocationMode, jr as collectSecretConfigKeys, li as EventCategory, ln as mayWriteToLocation, ri as secretTreeFromPaths, ti as resolveSecretMarkers, tn as legacyModeOf, xr as REDACTED_SECRET } from "../../dist-CXG6muCR.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { containsOrEquals, physicalRootOf } from "@camstack/types/node";
|
|
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-DxJdci75.js");
|
|
7
7
|
const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
|
|
8
8
|
const require_x509_es = require("../../x509.es-Dzl0BbmG.js");
|
|
9
9
|
const require_agent_https_names = require("../../agent-https-names-CpUSuP4w.js");
|
|
10
|
-
const require_constants$8 = require("../../constants-
|
|
10
|
+
const require_constants$8 = require("../../constants-BcNaVkvI.js");
|
|
11
11
|
const require_src$1 = require("../../src-CnAqG6EF.js");
|
|
12
12
|
let zod = require("zod");
|
|
13
13
|
let node_crypto = require("node:crypto");
|
|
@@ -792,7 +792,7 @@ var MeshCertificateRegistry = class {
|
|
|
792
792
|
async recordObserved(nodeId, leaf) {
|
|
793
793
|
const known = this.rows.get(leaf.fingerprint);
|
|
794
794
|
if (known !== void 0) {
|
|
795
|
-
if (known.revokedReason !== "renewal-abandoned") return false;
|
|
795
|
+
if (known.revokedReason !== "renewal-abandoned") return known.revokedAt === null ? this.abandonRenewalsNewerThan(known) : false;
|
|
796
796
|
const reinstated = {
|
|
797
797
|
...known,
|
|
798
798
|
revokedAt: null,
|
|
@@ -908,6 +908,29 @@ var MeshCertificateRegistry = class {
|
|
|
908
908
|
return settled;
|
|
909
909
|
}
|
|
910
910
|
/** Set a never-completed renewal leaf aside (not current, NOT on the CRL). */
|
|
911
|
+
/** Fingerprints of renewal leaves whose handover is running right now (this process only). */
|
|
912
|
+
renewalsInFlight = /* @__PURE__ */ new Set();
|
|
913
|
+
/**
|
|
914
|
+
* A renewal's leaf is "in flight" from signing until the handover ends. While it is, a node seen
|
|
915
|
+
* presenting its OLD leaf is simply not swapped yet: the new leaf is not set aside (that would
|
|
916
|
+
* flap set-aside / reinstate on the node's first connection with it).
|
|
917
|
+
*/
|
|
918
|
+
beginRenewal(fingerprint) {
|
|
919
|
+
this.renewalsInFlight.add(fingerprint);
|
|
920
|
+
}
|
|
921
|
+
endRenewal(fingerprint) {
|
|
922
|
+
this.renewalsInFlight.delete(fingerprint);
|
|
923
|
+
}
|
|
924
|
+
async abandonRenewalsNewerThan(presented) {
|
|
925
|
+
let changed = false;
|
|
926
|
+
for (const record of this.liveFor(presented.nodeId)) {
|
|
927
|
+
if (record.fingerprint === presented.fingerprint) continue;
|
|
928
|
+
if (record.issuedVia !== "renewal" || record.issuedAt <= presented.issuedAt) continue;
|
|
929
|
+
if (this.renewalsInFlight.has(record.fingerprint)) continue;
|
|
930
|
+
if (await this.abandon(record.fingerprint)) changed = true;
|
|
931
|
+
}
|
|
932
|
+
return changed;
|
|
933
|
+
}
|
|
911
934
|
async abandon(fingerprint) {
|
|
912
935
|
const record = this.rows.get(fingerprint);
|
|
913
936
|
if (record === void 0 || record.revokedAt !== null) return false;
|
|
@@ -1063,6 +1086,24 @@ function message$1(error) {
|
|
|
1063
1086
|
return error instanceof Error ? error.message : String(error);
|
|
1064
1087
|
}
|
|
1065
1088
|
async function renewMeshCertificate(deps) {
|
|
1089
|
+
const inFlight = { fingerprint: null };
|
|
1090
|
+
try {
|
|
1091
|
+
return await runRenewal(deps, inFlight);
|
|
1092
|
+
} finally {
|
|
1093
|
+
if (inFlight.fingerprint !== null) {
|
|
1094
|
+
deps.registry.endRenewal(inFlight.fingerprint);
|
|
1095
|
+
const live = deps.peers.peerLeaf(deps.nodeId);
|
|
1096
|
+
if (live !== void 0) await deps.registry.recordObserved(deps.nodeId, {
|
|
1097
|
+
cn: deps.nodeId,
|
|
1098
|
+
serial: live.serial,
|
|
1099
|
+
fingerprint: live.fingerprint,
|
|
1100
|
+
notBefore: live.notBefore,
|
|
1101
|
+
notAfter: live.notAfter
|
|
1102
|
+
}).catch(() => void 0);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
async function runRenewal(deps, inFlight) {
|
|
1066
1107
|
const { nodeId, log } = deps;
|
|
1067
1108
|
const tags = { nodeId };
|
|
1068
1109
|
const sleep = deps.sleep ?? defaultSleep;
|
|
@@ -1124,12 +1165,28 @@ async function renewMeshCertificate(deps) {
|
|
|
1124
1165
|
return fail("issue", message$1(error), true);
|
|
1125
1166
|
}
|
|
1126
1167
|
const newLeaf = describeMeshLeaf(issued.certPem);
|
|
1168
|
+
deps.registry.beginRenewal(newLeaf.fingerprint);
|
|
1169
|
+
inFlight.fingerprint = newLeaf.fingerprint;
|
|
1127
1170
|
let resolveRegistered = () => void 0;
|
|
1128
1171
|
const registeredPromise = new Promise((resolve) => {
|
|
1129
1172
|
resolveRegistered = resolve;
|
|
1130
1173
|
});
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1174
|
+
const expected = deps.expectedAddons?.(nodeId) ?? [];
|
|
1175
|
+
let missingAddons = [];
|
|
1176
|
+
const unsubscribe = deps.registrations.subscribe((id, addonIds) => {
|
|
1177
|
+
if (id !== nodeId || deps.peers.peerLeaf(nodeId)?.fingerprint !== newLeaf.fingerprint) return;
|
|
1178
|
+
if (addonIds !== void 0) {
|
|
1179
|
+
const present = new Set(addonIds);
|
|
1180
|
+
missingAddons = expected.filter((addonId) => !present.has(addonId));
|
|
1181
|
+
if (missingAddons.length > 0) {
|
|
1182
|
+
log.warn("Mesh renewal: the node registered without addons it had before - waiting", {
|
|
1183
|
+
tags,
|
|
1184
|
+
meta: { missing: missingAddons }
|
|
1185
|
+
});
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
resolveRegistered(true);
|
|
1133
1190
|
});
|
|
1134
1191
|
const deadlineTimer = setTimer(() => resolveRegistered(false), timeoutMs);
|
|
1135
1192
|
registeredPromise.then(() => deadlineTimer.cancel());
|
|
@@ -1160,7 +1217,8 @@ async function renewMeshCertificate(deps) {
|
|
|
1160
1217
|
}
|
|
1161
1218
|
});
|
|
1162
1219
|
await deps.registry.abandon(newLeaf.fingerprint);
|
|
1163
|
-
|
|
1220
|
+
const lost = missingAddons.length > 0 ? ` (its last registration lacked ${missingAddons.length} addon(s) it had before: ${missingAddons.slice(0, 5).join(", ")}; the swap was rolled back and nothing was revoked - once those addons are running again the next renewal will go through)` : "";
|
|
1221
|
+
return fail("reconnect", `the node was not back and registered with the new leaf within ${Math.round(timeoutMs / 1e3)} s${lost}; the previous leaf was kept and is still valid`, true);
|
|
1164
1222
|
}
|
|
1165
1223
|
log.info("Mesh renewal: the node registered presenting the new leaf", { tags });
|
|
1166
1224
|
let confirmError = "the node did not confirm the new leaf";
|
|
@@ -1280,10 +1338,14 @@ function onProcessNodeRegistered(listener) {
|
|
|
1280
1338
|
listeners.delete(listener);
|
|
1281
1339
|
};
|
|
1282
1340
|
}
|
|
1283
|
-
/**
|
|
1284
|
-
|
|
1341
|
+
/**
|
|
1342
|
+
* Called by the hub when a node's `registerNode` has been applied. `addonIds` is what that
|
|
1343
|
+
* registration carried (a node's own addons and its children's, D3), so a waiter can tell the
|
|
1344
|
+
* registration of a node that came back WHOLE from the first one of a node that lost its children.
|
|
1345
|
+
*/
|
|
1346
|
+
function emitProcessNodeRegistered(nodeId, addonIds) {
|
|
1285
1347
|
for (const listener of [...registrationListeners()]) try {
|
|
1286
|
-
listener(nodeId);
|
|
1348
|
+
listener(nodeId, addonIds);
|
|
1287
1349
|
} catch {}
|
|
1288
1350
|
}
|
|
1289
1351
|
//#endregion
|
|
@@ -87836,6 +87898,7 @@ var TlsTcpTransporter = class extends TcpTransporterBase {
|
|
|
87836
87898
|
});
|
|
87837
87899
|
server.on("error", (err) => {
|
|
87838
87900
|
this.logger.error("Mesh TLS server error.", err);
|
|
87901
|
+
if (this.tlsServer === server) this.tlsServer = null;
|
|
87839
87902
|
reject(err);
|
|
87840
87903
|
});
|
|
87841
87904
|
server.listen({
|
|
@@ -87845,9 +87908,9 @@ var TlsTcpTransporter = class extends TcpTransporterBase {
|
|
|
87845
87908
|
const address = server.address();
|
|
87846
87909
|
const port = address !== null && typeof address === "object" ? address.port : tlsPort;
|
|
87847
87910
|
this.logger.info(`Mesh TLS server is listening on port ${port}`);
|
|
87911
|
+
this.tlsServer = server;
|
|
87848
87912
|
resolve();
|
|
87849
87913
|
});
|
|
87850
|
-
this.tlsServer = server;
|
|
87851
87914
|
});
|
|
87852
87915
|
}
|
|
87853
87916
|
onTlsClientConnected(socket) {
|
|
@@ -88676,6 +88739,7 @@ exports.ServiceBroker = ServiceBroker;
|
|
|
88676
88739
|
exports.SystemConfigAddon = SystemConfigAddon;
|
|
88677
88740
|
exports.default = SystemConfigAddon;
|
|
88678
88741
|
exports.TlsTcpTransporter = TlsTcpTransporter;
|
|
88742
|
+
exports.Transporters = Transporters;
|
|
88679
88743
|
exports.UnlockTicketJtiStore = UnlockTicketJtiStore;
|
|
88680
88744
|
exports.caFingerprint = caFingerprint;
|
|
88681
88745
|
exports.caFingerprintCompact = caFingerprintCompact;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { Br as hydrateSchema, Fr as defineCustomActions, Gr as isSecretMarker, Pr as customAction, Wr as isSecretClear, _r as BaseAddon, ci as transformSecretWrite, gr as errMsg, ii as secretTreeFromSchema, qr as makeSecretMarker } from "../../dist-
|
|
2
|
+
import { Br as hydrateSchema, Fr as defineCustomActions, Gr as isSecretMarker, Pr as customAction, Wr as isSecretClear, _r as BaseAddon, ci as transformSecretWrite, gr as errMsg, ii as secretTreeFromSchema, qr as makeSecretMarker } from "../../dist-CXG6muCR.mjs";
|
|
3
3
|
import { t as require_safe_buffer } from "../../safe-buffer-B1OjL1I9.mjs";
|
|
4
4
|
import { a as KeyUsagesExtension, c as Pkcs10CertificateRequestGenerator, d as X509Certificate$1, f as X509CertificateGenerator, i as KeyUsageFlags, n as BasicConstraintsExtension, o as PemConverter, p as cryptoProvider, r as ExtendedKeyUsageExtension, s as Pkcs10CertificateRequest, t as AuthorityKeyIdentifierExtension, u as SubjectKeyIdentifierExtension } from "../../x509.es-CAjSsrkk.mjs";
|
|
5
5
|
import { a as setProcessAgentHttpsNames, n as AGENT_HTTPS_NAMES_COLUMNS, r as AgentHttpsNames, t as AGENT_HTTPS_NAMES_COLLECTION } from "../../agent-https-names-uetr4OQl.mjs";
|
|
6
|
-
import { a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, c as MESH_JOIN_TOKEN_MAX_TTL_SEC, d as CLUSTER_SECRET_REF, i as MESH_CA_FIELD, l as SERVER_AUTH_OID, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, r as MESH_CA_COMMON_NAME, s as MESH_CA_VALIDITY_DAYS, t as CLIENT_AUTH_OID, v as hashClusterSecret } from "../../constants-
|
|
6
|
+
import { a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, c as MESH_JOIN_TOKEN_MAX_TTL_SEC, d as CLUSTER_SECRET_REF, i as MESH_CA_FIELD, l as SERVER_AUTH_OID, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, r as MESH_CA_COMMON_NAME, s as MESH_CA_VALIDITY_DAYS, t as CLIENT_AUTH_OID, v as hashClusterSecret } from "../../constants-CttE77VF.mjs";
|
|
7
7
|
import { t as require_src } from "../../src-hG4grMU4.mjs";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { X509Certificate, createHash, createHmac, randomBytes, timingSafeEqual, webcrypto } from "node:crypto";
|
|
@@ -783,7 +783,7 @@ var MeshCertificateRegistry = class {
|
|
|
783
783
|
async recordObserved(nodeId, leaf) {
|
|
784
784
|
const known = this.rows.get(leaf.fingerprint);
|
|
785
785
|
if (known !== void 0) {
|
|
786
|
-
if (known.revokedReason !== "renewal-abandoned") return false;
|
|
786
|
+
if (known.revokedReason !== "renewal-abandoned") return known.revokedAt === null ? this.abandonRenewalsNewerThan(known) : false;
|
|
787
787
|
const reinstated = {
|
|
788
788
|
...known,
|
|
789
789
|
revokedAt: null,
|
|
@@ -899,6 +899,29 @@ var MeshCertificateRegistry = class {
|
|
|
899
899
|
return settled;
|
|
900
900
|
}
|
|
901
901
|
/** Set a never-completed renewal leaf aside (not current, NOT on the CRL). */
|
|
902
|
+
/** Fingerprints of renewal leaves whose handover is running right now (this process only). */
|
|
903
|
+
renewalsInFlight = /* @__PURE__ */ new Set();
|
|
904
|
+
/**
|
|
905
|
+
* A renewal's leaf is "in flight" from signing until the handover ends. While it is, a node seen
|
|
906
|
+
* presenting its OLD leaf is simply not swapped yet: the new leaf is not set aside (that would
|
|
907
|
+
* flap set-aside / reinstate on the node's first connection with it).
|
|
908
|
+
*/
|
|
909
|
+
beginRenewal(fingerprint) {
|
|
910
|
+
this.renewalsInFlight.add(fingerprint);
|
|
911
|
+
}
|
|
912
|
+
endRenewal(fingerprint) {
|
|
913
|
+
this.renewalsInFlight.delete(fingerprint);
|
|
914
|
+
}
|
|
915
|
+
async abandonRenewalsNewerThan(presented) {
|
|
916
|
+
let changed = false;
|
|
917
|
+
for (const record of this.liveFor(presented.nodeId)) {
|
|
918
|
+
if (record.fingerprint === presented.fingerprint) continue;
|
|
919
|
+
if (record.issuedVia !== "renewal" || record.issuedAt <= presented.issuedAt) continue;
|
|
920
|
+
if (this.renewalsInFlight.has(record.fingerprint)) continue;
|
|
921
|
+
if (await this.abandon(record.fingerprint)) changed = true;
|
|
922
|
+
}
|
|
923
|
+
return changed;
|
|
924
|
+
}
|
|
902
925
|
async abandon(fingerprint) {
|
|
903
926
|
const record = this.rows.get(fingerprint);
|
|
904
927
|
if (record === void 0 || record.revokedAt !== null) return false;
|
|
@@ -1054,6 +1077,24 @@ function message$1(error) {
|
|
|
1054
1077
|
return error instanceof Error ? error.message : String(error);
|
|
1055
1078
|
}
|
|
1056
1079
|
async function renewMeshCertificate(deps) {
|
|
1080
|
+
const inFlight = { fingerprint: null };
|
|
1081
|
+
try {
|
|
1082
|
+
return await runRenewal(deps, inFlight);
|
|
1083
|
+
} finally {
|
|
1084
|
+
if (inFlight.fingerprint !== null) {
|
|
1085
|
+
deps.registry.endRenewal(inFlight.fingerprint);
|
|
1086
|
+
const live = deps.peers.peerLeaf(deps.nodeId);
|
|
1087
|
+
if (live !== void 0) await deps.registry.recordObserved(deps.nodeId, {
|
|
1088
|
+
cn: deps.nodeId,
|
|
1089
|
+
serial: live.serial,
|
|
1090
|
+
fingerprint: live.fingerprint,
|
|
1091
|
+
notBefore: live.notBefore,
|
|
1092
|
+
notAfter: live.notAfter
|
|
1093
|
+
}).catch(() => void 0);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
async function runRenewal(deps, inFlight) {
|
|
1057
1098
|
const { nodeId, log } = deps;
|
|
1058
1099
|
const tags = { nodeId };
|
|
1059
1100
|
const sleep = deps.sleep ?? defaultSleep;
|
|
@@ -1115,12 +1156,28 @@ async function renewMeshCertificate(deps) {
|
|
|
1115
1156
|
return fail("issue", message$1(error), true);
|
|
1116
1157
|
}
|
|
1117
1158
|
const newLeaf = describeMeshLeaf(issued.certPem);
|
|
1159
|
+
deps.registry.beginRenewal(newLeaf.fingerprint);
|
|
1160
|
+
inFlight.fingerprint = newLeaf.fingerprint;
|
|
1118
1161
|
let resolveRegistered = () => void 0;
|
|
1119
1162
|
const registeredPromise = new Promise((resolve) => {
|
|
1120
1163
|
resolveRegistered = resolve;
|
|
1121
1164
|
});
|
|
1122
|
-
const
|
|
1123
|
-
|
|
1165
|
+
const expected = deps.expectedAddons?.(nodeId) ?? [];
|
|
1166
|
+
let missingAddons = [];
|
|
1167
|
+
const unsubscribe = deps.registrations.subscribe((id, addonIds) => {
|
|
1168
|
+
if (id !== nodeId || deps.peers.peerLeaf(nodeId)?.fingerprint !== newLeaf.fingerprint) return;
|
|
1169
|
+
if (addonIds !== void 0) {
|
|
1170
|
+
const present = new Set(addonIds);
|
|
1171
|
+
missingAddons = expected.filter((addonId) => !present.has(addonId));
|
|
1172
|
+
if (missingAddons.length > 0) {
|
|
1173
|
+
log.warn("Mesh renewal: the node registered without addons it had before - waiting", {
|
|
1174
|
+
tags,
|
|
1175
|
+
meta: { missing: missingAddons }
|
|
1176
|
+
});
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
resolveRegistered(true);
|
|
1124
1181
|
});
|
|
1125
1182
|
const deadlineTimer = setTimer(() => resolveRegistered(false), timeoutMs);
|
|
1126
1183
|
registeredPromise.then(() => deadlineTimer.cancel());
|
|
@@ -1151,7 +1208,8 @@ async function renewMeshCertificate(deps) {
|
|
|
1151
1208
|
}
|
|
1152
1209
|
});
|
|
1153
1210
|
await deps.registry.abandon(newLeaf.fingerprint);
|
|
1154
|
-
|
|
1211
|
+
const lost = missingAddons.length > 0 ? ` (its last registration lacked ${missingAddons.length} addon(s) it had before: ${missingAddons.slice(0, 5).join(", ")}; the swap was rolled back and nothing was revoked - once those addons are running again the next renewal will go through)` : "";
|
|
1212
|
+
return fail("reconnect", `the node was not back and registered with the new leaf within ${Math.round(timeoutMs / 1e3)} s${lost}; the previous leaf was kept and is still valid`, true);
|
|
1155
1213
|
}
|
|
1156
1214
|
log.info("Mesh renewal: the node registered presenting the new leaf", { tags });
|
|
1157
1215
|
let confirmError = "the node did not confirm the new leaf";
|
|
@@ -1271,10 +1329,14 @@ function onProcessNodeRegistered(listener) {
|
|
|
1271
1329
|
listeners.delete(listener);
|
|
1272
1330
|
};
|
|
1273
1331
|
}
|
|
1274
|
-
/**
|
|
1275
|
-
|
|
1332
|
+
/**
|
|
1333
|
+
* Called by the hub when a node's `registerNode` has been applied. `addonIds` is what that
|
|
1334
|
+
* registration carried (a node's own addons and its children's, D3), so a waiter can tell the
|
|
1335
|
+
* registration of a node that came back WHOLE from the first one of a node that lost its children.
|
|
1336
|
+
*/
|
|
1337
|
+
function emitProcessNodeRegistered(nodeId, addonIds) {
|
|
1276
1338
|
for (const listener of [...registrationListeners()]) try {
|
|
1277
|
-
listener(nodeId);
|
|
1339
|
+
listener(nodeId, addonIds);
|
|
1278
1340
|
} catch {}
|
|
1279
1341
|
}
|
|
1280
1342
|
//#endregion
|
|
@@ -87827,6 +87889,7 @@ var TlsTcpTransporter = class extends TcpTransporterBase {
|
|
|
87827
87889
|
});
|
|
87828
87890
|
server.on("error", (err) => {
|
|
87829
87891
|
this.logger.error("Mesh TLS server error.", err);
|
|
87892
|
+
if (this.tlsServer === server) this.tlsServer = null;
|
|
87830
87893
|
reject(err);
|
|
87831
87894
|
});
|
|
87832
87895
|
server.listen({
|
|
@@ -87836,9 +87899,9 @@ var TlsTcpTransporter = class extends TcpTransporterBase {
|
|
|
87836
87899
|
const address = server.address();
|
|
87837
87900
|
const port = address !== null && typeof address === "object" ? address.port : tlsPort;
|
|
87838
87901
|
this.logger.info(`Mesh TLS server is listening on port ${port}`);
|
|
87902
|
+
this.tlsServer = server;
|
|
87839
87903
|
resolve();
|
|
87840
87904
|
});
|
|
87841
|
-
this.tlsServer = server;
|
|
87842
87905
|
});
|
|
87843
87906
|
}
|
|
87844
87907
|
onTlsClientConnected(socket) {
|
|
@@ -88647,4 +88710,4 @@ function readJwtExp(token) {
|
|
|
88647
88710
|
return typeof exp === "number" ? exp : 0;
|
|
88648
88711
|
}
|
|
88649
88712
|
//#endregion
|
|
88650
|
-
export {
|
|
88713
|
+
export { verifyAgentUiUnlockTicket as $, setProcessMeshCertificateRegistry as A, generateMeshCa as B, setProcessMeshTlsListenerState as C, RENEWAL_ABANDONED as D, MeshCertificateRegistry as E, requireProcessMeshCa as F, AGENT_DASHBOARD_ORIGINS_FIELD as G, issueMeshLeafForNode as H, caFingerprint as I, AGENT_UI_UNLOCK_VERSION as J, AGENT_UI_UNLOCK_DOMAIN as K, caFingerprintCompact as L, processMeshCrl as M, MeshCaKeeper as N, describeMeshLeaf as O, getProcessMeshCaState as P, parseAgentDashboardOrigins as Q, createMeshCsrPem as R, openMeshTlsWhenRevocationsLoaded as S, SYSTEM_CONFIG_CLUSTER_SECTION_ID, SystemConfigAddon, SystemConfigAddon as default, MESH_NODE_CERTIFICATES_COLUMNS as T, issueMeshLeafFromCsr as U, generateMeshKeyPair as V, loadMeshCa as W, isAllowedAgentDashboardReturnTo as X, UnlockTicketJtiStore as Y, mintAgentUiUnlockTicket as Z, onProcessNodeRegistered as _, ServiceBroker as a, requestProcessMeshEnforcement as at, revokeMeshCertificate as b, enrollMeshNode as c, setProcessMeshEnforcer as ct, processJoinTokenJtiStore as d, parseCidrList as dt, MESH_AUTH_MODE_FIELD as et, verifyMeshJoinToken as f, readCidrSetting as ft, getProcessPeerLeaf as g, getProcessNodeMeshTransport as h, Errors as i, parseMeshAuthMode as it, MeshCrl as j, getProcessMeshCertificateRegistry as k, JoinTokenJtiStore as l, createCidrMatcher as lt, emitProcessNodeRegistered as m, MESH_TLS_PORT_HELLO_FIELD as n, getProcessMeshAuthStatus as nt, Transporters as o, setProcessMeshAuthMode as ot, dropProcessPeer as p, AGENT_UI_UNLOCK_TTL_MS as q, TlsTcpTransporter as r, isMeshAuthMode as rt, setProcessMeshTlsEnabler as s, setProcessMeshAuthStatusSource as st, systemConfigMeshActions as t, getProcessMeshAuthMode as tt, mintMeshJoinToken as u, normalizeIp as ut, setProcessMeshPeerTransportLookup as v, MESH_NODE_CERTIFICATES_COLLECTION as w, getProcessMeshTlsListenerState as x, renewMeshCertificate as y, exportMeshPrivateKeyPem as z };
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-DxJdci75.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _r as BaseAddon, an as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { _r as BaseAddon, an as logDestinationCapability } from "../../dist-CXG6muCR.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gr as errMsg, lr as compositionSourceKey } from "./dist-
|
|
1
|
+
import { gr as errMsg, lr as compositionSourceKey } from "./dist-CXG6muCR.mjs";
|
|
2
2
|
//#region src/builtins/core-blocks/composition-sources.ts
|
|
3
3
|
/**
|
|
4
4
|
* Describe what a composition reads and writes for SAVE-time validation
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ar as buildSecretRef, C as DEVICE_SAN_CREDENTIAL_PREFIX, w as DEVICE_SAN_USER_PREFIX } from "./dist-
|
|
1
|
+
import { Ar as buildSecretRef, C as DEVICE_SAN_CREDENTIAL_PREFIX, w as DEVICE_SAN_USER_PREFIX } from "./dist-CXG6muCR.mjs";
|
|
2
2
|
import { a as KeyUsagesExtension, d as X509Certificate$1, f as X509CertificateGenerator, i as KeyUsageFlags, l as SubjectAlternativeNameExtension, n as BasicConstraintsExtension, o as PemConverter, p as cryptoProvider, r as ExtendedKeyUsageExtension, t as AuthorityKeyIdentifierExtension, u as SubjectKeyIdentifierExtension } from "./x509.es-CAjSsrkk.mjs";
|
|
3
3
|
import { X509Certificate, createPublicKey, randomBytes, verify, webcrypto } from "node:crypto";
|
|
4
4
|
//#region src/auth/jwt-signing-key.ts
|