@camstack/system 1.2.435 → 1.2.437
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/{agent-https-B8lKYVtU.mjs → agent-https-BPfHrI4c.mjs} +3 -3
- package/dist/auth/login-session-manager.d.ts +2 -0
- package/dist/auth/session-revocation-bus.d.ts +32 -0
- 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 +5 -5
- 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 +6 -7
- package/dist/builtins/keychain/index.mjs +6 -7
- package/dist/builtins/keychain/keychain-service.d.ts +1 -2
- package/dist/builtins/keychain/system-held-secrets.d.ts +5 -5
- 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 +43 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +43 -3
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +4 -4
- 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 +10 -10
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +8 -8
- 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/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 +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
- 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.d.ts +11 -23
- package/dist/builtins/system-config/system-config.addon.js +219 -1479
- package/dist/builtins/system-config/system-config.addon.mjs +222 -1472
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-Cm42mgbv.js → composition-sources-BIT8IUKm.js} +1 -1
- package/dist/{composition-sources-_7W2Ly9s.mjs → composition-sources-tpYR0f1x.mjs} +1 -1
- package/dist/constants-Bc6trhoW.mjs +20 -0
- package/dist/constants-CwRY32Nx.js +66 -0
- package/dist/{device-ca-B6YJZus6.mjs → device-ca-BhdBByGD.mjs} +1 -1
- package/dist/{device-ca-WXuKc8AX.js → device-ca-DImD8IzR.js} +1 -1
- package/dist/{dist-CnUtkSwN.js → dist-CEAyXW3Q.js} +42 -12
- package/dist/{dist-Bz4_y8Xy.mjs → dist-m5JkT8UN.mjs} +33 -3
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-DJRwtlA8.mjs → hub-mdns-ciao-DMlQTdPU.mjs} +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +135 -796
- package/dist/index.mjs +150 -769
- package/dist/kernel/index.d.ts +7 -21
- package/dist/kernel/moleculer/agent-ui-unlock.d.ts +7 -32
- package/dist/kernel/moleculer/broker-factory.d.ts +3 -9
- package/dist/kernel/moleculer/broker-transport-swap.d.ts +17 -0
- package/dist/kernel/moleculer/hub-service.d.ts +6 -16
- package/dist/kernel/moleculer/mesh-access-middleware.d.ts +7 -17
- package/dist/kernel/moleculer/mesh-identity.d.ts +57 -0
- package/dist/kernel/moleculer/mesh-mtls/constants.d.ts +1 -4
- package/dist/kernel/moleculer/mesh-mtls/index.d.ts +1 -4
- package/dist/kernel/moleculer/mesh-mtls/mesh-ca.d.ts +1 -1
- package/dist/kernel/moleculer/mesh-mtls/mesh-renewal.d.ts +1 -1
- package/dist/kernel/moleculer/node-registry.d.ts +0 -6
- package/dist/kernel/moleculer/register-node-client.d.ts +9 -7
- package/dist/{restore-archive-BNoFLAg8.js → restore-archive-C75srVbG.js} +1 -1
- package/dist/{restore-archive-DJYuznWP.mjs → restore-archive-DNxAStrJ.mjs} +1 -1
- package/dist/{retired-settings-keys-9nA85bwT.mjs → retired-settings-keys-C5qP9QIf.mjs} +1 -1
- package/dist/{retired-settings-keys-CO3RqsDw.js → retired-settings-keys-DNfV28R_.js} +1 -1
- package/dist/{wal-maintenance-D3gwRj1B.js → wal-maintenance-Ch79gy9S.js} +0 -0
- package/dist/{wal-maintenance-DLrbapzi.mjs → wal-maintenance-DvnVO5IK.mjs} +0 -0
- package/package.json +1 -1
- package/dist/builtins/system-config/cluster-secret-keeper.d.ts +0 -63
- package/dist/constants-DL87WgeN.js +0 -221
- package/dist/constants-DoiTA134.mjs +0 -102
- package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +0 -91
- package/dist/kernel/moleculer/cluster-secret.d.ts +0 -46
- package/dist/kernel/moleculer/mesh-auth-mode.d.ts +0 -58
- package/dist/kernel/moleculer/mesh-authenticator.d.ts +0 -77
- package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +0 -46
- package/dist/kernel/moleculer/mesh-join-client.d.ts +0 -73
- package/dist/kernel/moleculer/mesh-join-hold.d.ts +0 -85
- package/dist/kernel/moleculer/mesh-join-proof.d.ts +0 -39
- package/dist/kernel/moleculer/mesh-mtls/mesh-enroll.d.ts +0 -34
- package/dist/kernel/moleculer/mesh-mtls/mesh-join-token.d.ts +0 -56
|
@@ -3,17 +3,19 @@ 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-CEAyXW3Q.js");
|
|
7
7
|
const require_safe_buffer$1 = require("../../safe-buffer-D3aoa-7X.js");
|
|
8
8
|
const require_x509_es = require("../../x509.es-r7Ht1thA.js");
|
|
9
9
|
const require_agent_https = require("../../agent-https-BZIwS4xF.js");
|
|
10
|
-
const require_constants$8 = require("../../constants-
|
|
10
|
+
const require_constants$8 = require("../../constants-CwRY32Nx.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");
|
|
14
14
|
let node_net = require("node:net");
|
|
15
15
|
let node_fs_promises = require("node:fs/promises");
|
|
16
16
|
let node_path = require("node:path");
|
|
17
|
+
let node_os = require("node:os");
|
|
18
|
+
node_os = require_chunk.__toESM(node_os);
|
|
17
19
|
let node_url = require("node:url");
|
|
18
20
|
let node_fs = require("node:fs");
|
|
19
21
|
node_fs = require_chunk.__toESM(node_fs, 1);
|
|
@@ -106,73 +108,27 @@ function createCidrMatcher(entries) {
|
|
|
106
108
|
};
|
|
107
109
|
}
|
|
108
110
|
//#endregion
|
|
109
|
-
//#region src/kernel/moleculer/mesh-auth-mode.ts
|
|
110
|
-
/** The field key inside the `cluster` section. */
|
|
111
|
-
var MESH_AUTH_MODE_FIELD = "meshAuth";
|
|
112
|
-
function isMeshAuthMode(value) {
|
|
113
|
-
return value === "transition" || value === "enforced";
|
|
114
|
-
}
|
|
115
|
-
/** A stored value that is not a mode reads as `transition`: never refuse on a typo. */
|
|
116
|
-
function parseMeshAuthMode(value) {
|
|
117
|
-
return isMeshAuthMode(value) ? value : "transition";
|
|
118
|
-
}
|
|
119
|
-
var MODE_SLOT = Symbol.for("camstack.cluster.mesh-auth-mode");
|
|
120
|
-
var ENFORCER_SLOT = Symbol.for("camstack.cluster.mesh-auth-enforcer");
|
|
121
|
-
var STATUS_SLOT = Symbol.for("camstack.cluster.mesh-auth-status");
|
|
122
|
-
/** Published by `system-config` whenever the stored mode is (re)read. */
|
|
123
|
-
function setProcessMeshAuthMode(mode) {
|
|
124
|
-
Reflect.set(globalThis, MODE_SLOT, mode);
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* The hub's mode. Until `system-config` has read it: `transition` — the safe
|
|
128
|
-
* side for an upgrading cluster (nothing that worked before is refused), and
|
|
129
|
-
* exactly what an unread setting means.
|
|
130
|
-
*/
|
|
131
|
-
function getProcessMeshAuthMode() {
|
|
132
|
-
return parseMeshAuthMode(Reflect.get(globalThis, MODE_SLOT));
|
|
133
|
-
}
|
|
134
|
-
function setProcessMeshEnforcer(enforcer) {
|
|
135
|
-
if (enforcer === null) Reflect.deleteProperty(globalThis, ENFORCER_SLOT);
|
|
136
|
-
else Reflect.set(globalThis, ENFORCER_SLOT, enforcer);
|
|
137
|
-
}
|
|
138
|
-
/** Ask the owner of the setting to switch to `enforced`. `false` when nobody can. */
|
|
139
|
-
async function requestProcessMeshEnforcement(reason) {
|
|
140
|
-
const enforcer = Reflect.get(globalThis, ENFORCER_SLOT);
|
|
141
|
-
if (typeof enforcer !== "function") return false;
|
|
142
|
-
await enforcer(reason);
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
/** Published by the hub's broker; read by System → Cluster. */
|
|
146
|
-
function setProcessMeshAuthStatusSource(source) {
|
|
147
|
-
if (source === null) Reflect.deleteProperty(globalThis, STATUS_SLOT);
|
|
148
|
-
else Reflect.set(globalThis, STATUS_SLOT, source);
|
|
149
|
-
}
|
|
150
|
-
function getProcessMeshAuthStatus() {
|
|
151
|
-
const source = Reflect.get(globalThis, STATUS_SLOT);
|
|
152
|
-
return typeof source === "function" ? source() : null;
|
|
153
|
-
}
|
|
154
|
-
//#endregion
|
|
155
111
|
//#region src/kernel/moleculer/agent-ui-unlock.ts
|
|
156
112
|
/**
|
|
157
|
-
* Agent UI remote unlock tickets (D821).
|
|
113
|
+
* Agent UI remote unlock tickets (D821, re-keyed by D857).
|
|
158
114
|
*
|
|
159
|
-
* A hub admin mints a short-lived
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
115
|
+
* A hub admin mints a short-lived ticket bound to one agent `nodeId`, signed
|
|
116
|
+
* with the MESH CA key (ES256 JWS). The agent verifies it
|
|
117
|
+
* with the CA certificate it pinned at pairing and redeems it once for a tab
|
|
118
|
+
* session Bearer. There is no shared secret: a ticket is worth exactly as much
|
|
119
|
+
* as the CA key that signed it, and the agent trusts exactly the CA its
|
|
120
|
+
* operator confirmed during pairing.
|
|
163
121
|
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* payload = { v: 1, nodeId, exp (ms), jti }
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* D857 (transition release): a ticket signed by the MESH CA key (ES256 JWS) is accepted by an agent
|
|
172
|
-
* IN ADDITION to the HMAC ticket. The removal release mints only this form.
|
|
122
|
+
* ticket = b64url(header) '.' b64url(payload) '.' b64url(ES256 signature)
|
|
123
|
+
* header = { alg: 'ES256', typ: 'camstack-agent-ui-unlock+jwt' }
|
|
124
|
+
* payload = { v: 1, use: 'agent-ui-unlock', nodeId, iat (ms), exp (ms), jti }
|
|
125
|
+
*
|
|
126
|
+
* The `typ` and `use` pins keep a join token or a pairing proof (also signed
|
|
127
|
+
* by the CA key) from ever being accepted here, and the reverse.
|
|
173
128
|
*/
|
|
174
129
|
var AGENT_UI_UNLOCK_TYP = "camstack-agent-ui-unlock+jwt";
|
|
175
130
|
var AGENT_UI_UNLOCK_USE = "agent-ui-unlock";
|
|
131
|
+
var AGENT_UI_UNLOCK_VERSION = 1;
|
|
176
132
|
/** Ticket lifetime — long enough for a redirect hop, short enough to steal poorly. */
|
|
177
133
|
var AGENT_UI_UNLOCK_TTL_MS = 5 * 6e4;
|
|
178
134
|
/**
|
|
@@ -202,18 +158,28 @@ var UnlockTicketJtiStore = class {
|
|
|
202
158
|
for (const [jti, exp] of this.spent) if (exp <= nowMs) this.spent.delete(jti);
|
|
203
159
|
}
|
|
204
160
|
};
|
|
161
|
+
function b64urlJson$1(value) {
|
|
162
|
+
return Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
163
|
+
}
|
|
205
164
|
function mintAgentUiUnlockTicket(input) {
|
|
206
165
|
const nowMs = input.nowMs ?? Date.now();
|
|
207
166
|
const ttl = Math.min(Math.max(1e3, input.ttlMs ?? 3e5), AGENT_UI_UNLOCK_TTL_MS);
|
|
208
167
|
const payload = {
|
|
209
168
|
v: 1,
|
|
169
|
+
use: AGENT_UI_UNLOCK_USE,
|
|
210
170
|
nodeId: input.nodeId,
|
|
211
171
|
iat: nowMs,
|
|
212
172
|
exp: nowMs + ttl,
|
|
213
173
|
jti: input.jti ?? (0, node_crypto.randomBytes)(16).toString("base64url")
|
|
214
174
|
};
|
|
215
|
-
const
|
|
216
|
-
|
|
175
|
+
const signingInput = `${b64urlJson$1({
|
|
176
|
+
alg: "ES256",
|
|
177
|
+
typ: AGENT_UI_UNLOCK_TYP
|
|
178
|
+
})}.${b64urlJson$1(payload)}`;
|
|
179
|
+
return `${signingInput}.${(0, node_crypto.sign)("sha256", Buffer.from(signingInput, "utf8"), {
|
|
180
|
+
key: (0, node_crypto.createPrivateKey)(input.caKeyPem),
|
|
181
|
+
dsaEncoding: "ieee-p1363"
|
|
182
|
+
}).toString("base64url")}`;
|
|
217
183
|
}
|
|
218
184
|
/** A ticket is issued now-ish, lives at most the TTL, and not before `notBeforeMs`. */
|
|
219
185
|
function issuedSanely(payload, nowMs, notBeforeMs) {
|
|
@@ -222,22 +188,36 @@ function issuedSanely(payload, nowMs, notBeforeMs) {
|
|
|
222
188
|
return notBeforeMs === void 0 || payload.iat >= notBeforeMs;
|
|
223
189
|
}
|
|
224
190
|
/**
|
|
225
|
-
* Verify a ticket
|
|
226
|
-
* signature, shape, expiry or nodeId fails
|
|
191
|
+
* Verify a ticket against the mesh CA certificate the agent pinned. Returns the
|
|
192
|
+
* payload, or `null` when the signature, header, shape, expiry or nodeId fails
|
|
193
|
+
* (no reason string — refuse quietly).
|
|
227
194
|
*/
|
|
228
|
-
function verifyAgentUiUnlockTicket(
|
|
195
|
+
function verifyAgentUiUnlockTicket(caCertPem, ticket, options) {
|
|
229
196
|
const nowMs = options.nowMs ?? Date.now();
|
|
230
|
-
const
|
|
231
|
-
if (
|
|
232
|
-
const payloadB64 =
|
|
233
|
-
|
|
234
|
-
|
|
197
|
+
const parts = ticket.split(".");
|
|
198
|
+
if (parts.length !== 3) return null;
|
|
199
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
200
|
+
if (headerB64 === void 0 || payloadB64 === void 0 || signatureB64 === void 0) return null;
|
|
201
|
+
let header;
|
|
235
202
|
let parsed;
|
|
236
203
|
try {
|
|
204
|
+
header = JSON.parse(Buffer.from(headerB64, "base64url").toString("utf8"));
|
|
237
205
|
parsed = JSON.parse(Buffer.from(payloadB64, "base64url").toString("utf8"));
|
|
238
206
|
} catch {
|
|
239
207
|
return null;
|
|
240
208
|
}
|
|
209
|
+
if (typeof header !== "object" || header === null) return null;
|
|
210
|
+
if (Reflect.get(header, "alg") !== "ES256" || Reflect.get(header, "typ") !== "camstack-agent-ui-unlock+jwt") return null;
|
|
211
|
+
let valid = false;
|
|
212
|
+
try {
|
|
213
|
+
valid = (0, node_crypto.verify)("sha256", Buffer.from(`${headerB64}.${payloadB64}`, "utf8"), {
|
|
214
|
+
key: new node_crypto.X509Certificate(caCertPem).publicKey,
|
|
215
|
+
dsaEncoding: "ieee-p1363"
|
|
216
|
+
}, Buffer.from(signatureB64, "base64url"));
|
|
217
|
+
} catch {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
if (!valid) return null;
|
|
241
221
|
const payload = parsePayload(parsed);
|
|
242
222
|
if (payload === null) return null;
|
|
243
223
|
if (payload.exp <= nowMs) return null;
|
|
@@ -296,96 +276,7 @@ function parseAgentDashboardOrigins(stored) {
|
|
|
296
276
|
}
|
|
297
277
|
return out;
|
|
298
278
|
}
|
|
299
|
-
function sign$1(secretHash, payloadB64) {
|
|
300
|
-
return (0, node_crypto.createHmac)("sha256", Buffer.from(secretHash, "utf8")).update(`${AGENT_UI_UNLOCK_DOMAIN}|${payloadB64}`, "utf8").digest("base64url");
|
|
301
|
-
}
|
|
302
|
-
function sigsEqual(expected, presented) {
|
|
303
|
-
const a = Buffer.from(expected, "utf8");
|
|
304
|
-
const b = Buffer.from(presented, "utf8");
|
|
305
|
-
if (a.length !== b.length) return false;
|
|
306
|
-
return (0, node_crypto.timingSafeEqual)(a, b);
|
|
307
|
-
}
|
|
308
279
|
function parsePayload(value) {
|
|
309
|
-
if (typeof value !== "object" || value === null) return null;
|
|
310
|
-
const rec = value;
|
|
311
|
-
if (rec["v"] !== 1) return null;
|
|
312
|
-
const nodeId = rec["nodeId"];
|
|
313
|
-
const exp = rec["exp"];
|
|
314
|
-
const jti = rec["jti"];
|
|
315
|
-
if (typeof nodeId !== "string" || nodeId.length === 0) return null;
|
|
316
|
-
if (typeof exp !== "number" || !Number.isFinite(exp)) return null;
|
|
317
|
-
if (typeof jti !== "string" || jti.length === 0) return null;
|
|
318
|
-
const iat = rec["iat"];
|
|
319
|
-
return {
|
|
320
|
-
v: 1,
|
|
321
|
-
nodeId,
|
|
322
|
-
iat: typeof iat === "number" && Number.isFinite(iat) ? iat : exp - AGENT_UI_UNLOCK_TTL_MS,
|
|
323
|
-
exp,
|
|
324
|
-
jti
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
function b64urlJsonEs256(value) {
|
|
328
|
-
return Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
329
|
-
}
|
|
330
|
-
function mintAgentUiUnlockTicketEs256(input) {
|
|
331
|
-
const nowMs = input.nowMs ?? Date.now();
|
|
332
|
-
const ttl = Math.min(Math.max(1e3, input.ttlMs ?? 3e5), AGENT_UI_UNLOCK_TTL_MS);
|
|
333
|
-
const payload = {
|
|
334
|
-
v: 1,
|
|
335
|
-
use: AGENT_UI_UNLOCK_USE,
|
|
336
|
-
nodeId: input.nodeId,
|
|
337
|
-
iat: nowMs,
|
|
338
|
-
exp: nowMs + ttl,
|
|
339
|
-
jti: input.jti ?? (0, node_crypto.randomBytes)(16).toString("base64url")
|
|
340
|
-
};
|
|
341
|
-
const signingInput = `${b64urlJsonEs256({
|
|
342
|
-
alg: "ES256",
|
|
343
|
-
typ: AGENT_UI_UNLOCK_TYP
|
|
344
|
-
})}.${b64urlJsonEs256(payload)}`;
|
|
345
|
-
return `${signingInput}.${(0, node_crypto.sign)("sha256", Buffer.from(signingInput, "utf8"), {
|
|
346
|
-
key: (0, node_crypto.createPrivateKey)(input.caKeyPem),
|
|
347
|
-
dsaEncoding: "ieee-p1363"
|
|
348
|
-
}).toString("base64url")}`;
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Verify a ticket against the mesh CA certificate the agent pinned. Returns the
|
|
352
|
-
* payload, or `null` when the signature, header, shape, expiry or nodeId fails
|
|
353
|
-
* (no reason string — refuse quietly).
|
|
354
|
-
*/
|
|
355
|
-
function verifyAgentUiUnlockTicketEs256(caCertPem, ticket, options) {
|
|
356
|
-
const nowMs = options.nowMs ?? Date.now();
|
|
357
|
-
const parts = ticket.split(".");
|
|
358
|
-
if (parts.length !== 3) return null;
|
|
359
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
360
|
-
if (headerB64 === void 0 || payloadB64 === void 0 || signatureB64 === void 0) return null;
|
|
361
|
-
let header;
|
|
362
|
-
let parsed;
|
|
363
|
-
try {
|
|
364
|
-
header = JSON.parse(Buffer.from(headerB64, "base64url").toString("utf8"));
|
|
365
|
-
parsed = JSON.parse(Buffer.from(payloadB64, "base64url").toString("utf8"));
|
|
366
|
-
} catch {
|
|
367
|
-
return null;
|
|
368
|
-
}
|
|
369
|
-
if (typeof header !== "object" || header === null) return null;
|
|
370
|
-
if (Reflect.get(header, "alg") !== "ES256" || Reflect.get(header, "typ") !== "camstack-agent-ui-unlock+jwt") return null;
|
|
371
|
-
let valid = false;
|
|
372
|
-
try {
|
|
373
|
-
valid = (0, node_crypto.verify)("sha256", Buffer.from(`${headerB64}.${payloadB64}`, "utf8"), {
|
|
374
|
-
key: new node_crypto.X509Certificate(caCertPem).publicKey,
|
|
375
|
-
dsaEncoding: "ieee-p1363"
|
|
376
|
-
}, Buffer.from(signatureB64, "base64url"));
|
|
377
|
-
} catch {
|
|
378
|
-
return null;
|
|
379
|
-
}
|
|
380
|
-
if (!valid) return null;
|
|
381
|
-
const payload = parsePayloadEs256(parsed);
|
|
382
|
-
if (payload === null) return null;
|
|
383
|
-
if (payload.exp <= nowMs) return null;
|
|
384
|
-
if (payload.nodeId !== options.expectedNodeId) return null;
|
|
385
|
-
if (!issuedSanely(payload, nowMs, options.notBeforeMs)) return null;
|
|
386
|
-
return payload;
|
|
387
|
-
}
|
|
388
|
-
function parsePayloadEs256(value) {
|
|
389
280
|
if (typeof value !== "object" || value === null) return null;
|
|
390
281
|
const rec = value;
|
|
391
282
|
if (rec["v"] !== 1) return null;
|
|
@@ -393,10 +284,10 @@ function parsePayloadEs256(value) {
|
|
|
393
284
|
const nodeId = rec["nodeId"];
|
|
394
285
|
const exp = rec["exp"];
|
|
395
286
|
const jti = rec["jti"];
|
|
287
|
+
const iat = rec["iat"];
|
|
396
288
|
if (typeof nodeId !== "string" || nodeId.length === 0) return null;
|
|
397
289
|
if (typeof exp !== "number" || !Number.isFinite(exp)) return null;
|
|
398
290
|
if (typeof jti !== "string" || jti.length === 0) return null;
|
|
399
|
-
const iat = rec["iat"];
|
|
400
291
|
if (typeof iat !== "number" || !Number.isFinite(iat)) return null;
|
|
401
292
|
return {
|
|
402
293
|
v: 1,
|
|
@@ -412,7 +303,7 @@ function parsePayloadEs256(value) {
|
|
|
412
303
|
* Hub mesh CA — EC P-256, key in the keychain, cert in `cluster.meshCa`.
|
|
413
304
|
*
|
|
414
305
|
* Distinct from the HTTPS local CA (`tls/cert-issue.ts`, RSA): the mesh CA
|
|
415
|
-
* signs node leaves (CN = nodeID) and
|
|
306
|
+
* signs node leaves (CN = nodeID) and unlock-ticket JWS (ES256). Issuance uses
|
|
416
307
|
* `@peculiar/x509` over WebCrypto — same library the HTTPS path already uses
|
|
417
308
|
* (installed `1.14.3`; registry latest at adoption time was `2.1.0` — stay on
|
|
418
309
|
* the pinned range already shipping).
|
|
@@ -453,7 +344,7 @@ async function exportKeyPem(key) {
|
|
|
453
344
|
function caFingerprint(certPem) {
|
|
454
345
|
return new node_crypto.X509Certificate(certPem).fingerprint256;
|
|
455
346
|
}
|
|
456
|
-
/** Compact fingerprint (lowercase hex, no colons)
|
|
347
|
+
/** Compact fingerprint (lowercase hex, no colons). */
|
|
457
348
|
function caFingerprintCompact(certPem) {
|
|
458
349
|
return (0, node_crypto.createHash)("sha256").update(new node_crypto.X509Certificate(certPem).raw).digest("hex");
|
|
459
350
|
}
|
|
@@ -1219,7 +1110,7 @@ function defaultSetTimer(fn, ms) {
|
|
|
1219
1110
|
function defaultSleep(ms) {
|
|
1220
1111
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1221
1112
|
}
|
|
1222
|
-
function message
|
|
1113
|
+
function message(error) {
|
|
1223
1114
|
return error instanceof Error ? error.message : String(error);
|
|
1224
1115
|
}
|
|
1225
1116
|
async function renewMeshCertificate(deps) {
|
|
@@ -1285,7 +1176,7 @@ async function runRenewal(deps, inFlight) {
|
|
|
1285
1176
|
csrPem = (await deps.client.prepareMeshRenewal()).csrPem;
|
|
1286
1177
|
log.info("Mesh renewal: the node generated a new key and sent its CSR", { tags });
|
|
1287
1178
|
} catch (error) {
|
|
1288
|
-
return fail("prepare", message
|
|
1179
|
+
return fail("prepare", message(error), true);
|
|
1289
1180
|
}
|
|
1290
1181
|
let issued;
|
|
1291
1182
|
try {
|
|
@@ -1299,7 +1190,7 @@ async function runRenewal(deps, inFlight) {
|
|
|
1299
1190
|
}
|
|
1300
1191
|
});
|
|
1301
1192
|
} catch (error) {
|
|
1302
|
-
return fail("issue", message
|
|
1193
|
+
return fail("issue", message(error), true);
|
|
1303
1194
|
}
|
|
1304
1195
|
const newLeaf = describeMeshLeaf(issued.certPem);
|
|
1305
1196
|
deps.registry.beginRenewal(newLeaf.fingerprint);
|
|
@@ -1339,7 +1230,7 @@ async function runRenewal(deps, inFlight) {
|
|
|
1339
1230
|
deadlineTimer.cancel();
|
|
1340
1231
|
await deps.client.rollbackMeshLeaf().catch(() => void 0);
|
|
1341
1232
|
await deps.registry.abandon(newLeaf.fingerprint);
|
|
1342
|
-
return fail("install", message
|
|
1233
|
+
return fail("install", message(error), true);
|
|
1343
1234
|
}
|
|
1344
1235
|
const deadline = now() + timeoutMs;
|
|
1345
1236
|
const registered = await registeredPromise;
|
|
@@ -1368,7 +1259,7 @@ async function runRenewal(deps, inFlight) {
|
|
|
1368
1259
|
}
|
|
1369
1260
|
confirmError = "the node did not confirm the new leaf";
|
|
1370
1261
|
} catch (error) {
|
|
1371
|
-
confirmError = message
|
|
1262
|
+
confirmError = message(error);
|
|
1372
1263
|
log.warn("Mesh renewal: confirm not accepted yet", {
|
|
1373
1264
|
tags,
|
|
1374
1265
|
meta: { error: confirmError }
|
|
@@ -1402,7 +1293,7 @@ async function runRenewal(deps, inFlight) {
|
|
|
1402
1293
|
}
|
|
1403
1294
|
/**
|
|
1404
1295
|
* Revoke every live mesh leaf of `nodeId` and cut its connection. The node cannot
|
|
1405
|
-
* reconnect: it must
|
|
1296
|
+
* reconnect: it must be paired again. The node is NOT forgotten
|
|
1406
1297
|
* (that stays `clusterNodes.forgetNode`).
|
|
1407
1298
|
*/
|
|
1408
1299
|
async function revokeMeshCertificate(deps) {
|
|
@@ -1429,7 +1320,7 @@ async function revokeMeshCertificate(deps) {
|
|
|
1429
1320
|
nodeId,
|
|
1430
1321
|
revokedSerials: serials,
|
|
1431
1322
|
disconnected,
|
|
1432
|
-
next: "The node can no longer connect.
|
|
1323
|
+
next: "The node can no longer connect. Pair it again from the hub (System -> Cluster -> Agents); to remove it from the cluster use Forget node."
|
|
1433
1324
|
};
|
|
1434
1325
|
}
|
|
1435
1326
|
//#endregion
|
|
@@ -1490,872 +1381,6 @@ function emitProcessNodeRegistered(nodeId, addonIds) {
|
|
|
1490
1381
|
} catch {}
|
|
1491
1382
|
}
|
|
1492
1383
|
//#endregion
|
|
1493
|
-
//#region ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
1494
|
-
var encoder = new TextEncoder(), decoder = new TextDecoder(), strictDecoder = new TextDecoder("utf-8", { fatal: !0 });
|
|
1495
|
-
function concat(...buffers) {
|
|
1496
|
-
const size = buffers.reduce((acc, { length }) => acc + length, 0), buf = new Uint8Array(size);
|
|
1497
|
-
let i = 0;
|
|
1498
|
-
for (const buffer of buffers) buf.set(buffer, i), i += buffer.length;
|
|
1499
|
-
return buf;
|
|
1500
|
-
}
|
|
1501
|
-
var NON_ASCII = /[^\x00-\x7f]/;
|
|
1502
|
-
function encode$1(string) {
|
|
1503
|
-
if (typeof string == "string" && string.length >= 128) {
|
|
1504
|
-
if (NON_ASCII.test(string)) throw new TypeError("non-ASCII string encountered in encode()");
|
|
1505
|
-
return encoder.encode(string);
|
|
1506
|
-
}
|
|
1507
|
-
const bytes = new Uint8Array(string.length);
|
|
1508
|
-
for (let i = 0; i < string.length; i++) {
|
|
1509
|
-
const code = string.charCodeAt(i);
|
|
1510
|
-
if (code > 127) throw new TypeError("non-ASCII string encountered in encode()");
|
|
1511
|
-
bytes[i] = code;
|
|
1512
|
-
}
|
|
1513
|
-
return bytes;
|
|
1514
|
-
}
|
|
1515
|
-
function encodeBase64(input, url = !1) {
|
|
1516
|
-
if (Uint8Array.prototype.toBase64) return input.toBase64({
|
|
1517
|
-
alphabet: url ? "base64url" : "base64",
|
|
1518
|
-
omitPadding: url
|
|
1519
|
-
});
|
|
1520
|
-
const CHUNK_SIZE = 32768, arr = [];
|
|
1521
|
-
for (let i = 0; i < input.length; i += CHUNK_SIZE) arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
|
|
1522
|
-
const encoded = btoa(arr.join(""));
|
|
1523
|
-
return url ? encoded.replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_") : encoded;
|
|
1524
|
-
}
|
|
1525
|
-
function decodeBase64(encoded, url = !1) {
|
|
1526
|
-
if (Uint8Array.fromBase64) return Uint8Array.fromBase64(encoded, { alphabet: url ? "base64url" : "base64" });
|
|
1527
|
-
if (url) {
|
|
1528
|
-
if (encoded.includes("+") || encoded.includes("/")) throw new TypeError("Invalid base64url");
|
|
1529
|
-
encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
1530
|
-
}
|
|
1531
|
-
const binary = atob(encoded), bytes = new Uint8Array(binary.length);
|
|
1532
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
1533
|
-
return bytes;
|
|
1534
|
-
}
|
|
1535
|
-
//#endregion
|
|
1536
|
-
//#region ../../node_modules/jose/dist/webapi/util/errors.js
|
|
1537
|
-
var JOSEError = class extends Error {
|
|
1538
|
-
static code = "ERR_JOSE_GENERIC";
|
|
1539
|
-
code = "ERR_JOSE_GENERIC";
|
|
1540
|
-
constructor(message, options) {
|
|
1541
|
-
super(message, options), this.name = this.constructor.name, Error.captureStackTrace?.(this, this.constructor);
|
|
1542
|
-
}
|
|
1543
|
-
};
|
|
1544
|
-
var JWTClaimValidationFailed = class extends JOSEError {
|
|
1545
|
-
static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
1546
|
-
code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
|
|
1547
|
-
claim;
|
|
1548
|
-
reason;
|
|
1549
|
-
payload;
|
|
1550
|
-
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
1551
|
-
super(message, { cause: {
|
|
1552
|
-
claim,
|
|
1553
|
-
reason,
|
|
1554
|
-
payload
|
|
1555
|
-
} }), this.claim = claim, this.reason = reason, this.payload = payload;
|
|
1556
|
-
}
|
|
1557
|
-
};
|
|
1558
|
-
var JWTExpired = class extends JOSEError {
|
|
1559
|
-
static code = "ERR_JWT_EXPIRED";
|
|
1560
|
-
code = "ERR_JWT_EXPIRED";
|
|
1561
|
-
claim;
|
|
1562
|
-
reason;
|
|
1563
|
-
payload;
|
|
1564
|
-
constructor(message, payload, claim = "unspecified", reason = "unspecified") {
|
|
1565
|
-
super(message, { cause: {
|
|
1566
|
-
claim,
|
|
1567
|
-
reason,
|
|
1568
|
-
payload
|
|
1569
|
-
} }), this.claim = claim, this.reason = reason, this.payload = payload;
|
|
1570
|
-
}
|
|
1571
|
-
};
|
|
1572
|
-
var JOSEAlgNotAllowed = class extends JOSEError {
|
|
1573
|
-
static code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
1574
|
-
code = "ERR_JOSE_ALG_NOT_ALLOWED";
|
|
1575
|
-
};
|
|
1576
|
-
var JOSENotSupported = class extends JOSEError {
|
|
1577
|
-
static code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1578
|
-
code = "ERR_JOSE_NOT_SUPPORTED";
|
|
1579
|
-
};
|
|
1580
|
-
var JWSInvalid = class extends JOSEError {
|
|
1581
|
-
static code = "ERR_JWS_INVALID";
|
|
1582
|
-
code = "ERR_JWS_INVALID";
|
|
1583
|
-
};
|
|
1584
|
-
var JWTInvalid = class extends JOSEError {
|
|
1585
|
-
static code = "ERR_JWT_INVALID";
|
|
1586
|
-
code = "ERR_JWT_INVALID";
|
|
1587
|
-
};
|
|
1588
|
-
var JWSSignatureVerificationFailed = class extends JOSEError {
|
|
1589
|
-
static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1590
|
-
code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
|
|
1591
|
-
constructor(message = "signature verification failed", options) {
|
|
1592
|
-
super(message, options);
|
|
1593
|
-
}
|
|
1594
|
-
};
|
|
1595
|
-
//#endregion
|
|
1596
|
-
//#region ../../node_modules/jose/dist/webapi/util/base64url.js
|
|
1597
|
-
var invalid = "The input to be decoded is not correctly encoded.";
|
|
1598
|
-
function decode(input) {
|
|
1599
|
-
try {
|
|
1600
|
-
return decodeBase64(typeof input == "string" ? input : decoder.decode(input), !0);
|
|
1601
|
-
} catch (cause) {
|
|
1602
|
-
throw new TypeError(invalid, { cause });
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
function encode(input) {
|
|
1606
|
-
return encodeBase64(typeof input == "string" ? encoder.encode(input) : input, !0);
|
|
1607
|
-
}
|
|
1608
|
-
//#endregion
|
|
1609
|
-
//#region ../../node_modules/jose/dist/webapi/lib/validate.js
|
|
1610
|
-
function isObject$1(input) {
|
|
1611
|
-
if (typeof input != "object" || input === null || Object.prototype.toString.call(input) !== "[object Object]") return !1;
|
|
1612
|
-
const prototype = Object.getPrototypeOf(input);
|
|
1613
|
-
return prototype === null || Object.getPrototypeOf(prototype) === null;
|
|
1614
|
-
}
|
|
1615
|
-
function isDisjoint(...headers) {
|
|
1616
|
-
const parameters = /* @__PURE__ */ new Set();
|
|
1617
|
-
for (const header of headers) if (header) for (const parameter of Object.keys(header)) {
|
|
1618
|
-
if (parameters.has(parameter)) return !1;
|
|
1619
|
-
parameters.add(parameter);
|
|
1620
|
-
}
|
|
1621
|
-
return !0;
|
|
1622
|
-
}
|
|
1623
|
-
function assertNotSet(value, name) {
|
|
1624
|
-
if (value !== void 0) throw new TypeError(`${name} can only be called once`);
|
|
1625
|
-
}
|
|
1626
|
-
function decodeBase64url(value, label, ErrorClass) {
|
|
1627
|
-
try {
|
|
1628
|
-
return decode(value);
|
|
1629
|
-
} catch {
|
|
1630
|
-
throw new ErrorClass(`Failed to base64url decode the ${label}`);
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
function encodeBase64url(value, label, ErrorClass) {
|
|
1634
|
-
try {
|
|
1635
|
-
return encode$1(value);
|
|
1636
|
-
} catch {
|
|
1637
|
-
throw new ErrorClass(`The ${label} is not a valid base64url string`);
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
function parseJoseHeader(b64, ErrorClass, message) {
|
|
1641
|
-
let parsed;
|
|
1642
|
-
try {
|
|
1643
|
-
parsed = JSON.parse(strictDecoder.decode(decode(b64)));
|
|
1644
|
-
} catch {
|
|
1645
|
-
throw new ErrorClass(message);
|
|
1646
|
-
}
|
|
1647
|
-
if (!isObject$1(parsed)) throw new ErrorClass(message);
|
|
1648
|
-
return parsed;
|
|
1649
|
-
}
|
|
1650
|
-
var JWS_RECOGNIZED = {
|
|
1651
|
-
__proto__: null,
|
|
1652
|
-
b64: !0
|
|
1653
|
-
};
|
|
1654
|
-
function validateAlgorithms(option, algorithms) {
|
|
1655
|
-
if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s != "string"))) throw new TypeError(`"${option}" option must be an array of strings`);
|
|
1656
|
-
return algorithms === void 0 ? void 0 : new Set(algorithms);
|
|
1657
|
-
}
|
|
1658
|
-
function validateCritDuplicates(Err, protectedHeader) {
|
|
1659
|
-
const { crit } = protectedHeader ?? {};
|
|
1660
|
-
if (Array.isArray(crit) && new Set(crit).size !== crit.length) throw new Err("\"crit\" (Critical) Header Parameter MUST NOT contain duplicate values");
|
|
1661
|
-
}
|
|
1662
|
-
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
|
|
1663
|
-
if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) throw new Err("\"crit\" (Critical) Header Parameter MUST be integrity protected");
|
|
1664
|
-
if (!protectedHeader || protectedHeader.crit === void 0) return [];
|
|
1665
|
-
if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input != "string" || input.length === 0)) throw new Err("\"crit\" (Critical) Header Parameter MUST be an array of non-empty strings when present");
|
|
1666
|
-
const recognized = recognizedOption === void 0 ? recognizedDefault : {
|
|
1667
|
-
__proto__: null,
|
|
1668
|
-
...recognizedOption,
|
|
1669
|
-
...recognizedDefault
|
|
1670
|
-
};
|
|
1671
|
-
for (const parameter of protectedHeader.crit) {
|
|
1672
|
-
if (!(parameter in recognized)) throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
1673
|
-
if (!Object.hasOwn(joseHeader, parameter) || joseHeader[parameter] === void 0) throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
1674
|
-
if (recognized[parameter] && (!Object.hasOwn(protectedHeader, parameter) || protectedHeader[parameter] === void 0)) throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
1675
|
-
}
|
|
1676
|
-
return protectedHeader.crit;
|
|
1677
|
-
}
|
|
1678
|
-
function validateB64(protectedHeader, extensions) {
|
|
1679
|
-
if (extensions.includes("b64")) {
|
|
1680
|
-
const b64 = protectedHeader.b64;
|
|
1681
|
-
if (typeof b64 != "boolean") throw new JWSInvalid("The \"b64\" (base64url-encode payload) Header Parameter must be a boolean");
|
|
1682
|
-
return b64;
|
|
1683
|
-
}
|
|
1684
|
-
return !0;
|
|
1685
|
-
}
|
|
1686
|
-
function serializeJoseHeader(Err, header) {
|
|
1687
|
-
let serialized, parsed;
|
|
1688
|
-
try {
|
|
1689
|
-
serialized = JSON.stringify(header), parsed = JSON.parse(serialized);
|
|
1690
|
-
} catch (cause) {
|
|
1691
|
-
throw new Err("JOSE Header is not valid JSON", { cause });
|
|
1692
|
-
}
|
|
1693
|
-
if (!isObject$1(parsed)) throw new Err("JOSE Header is not a JSON object");
|
|
1694
|
-
return [parsed, serialized];
|
|
1695
|
-
}
|
|
1696
|
-
//#endregion
|
|
1697
|
-
//#region ../../node_modules/jose/dist/webapi/lib/key.js
|
|
1698
|
-
var tag = (key) => key[Symbol.toStringTag], jwkMatchesOp = (entry, key, usage) => {
|
|
1699
|
-
const { alg } = entry;
|
|
1700
|
-
if (key.use !== void 0) {
|
|
1701
|
-
const expected = usage === "sign" || usage === "verify" ? "sig" : "enc";
|
|
1702
|
-
if (key.use !== expected) throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
|
|
1703
|
-
}
|
|
1704
|
-
if (key.alg !== void 0 && key.alg !== alg) throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
|
|
1705
|
-
if (Array.isArray(key.key_ops)) {
|
|
1706
|
-
const expectedKeyOp = usage === "encrypt" || usage === "decrypt" ? entry.ops?.[usage === "encrypt" ? 0 : 1] : usage;
|
|
1707
|
-
if (expectedKeyOp && !key.key_ops.includes(expectedKeyOp)) throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
|
|
1708
|
-
}
|
|
1709
|
-
};
|
|
1710
|
-
async function prepareKey(entry, key, usage) {
|
|
1711
|
-
const { alg, secret } = entry, privateKey = usage === "decrypt" || usage === "sign";
|
|
1712
|
-
if (secret && key instanceof Uint8Array) return key;
|
|
1713
|
-
let normalized, keyObject;
|
|
1714
|
-
if (isObject$1(key)) {
|
|
1715
|
-
if (normalized = normalizeJwk(key), typeof normalized.kty != "string") throw invalidKeyType(alg, key, secret);
|
|
1716
|
-
if (!(secret ? normalized.kty === "oct" && typeof normalized.k == "string" : normalized.kty !== "oct" && (privateKey ? normalized.kty === "AKP" && typeof normalized.priv == "string" || typeof normalized.d == "string" : normalized.d === void 0 && normalized.priv === void 0))) throw new TypeError(secret ? "JSON Web Key for symmetric algorithms must have JWK \"kty\" (Key Type) equal to \"oct\" and the JWK \"k\" (Key Value) present" : `JSON Web Key for this operation must be a ${privateKey ? "private" : "public"} JWK`);
|
|
1717
|
-
if (jwkMatchesOp(entry, normalized, usage), normalized.kty === "oct") return decode(normalized.k);
|
|
1718
|
-
if (!Object.isFrozen(key)) {
|
|
1719
|
-
const { key_ops } = key;
|
|
1720
|
-
Array.isArray(key_ops) && Object.freeze(key_ops), Object.freeze(key);
|
|
1721
|
-
}
|
|
1722
|
-
} else {
|
|
1723
|
-
if (!isKeyLike(key)) throw invalidKeyType(alg, key, secret);
|
|
1724
|
-
const expectedType = secret ? "secret" : privateKey ? "private" : "public";
|
|
1725
|
-
if (key.type !== expectedType && (secret || [
|
|
1726
|
-
"secret",
|
|
1727
|
-
"public",
|
|
1728
|
-
"private"
|
|
1729
|
-
].includes(key.type))) throw new TypeError(`${tag(key)} instances must be of type "${expectedType}" for the ${alg} algorithm`);
|
|
1730
|
-
if (isCryptoKey(key)) return key;
|
|
1731
|
-
if (keyObject = key, keyObject.type === "secret") return keyObject.export();
|
|
1732
|
-
}
|
|
1733
|
-
cache ||= /* @__PURE__ */ new WeakMap();
|
|
1734
|
-
const cacheKey = key;
|
|
1735
|
-
let cached = cache.get(cacheKey);
|
|
1736
|
-
if (cached?.[alg]) return cached[alg];
|
|
1737
|
-
if (cached || cache.set(cacheKey, cached = {}), keyObject && typeof keyObject.toCryptoKey == "function") {
|
|
1738
|
-
const isPublic = keyObject.type === "public", crv = nist[keyObject.asymmetricKeyDetails?.namedCurve], params = entry.resolve?.({
|
|
1739
|
-
crv,
|
|
1740
|
-
asymmetricKeyType: keyObject.asymmetricKeyType
|
|
1741
|
-
}) ?? entry.subtle;
|
|
1742
|
-
return cached[alg] = keyObject.toCryptoKey(params, isPublic, entry.usages[isPublic ? 0 : 1]);
|
|
1743
|
-
}
|
|
1744
|
-
return normalized ??= keyObject.export({ format: "jwk" }), normalized.alg = alg, cached[alg] = await jwkToKey(entry, normalized);
|
|
1745
|
-
}
|
|
1746
|
-
var cache;
|
|
1747
|
-
var nist = {
|
|
1748
|
-
__proto__: null,
|
|
1749
|
-
prime256v1: "P-256",
|
|
1750
|
-
secp384r1: "P-384",
|
|
1751
|
-
secp521r1: "P-521"
|
|
1752
|
-
};
|
|
1753
|
-
var isCryptoKey = (key) => {
|
|
1754
|
-
if (key?.[Symbol.toStringTag] === "CryptoKey") return !0;
|
|
1755
|
-
try {
|
|
1756
|
-
return key instanceof CryptoKey;
|
|
1757
|
-
} catch {
|
|
1758
|
-
return !1;
|
|
1759
|
-
}
|
|
1760
|
-
}, isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject", isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
|
|
1761
|
-
function message(msg, actual, ...types) {
|
|
1762
|
-
if (types.length > 2) {
|
|
1763
|
-
const last = types.pop();
|
|
1764
|
-
msg += `one of type ${types.join(", ")}, or ${last}.`;
|
|
1765
|
-
} else types.length === 2 ? msg += `one of type ${types[0]} or ${types[1]}.` : msg += `of type ${types[0]}.`;
|
|
1766
|
-
return actual == null ? msg += ` Received ${actual}` : typeof actual == "function" && actual.name ? msg += ` Received function ${actual.name}` : typeof actual == "object" && actual != null && actual.constructor?.name && (msg += ` Received an instance of ${actual.constructor.name}`), msg;
|
|
1767
|
-
}
|
|
1768
|
-
function invalidKeyType(alg, actual, secret) {
|
|
1769
|
-
const types = [
|
|
1770
|
-
"CryptoKey",
|
|
1771
|
-
"KeyObject",
|
|
1772
|
-
"JSON Web Key"
|
|
1773
|
-
];
|
|
1774
|
-
return secret && types.push("Uint8Array"), new TypeError(message(`Key for the ${alg} algorithm must be `, actual, ...types));
|
|
1775
|
-
}
|
|
1776
|
-
var unusable = (name, prop = "algorithm.name") => /* @__PURE__ */ new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
|
1777
|
-
function checkUsage(key, usage) {
|
|
1778
|
-
if (usage && !key.usages.includes(usage)) throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
|
|
1779
|
-
}
|
|
1780
|
-
function checkModulusLength(alg, key) {
|
|
1781
|
-
const { modulusLength } = key.algorithm;
|
|
1782
|
-
if (typeof modulusLength != "number" || modulusLength < 2048) throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
|
|
1783
|
-
}
|
|
1784
|
-
function checkCryptoKey(key, expected, usage) {
|
|
1785
|
-
const algorithm = key.algorithm;
|
|
1786
|
-
if (algorithm.name !== expected.name) throw unusable(expected.name);
|
|
1787
|
-
if (expected.hash && algorithm.hash?.name !== expected.hash) throw unusable(expected.hash, "algorithm.hash");
|
|
1788
|
-
if (expected.namedCurve && algorithm.namedCurve !== expected.namedCurve) throw unusable(expected.namedCurve, "algorithm.namedCurve");
|
|
1789
|
-
if (expected.length !== void 0 && algorithm.length !== expected.length) throw unusable(expected.length, "algorithm.length");
|
|
1790
|
-
checkUsage(key, usage);
|
|
1791
|
-
}
|
|
1792
|
-
function snapshotJwk(jwk) {
|
|
1793
|
-
return {
|
|
1794
|
-
__proto__: null,
|
|
1795
|
-
...jwk
|
|
1796
|
-
};
|
|
1797
|
-
}
|
|
1798
|
-
function normalizeJwk(jwk) {
|
|
1799
|
-
const normalized = snapshotJwk(jwk);
|
|
1800
|
-
if (normalized.ext !== void 0 && typeof normalized.ext != "boolean") throw new TypeError("\"ext\" (Extractable) Parameter must be a boolean");
|
|
1801
|
-
if (normalized.key_ops !== void 0) {
|
|
1802
|
-
const value = normalized.key_ops, keyOps = Array.isArray(value) ? [...value] : void 0;
|
|
1803
|
-
if (!keyOps || keyOps.some((operation) => typeof operation != "string") || new Set(keyOps).size !== keyOps.length) throw new TypeError("\"key_ops\" (Key Operations) Parameter must be an array of unique strings");
|
|
1804
|
-
normalized.key_ops = keyOps;
|
|
1805
|
-
}
|
|
1806
|
-
return normalized;
|
|
1807
|
-
}
|
|
1808
|
-
async function jwkToKey(entry, jwk, extractable) {
|
|
1809
|
-
if (!entry.kty.includes(jwk.kty)) throw new JOSENotSupported("Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value");
|
|
1810
|
-
const algorithm = entry.resolve?.({
|
|
1811
|
-
kty: jwk.kty,
|
|
1812
|
-
crv: jwk.crv
|
|
1813
|
-
}) ?? entry.subtle, isPrivate = !!(jwk.d || jwk.priv), keyData = {
|
|
1814
|
-
...jwk,
|
|
1815
|
-
ext: extractable ?? jwk.ext
|
|
1816
|
-
};
|
|
1817
|
-
return keyData.kty !== "AKP" && delete keyData.alg, delete keyData.use, crypto.subtle.importKey("jwk", keyData, algorithm, keyData.ext ?? !isPrivate, jwk.key_ops ?? entry.usages[isPrivate ? 1 : 0]);
|
|
1818
|
-
}
|
|
1819
|
-
async function rawKey(key, expected, usage, extractable = !1) {
|
|
1820
|
-
return key instanceof Uint8Array && (key = await crypto.subtle.importKey("raw", key, expected, extractable, [usage])), checkCryptoKey(key, expected, usage), key;
|
|
1821
|
-
}
|
|
1822
|
-
//#endregion
|
|
1823
|
-
//#region ../../node_modules/jose/dist/webapi/lib/key_descriptor.js
|
|
1824
|
-
function table(entries) {
|
|
1825
|
-
const out = { __proto__: null };
|
|
1826
|
-
for (const alg in entries) out[alg] = {
|
|
1827
|
-
...entries[alg],
|
|
1828
|
-
alg
|
|
1829
|
-
};
|
|
1830
|
-
return out;
|
|
1831
|
-
}
|
|
1832
|
-
//#endregion
|
|
1833
|
-
//#region ../../node_modules/jose/dist/webapi/lib/jws_algorithms.js
|
|
1834
|
-
var sig = [["verify"], ["sign"]];
|
|
1835
|
-
function hmac(bits) {
|
|
1836
|
-
const subtle = {
|
|
1837
|
-
name: "HMAC",
|
|
1838
|
-
hash: `SHA-${bits}`
|
|
1839
|
-
};
|
|
1840
|
-
return {
|
|
1841
|
-
kty: ["oct"],
|
|
1842
|
-
secret: !0,
|
|
1843
|
-
subtle,
|
|
1844
|
-
signing: subtle,
|
|
1845
|
-
usages: sig
|
|
1846
|
-
};
|
|
1847
|
-
}
|
|
1848
|
-
function rsa(bits, saltLength) {
|
|
1849
|
-
const subtle = {
|
|
1850
|
-
name: saltLength ? "RSA-PSS" : "RSASSA-PKCS1-v1_5",
|
|
1851
|
-
hash: `SHA-${bits}`
|
|
1852
|
-
};
|
|
1853
|
-
return {
|
|
1854
|
-
kty: ["RSA"],
|
|
1855
|
-
subtle,
|
|
1856
|
-
signing: saltLength ? {
|
|
1857
|
-
...subtle,
|
|
1858
|
-
saltLength
|
|
1859
|
-
} : subtle,
|
|
1860
|
-
usages: sig,
|
|
1861
|
-
minRsaBits: 2048
|
|
1862
|
-
};
|
|
1863
|
-
}
|
|
1864
|
-
function ecdsa(crv, bits) {
|
|
1865
|
-
return {
|
|
1866
|
-
kty: ["EC"],
|
|
1867
|
-
crv,
|
|
1868
|
-
subtle: {
|
|
1869
|
-
name: "ECDSA",
|
|
1870
|
-
namedCurve: crv
|
|
1871
|
-
},
|
|
1872
|
-
signing: {
|
|
1873
|
-
name: "ECDSA",
|
|
1874
|
-
hash: `SHA-${bits}`
|
|
1875
|
-
},
|
|
1876
|
-
usages: sig
|
|
1877
|
-
};
|
|
1878
|
-
}
|
|
1879
|
-
function eddsa() {
|
|
1880
|
-
const subtle = { name: "Ed25519" };
|
|
1881
|
-
return {
|
|
1882
|
-
kty: ["OKP"],
|
|
1883
|
-
crv: "Ed25519",
|
|
1884
|
-
subtle,
|
|
1885
|
-
signing: subtle,
|
|
1886
|
-
usages: sig
|
|
1887
|
-
};
|
|
1888
|
-
}
|
|
1889
|
-
function mldsa(bits) {
|
|
1890
|
-
const subtle = { name: `ML-DSA-${bits}` };
|
|
1891
|
-
return {
|
|
1892
|
-
kty: ["AKP"],
|
|
1893
|
-
subtle,
|
|
1894
|
-
signing: subtle,
|
|
1895
|
-
usages: sig
|
|
1896
|
-
};
|
|
1897
|
-
}
|
|
1898
|
-
var JWS = table({
|
|
1899
|
-
HS256: hmac(256),
|
|
1900
|
-
HS384: hmac(384),
|
|
1901
|
-
HS512: hmac(512),
|
|
1902
|
-
RS256: rsa(256),
|
|
1903
|
-
RS384: rsa(384),
|
|
1904
|
-
RS512: rsa(512),
|
|
1905
|
-
PS256: rsa(256, 32),
|
|
1906
|
-
PS384: rsa(384, 48),
|
|
1907
|
-
PS512: rsa(512, 64),
|
|
1908
|
-
ES256: ecdsa("P-256", 256),
|
|
1909
|
-
ES384: ecdsa("P-384", 384),
|
|
1910
|
-
ES512: ecdsa("P-521", 512),
|
|
1911
|
-
EdDSA: eddsa(),
|
|
1912
|
-
Ed25519: eddsa(),
|
|
1913
|
-
"ML-DSA-44": mldsa(44),
|
|
1914
|
-
"ML-DSA-65": mldsa(65),
|
|
1915
|
-
"ML-DSA-87": mldsa(87)
|
|
1916
|
-
});
|
|
1917
|
-
function jwsAlgorithm(alg) {
|
|
1918
|
-
const entry = typeof alg == "string" ? JWS[alg] : void 0;
|
|
1919
|
-
if (!entry) throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
|
1920
|
-
return entry;
|
|
1921
|
-
}
|
|
1922
|
-
//#endregion
|
|
1923
|
-
//#region ../../node_modules/jose/dist/webapi/lib/jws_verify.js
|
|
1924
|
-
function prepareVerify(options) {
|
|
1925
|
-
return [options && validateAlgorithms("algorithms", options.algorithms), options?.crit];
|
|
1926
|
-
}
|
|
1927
|
-
function parseProtectedHeader(encodedProtected) {
|
|
1928
|
-
return encodedProtected === void 0 ? {} : parseJoseHeader(encodedProtected, JWSInvalid, "JWS Protected Header is invalid");
|
|
1929
|
-
}
|
|
1930
|
-
function encodeCompactUnencodedPayload(payload) {
|
|
1931
|
-
try {
|
|
1932
|
-
return encode$1(payload);
|
|
1933
|
-
} catch {
|
|
1934
|
-
throw new JWSInvalid("JWS Compact Serialization payload must use only ASCII characters");
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
async function verifySignature(jws, shared, key, encodeUnencodedPayload, parsedProtected) {
|
|
1938
|
-
const { protected: encodedProtected, header, payload: inputPayload } = jws, parsedProt = parsedProtected ?? parseProtectedHeader(encodedProtected);
|
|
1939
|
-
if (!isDisjoint(parsedProt, header)) throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
1940
|
-
const joseHeader = {
|
|
1941
|
-
...parsedProt,
|
|
1942
|
-
...header
|
|
1943
|
-
}, b64 = validateB64(parsedProt, validateCrit(JWSInvalid, JWS_RECOGNIZED, shared[1], parsedProt, joseHeader)), { alg } = joseHeader;
|
|
1944
|
-
if (typeof alg != "string" || !alg) throw new JWSInvalid("JWS \"alg\" (Algorithm) Header Parameter missing or invalid");
|
|
1945
|
-
if (shared[0] && !shared[0].has(alg)) throw new JOSEAlgNotAllowed("\"alg\" (Algorithm) Header Parameter value not allowed");
|
|
1946
|
-
if (b64) {
|
|
1947
|
-
if (typeof inputPayload != "string") throw new JWSInvalid("JWS Payload must be a string");
|
|
1948
|
-
} else if (typeof inputPayload != "string" && !(inputPayload instanceof Uint8Array)) throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
|
|
1949
|
-
const signingPayload = b64 || typeof inputPayload != "string" ? inputPayload : encodeUnencodedPayload(inputPayload);
|
|
1950
|
-
let resolvedKey = !1;
|
|
1951
|
-
typeof key == "function" && (key = await key(parsedProt, jws), resolvedKey = !0);
|
|
1952
|
-
const entry = jwsAlgorithm(alg), data = concat(encodedProtected !== void 0 ? encode$1(encodedProtected) : new Uint8Array(), encode$1("."), typeof signingPayload == "string" ? shared[2] ??= encodeBase64url(signingPayload, "payload", JWSInvalid) : signingPayload), signature = decodeBase64url(jws.signature, "signature", JWSInvalid), k = await prepareKey(entry, key, "verify"), cryptoKey = await rawKey(k, entry.subtle, "verify");
|
|
1953
|
-
entry.minRsaBits && checkModulusLength(entry.alg, cryptoKey);
|
|
1954
|
-
let verified = !1;
|
|
1955
|
-
try {
|
|
1956
|
-
verified = await crypto.subtle.verify(entry.signing, cryptoKey, signature, data);
|
|
1957
|
-
} catch {}
|
|
1958
|
-
if (!verified) throw new JWSSignatureVerificationFailed();
|
|
1959
|
-
const result = { payload: typeof signingPayload == "string" ? decodeBase64url(signingPayload, "payload", JWSInvalid) : signingPayload };
|
|
1960
|
-
return encodedProtected !== void 0 && (result.protectedHeader = parsedProt), header !== void 0 && (result.unprotectedHeader = header), resolvedKey ? [{
|
|
1961
|
-
...result,
|
|
1962
|
-
key: k
|
|
1963
|
-
}, b64] : [result, b64];
|
|
1964
|
-
}
|
|
1965
|
-
async function verifyCompact(jws, shared, key) {
|
|
1966
|
-
if (jws instanceof Uint8Array && (jws = decoder.decode(jws)), typeof jws != "string") throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
|
|
1967
|
-
const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split(".");
|
|
1968
|
-
if (length !== 3) throw new JWSInvalid("Invalid Compact JWS");
|
|
1969
|
-
return verifySignature({
|
|
1970
|
-
payload,
|
|
1971
|
-
protected: protectedHeader,
|
|
1972
|
-
signature
|
|
1973
|
-
}, shared, key, encodeCompactUnencodedPayload);
|
|
1974
|
-
}
|
|
1975
|
-
//#endregion
|
|
1976
|
-
//#region ../../node_modules/jose/dist/webapi/lib/jwt_claims_set.js
|
|
1977
|
-
var epoch = (date) => Math.floor(date.getTime() / 1e3), multipliers = {
|
|
1978
|
-
s: 1,
|
|
1979
|
-
m: 60,
|
|
1980
|
-
h: 3600,
|
|
1981
|
-
d: 86400,
|
|
1982
|
-
w: 604800,
|
|
1983
|
-
y: 31557600
|
|
1984
|
-
}, REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i, checkFailed = "check_failed";
|
|
1985
|
-
function invalidDuration() {
|
|
1986
|
-
throw new TypeError("Invalid time period format");
|
|
1987
|
-
}
|
|
1988
|
-
function secs(str) {
|
|
1989
|
-
typeof str != "string" && invalidDuration();
|
|
1990
|
-
const matched = REGEX.exec(str);
|
|
1991
|
-
(!matched || matched[4] && matched[1]) && invalidDuration();
|
|
1992
|
-
const value = parseFloat(matched[2]), numericDate2 = Math.round(value * multipliers[matched[3][0].toLowerCase()]);
|
|
1993
|
-
return Number.isFinite(numericDate2) || invalidDuration(), matched[1] === "-" || matched[4] === "ago" ? -numericDate2 : numericDate2;
|
|
1994
|
-
}
|
|
1995
|
-
function validateInput(label, input) {
|
|
1996
|
-
if (!Number.isFinite(input)) throw new TypeError(`Invalid ${label} input`);
|
|
1997
|
-
return input;
|
|
1998
|
-
}
|
|
1999
|
-
function validateStringClaim(claim, value) {
|
|
2000
|
-
if (typeof value != "string") throw new TypeError(`"${claim}" claim must be a string`);
|
|
2001
|
-
}
|
|
2002
|
-
function validateAudienceClaim(value) {
|
|
2003
|
-
if (typeof value != "string" && (!Array.isArray(value) || Array.from(value).some((member) => typeof member != "string"))) throw new TypeError("\"aud\" claim must be a string or an array of strings");
|
|
2004
|
-
}
|
|
2005
|
-
function numericDate(value, label) {
|
|
2006
|
-
return typeof value == "number" ? validateInput(label, value) : value instanceof Date ? validateInput(label, epoch(value)) : epoch(/* @__PURE__ */ new Date()) + secs(value);
|
|
2007
|
-
}
|
|
2008
|
-
var normalizeTyp = (value) => {
|
|
2009
|
-
const normalized = value.toLowerCase();
|
|
2010
|
-
return value.includes("/") ? normalized : `application/${normalized}`;
|
|
2011
|
-
}, checkAudiencePresence = (audPayload, audOption) => typeof audPayload == "string" ? audOption.includes(audPayload) : Array.isArray(audPayload) ? audOption.some((aud) => audPayload.includes(aud)) : !1;
|
|
2012
|
-
function validateNumericDate(payload, claim, required = !1) {
|
|
2013
|
-
const value = payload[claim];
|
|
2014
|
-
if (!(value === void 0 && !required)) {
|
|
2015
|
-
if (typeof value != "number") throw new JWTClaimValidationFailed(`"${claim}" claim must be a number`, payload, claim, "invalid");
|
|
2016
|
-
return value;
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
function unexpectedClaim(payload, claim) {
|
|
2020
|
-
throw new JWTClaimValidationFailed(`unexpected "${claim}" claim value`, payload, claim, checkFailed);
|
|
2021
|
-
}
|
|
2022
|
-
function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
|
|
2023
|
-
let payload;
|
|
2024
|
-
try {
|
|
2025
|
-
payload = JSON.parse(strictDecoder.decode(encodedPayload));
|
|
2026
|
-
} catch {}
|
|
2027
|
-
if (!isObject$1(payload)) throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
|
|
2028
|
-
const { typ } = options;
|
|
2029
|
-
if (typ !== void 0 && (typeof protectedHeader.typ != "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) throw new JWTClaimValidationFailed("unexpected \"typ\" JWT header value", payload, "typ", checkFailed);
|
|
2030
|
-
const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options, presenceCheck = [...requiredClaims];
|
|
2031
|
-
maxTokenAge !== void 0 && presenceCheck.push("iat"), audience !== void 0 && presenceCheck.push("aud"), subject !== void 0 && presenceCheck.push("sub"), issuer !== void 0 && presenceCheck.push("iss");
|
|
2032
|
-
for (const claim of new Set(presenceCheck.reverse())) if (!Object.hasOwn(payload, claim)) throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload, claim, "missing");
|
|
2033
|
-
issuer !== void 0 && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss) && unexpectedClaim(payload, "iss"), subject !== void 0 && payload.sub !== subject && unexpectedClaim(payload, "sub"), audience !== void 0 && !checkAudiencePresence(payload.aud, typeof audience == "string" ? [audience] : audience) && unexpectedClaim(payload, "aud");
|
|
2034
|
-
const { clockTolerance } = options;
|
|
2035
|
-
let tolerance = 0;
|
|
2036
|
-
if (typeof clockTolerance == "string") tolerance = secs(clockTolerance);
|
|
2037
|
-
else if (clockTolerance !== void 0) {
|
|
2038
|
-
if (typeof clockTolerance != "number") throw new TypeError("Invalid clockTolerance option type");
|
|
2039
|
-
tolerance = clockTolerance;
|
|
2040
|
-
}
|
|
2041
|
-
validateInput("clockTolerance option", tolerance);
|
|
2042
|
-
const { currentDate } = options, now = validateInput("currentDate option", epoch(currentDate === void 0 ? /* @__PURE__ */ new Date() : currentDate)), iat = validateNumericDate(payload, "iat", maxTokenAge !== void 0), nbf = validateNumericDate(payload, "nbf");
|
|
2043
|
-
if (nbf !== void 0 && nbf > now + tolerance) throw new JWTClaimValidationFailed("\"nbf\" claim timestamp check failed", payload, "nbf", checkFailed);
|
|
2044
|
-
const exp = validateNumericDate(payload, "exp");
|
|
2045
|
-
if (exp !== void 0 && exp <= now - tolerance) throw new JWTExpired("\"exp\" claim timestamp check failed", payload, "exp", checkFailed);
|
|
2046
|
-
if (maxTokenAge !== void 0) {
|
|
2047
|
-
const age = now - iat, max = validateInput("maxTokenAge option", typeof maxTokenAge == "number" ? maxTokenAge : secs(maxTokenAge));
|
|
2048
|
-
if (age - tolerance > max) throw new JWTExpired("\"iat\" claim timestamp check failed (too far in the past)", payload, "iat", checkFailed);
|
|
2049
|
-
if (age < -tolerance) throw new JWTClaimValidationFailed("\"iat\" claim timestamp check failed (it should be in the past)", payload, "iat", checkFailed);
|
|
2050
|
-
}
|
|
2051
|
-
return payload;
|
|
2052
|
-
}
|
|
2053
|
-
var producerPayloads;
|
|
2054
|
-
function producerPayload(producer) {
|
|
2055
|
-
return producerPayloads.get(producer);
|
|
2056
|
-
}
|
|
2057
|
-
function jwtData(producer) {
|
|
2058
|
-
const payload = producerPayload(producer);
|
|
2059
|
-
for (const claim of [
|
|
2060
|
-
"iat",
|
|
2061
|
-
"nbf",
|
|
2062
|
-
"exp"
|
|
2063
|
-
]) {
|
|
2064
|
-
const value = payload[claim];
|
|
2065
|
-
if (typeof value == "number" && !Number.isFinite(value)) throw new TypeError(`"${claim}" claim must be a finite number`);
|
|
2066
|
-
}
|
|
2067
|
-
return encoder.encode(JSON.stringify(payload));
|
|
2068
|
-
}
|
|
2069
|
-
var JWTClaimsBuilder = class {
|
|
2070
|
-
constructor(payload = {}) {
|
|
2071
|
-
if (!isObject$1(payload)) throw new TypeError("JWT Claims Set MUST be an object");
|
|
2072
|
-
(producerPayloads ||= /* @__PURE__ */ new WeakMap()).set(this, structuredClone(payload));
|
|
2073
|
-
}
|
|
2074
|
-
setIssuer(value) {
|
|
2075
|
-
return validateStringClaim("iss", value), producerPayload(this).iss = value, this;
|
|
2076
|
-
}
|
|
2077
|
-
setSubject(value) {
|
|
2078
|
-
return validateStringClaim("sub", value), producerPayload(this).sub = value, this;
|
|
2079
|
-
}
|
|
2080
|
-
setAudience(value) {
|
|
2081
|
-
return validateAudienceClaim(value), producerPayload(this).aud = value, this;
|
|
2082
|
-
}
|
|
2083
|
-
setJti(value) {
|
|
2084
|
-
return validateStringClaim("jti", value), producerPayload(this).jti = value, this;
|
|
2085
|
-
}
|
|
2086
|
-
setNotBefore(value) {
|
|
2087
|
-
return producerPayload(this).nbf = numericDate(value, "setNotBefore"), this;
|
|
2088
|
-
}
|
|
2089
|
-
setExpirationTime(value) {
|
|
2090
|
-
return producerPayload(this).exp = numericDate(value, "setExpirationTime"), this;
|
|
2091
|
-
}
|
|
2092
|
-
setIssuedAt(value) {
|
|
2093
|
-
const payload = producerPayload(this);
|
|
2094
|
-
return value === void 0 ? payload.iat = epoch(/* @__PURE__ */ new Date()) : typeof value == "string" ? payload.iat = validateInput("setIssuedAt", epoch(/* @__PURE__ */ new Date()) + secs(value)) : payload.iat = numericDate(value, "setIssuedAt"), this;
|
|
2095
|
-
}
|
|
2096
|
-
};
|
|
2097
|
-
//#endregion
|
|
2098
|
-
//#region ../../node_modules/jose/dist/webapi/jwt/verify.js
|
|
2099
|
-
async function jwtVerify(jwt, key, options) {
|
|
2100
|
-
const [verified, b64] = await verifyCompact(jwt, prepareVerify(options), key);
|
|
2101
|
-
if (!b64) throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
2102
|
-
const payload = validateClaimsSet(verified.protectedHeader, verified.payload, options);
|
|
2103
|
-
return {
|
|
2104
|
-
...verified,
|
|
2105
|
-
payload
|
|
2106
|
-
};
|
|
2107
|
-
}
|
|
2108
|
-
//#endregion
|
|
2109
|
-
//#region ../../node_modules/jose/dist/webapi/lib/jws_sign.js
|
|
2110
|
-
async function createSignature(input, key, rejectUnencoded) {
|
|
2111
|
-
let [payload, protectedHeader, unprotectedHeader, crit] = input, protectedHeaderString = "";
|
|
2112
|
-
if (protectedHeader !== void 0) {
|
|
2113
|
-
const normalized = serializeJoseHeader(JWSInvalid, protectedHeader);
|
|
2114
|
-
protectedHeader = normalized[0], protectedHeaderString = encode(normalized[1]);
|
|
2115
|
-
}
|
|
2116
|
-
if (unprotectedHeader !== void 0 && (unprotectedHeader = serializeJoseHeader(JWSInvalid, unprotectedHeader)[0]), !protectedHeader && !unprotectedHeader) throw new JWSInvalid("either setProtectedHeader or setUnprotectedHeader must be called before #sign()");
|
|
2117
|
-
if (!isDisjoint(protectedHeader, unprotectedHeader)) throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
|
|
2118
|
-
const joseHeader = {
|
|
2119
|
-
...protectedHeader,
|
|
2120
|
-
...unprotectedHeader
|
|
2121
|
-
};
|
|
2122
|
-
validateCritDuplicates(JWSInvalid, protectedHeader);
|
|
2123
|
-
const b64 = validateB64(protectedHeader, validateCrit(JWSInvalid, JWS_RECOGNIZED, crit, protectedHeader, joseHeader));
|
|
2124
|
-
b64 || rejectUnencoded?.();
|
|
2125
|
-
const { alg } = joseHeader;
|
|
2126
|
-
if (typeof alg != "string" || !alg) throw new JWSInvalid("JWS \"alg\" (Algorithm) Header Parameter missing or invalid");
|
|
2127
|
-
const entry = jwsAlgorithm(alg);
|
|
2128
|
-
let payloadS = "", payloadB = payload, data;
|
|
2129
|
-
if (b64) {
|
|
2130
|
-
const encoded = input[4];
|
|
2131
|
-
encoded ? (payloadS = encoded[0] ??= encode(payload), payloadB = encoded[1] ??= encode$1(payloadS)) : (payloadS = encode(payload), data = encoder.encode(`${protectedHeaderString}.${payloadS}`));
|
|
2132
|
-
}
|
|
2133
|
-
data ??= concat(encode$1(protectedHeaderString), encode$1("."), payloadB);
|
|
2134
|
-
const k = await rawKey(await prepareKey(entry, key, "sign"), entry.subtle, "sign");
|
|
2135
|
-
entry.minRsaBits && checkModulusLength(entry.alg, k);
|
|
2136
|
-
const jws = {
|
|
2137
|
-
signature: encode(new Uint8Array(await crypto.subtle.sign(entry.signing, k, data))),
|
|
2138
|
-
payload: payloadS
|
|
2139
|
-
};
|
|
2140
|
-
return protectedHeader && (jws.protected = protectedHeaderString), unprotectedHeader && (jws.header = unprotectedHeader), [jws, b64];
|
|
2141
|
-
}
|
|
2142
|
-
async function createCompactSignature(payload, protectedHeader, crit, key, rejectUnencoded) {
|
|
2143
|
-
const [jws] = await createSignature([
|
|
2144
|
-
payload,
|
|
2145
|
-
protectedHeader,
|
|
2146
|
-
void 0,
|
|
2147
|
-
crit
|
|
2148
|
-
], key, rejectUnencoded);
|
|
2149
|
-
return `${jws.protected}.${jws.payload}.${jws.signature}`;
|
|
2150
|
-
}
|
|
2151
|
-
//#endregion
|
|
2152
|
-
//#region ../../node_modules/jose/dist/webapi/jwt/sign.js
|
|
2153
|
-
var SignJWT_base = JWTClaimsBuilder;
|
|
2154
|
-
var SignJWT = class extends SignJWT_base {
|
|
2155
|
-
#protectedHeader;
|
|
2156
|
-
setProtectedHeader(protectedHeader) {
|
|
2157
|
-
return assertNotSet(this.#protectedHeader, "setProtectedHeader"), this.#protectedHeader = protectedHeader, this;
|
|
2158
|
-
}
|
|
2159
|
-
async sign(key, options) {
|
|
2160
|
-
return createCompactSignature(jwtData(this), this.#protectedHeader, options?.crit, key, () => {
|
|
2161
|
-
throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
|
|
2162
|
-
});
|
|
2163
|
-
}
|
|
2164
|
-
};
|
|
2165
|
-
//#endregion
|
|
2166
|
-
//#region src/kernel/moleculer/mesh-mtls/mesh-join-token.ts
|
|
2167
|
-
/**
|
|
2168
|
-
* Mesh join tokens — single-use JWS ES256 signed with the hub mesh CA key.
|
|
2169
|
-
*
|
|
2170
|
-
* Payload: `{ v, hubUrl, hubMeshAddress, caFingerprint, nodeId, jti, exp }`. The node id is MANDATORY
|
|
2171
|
-
* (D857): a token that does not name the node it is for would let its holder pick any id, `hub` included.
|
|
2172
|
-
* `exp` ≤ now + 1 h. `jti` is recorded until expiry so a token cannot be reused.
|
|
2173
|
-
*/
|
|
2174
|
-
/** In-memory + optional persist of spent `jti` until `exp`. */
|
|
2175
|
-
var JoinTokenJtiStore = class {
|
|
2176
|
-
spent = /* @__PURE__ */ new Map();
|
|
2177
|
-
/** True when `jti` was already consumed (and not yet expired). */
|
|
2178
|
-
isSpent(jti, nowSec = Math.floor(Date.now() / 1e3)) {
|
|
2179
|
-
this.gc(nowSec);
|
|
2180
|
-
return this.spent.has(jti);
|
|
2181
|
-
}
|
|
2182
|
-
/** Record a jti as used until `exp`. Returns false if already spent. */
|
|
2183
|
-
consume(jti, exp, nowSec = Math.floor(Date.now() / 1e3)) {
|
|
2184
|
-
this.gc(nowSec);
|
|
2185
|
-
if (this.spent.has(jti)) return false;
|
|
2186
|
-
this.spent.set(jti, exp);
|
|
2187
|
-
return true;
|
|
2188
|
-
}
|
|
2189
|
-
/** Test helper. */
|
|
2190
|
-
size() {
|
|
2191
|
-
return this.spent.size;
|
|
2192
|
-
}
|
|
2193
|
-
gc(nowSec) {
|
|
2194
|
-
for (const [jti, exp] of this.spent) if (exp <= nowSec) this.spent.delete(jti);
|
|
2195
|
-
}
|
|
2196
|
-
};
|
|
2197
|
-
var processJtiStore = new JoinTokenJtiStore();
|
|
2198
|
-
function processJoinTokenJtiStore() {
|
|
2199
|
-
return processJtiStore;
|
|
2200
|
-
}
|
|
2201
|
-
async function mintMeshJoinToken(input) {
|
|
2202
|
-
if (!isValidAgentNodeId(input.nodeId)) throw new Error(`a join token needs the node id it is for; "${input.nodeId}" is not one an agent may carry`);
|
|
2203
|
-
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
2204
|
-
const nowSec = Math.floor(now.getTime() / 1e3);
|
|
2205
|
-
const exp = nowSec + Math.min(Math.max(1, input.ttlSec ?? 3600), require_constants$8.MESH_JOIN_TOKEN_MAX_TTL_SEC);
|
|
2206
|
-
const jti = input.jti ?? (0, node_crypto.randomBytes)(16).toString("base64url");
|
|
2207
|
-
return new SignJWT({
|
|
2208
|
-
v: 1,
|
|
2209
|
-
hubUrl: input.hubUrl,
|
|
2210
|
-
hubMeshAddress: input.hubMeshAddress,
|
|
2211
|
-
caFingerprint: caFingerprintCompact(input.ca.certPem),
|
|
2212
|
-
nodeId: input.nodeId,
|
|
2213
|
-
jti,
|
|
2214
|
-
exp
|
|
2215
|
-
}).setProtectedHeader({
|
|
2216
|
-
alg: "ES256",
|
|
2217
|
-
typ: "JWT"
|
|
2218
|
-
}).setIssuedAt(nowSec).setExpirationTime(exp).setJti(jti).sign(input.ca.privateKey);
|
|
2219
|
-
}
|
|
2220
|
-
async function verifyMeshJoinToken(input) {
|
|
2221
|
-
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
2222
|
-
const nowSec = Math.floor(now.getTime() / 1e3);
|
|
2223
|
-
let payload;
|
|
2224
|
-
try {
|
|
2225
|
-
payload = (await jwtVerify(input.token, input.ca.publicKey, {
|
|
2226
|
-
algorithms: ["ES256"],
|
|
2227
|
-
currentDate: now
|
|
2228
|
-
})).payload;
|
|
2229
|
-
} catch (err) {
|
|
2230
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2231
|
-
if (/exp/i.test(msg) || /timestamp/i.test(msg)) return {
|
|
2232
|
-
ok: false,
|
|
2233
|
-
reason: "token expired"
|
|
2234
|
-
};
|
|
2235
|
-
return {
|
|
2236
|
-
ok: false,
|
|
2237
|
-
reason: `token signature invalid: ${msg}`
|
|
2238
|
-
};
|
|
2239
|
-
}
|
|
2240
|
-
const claims = parseClaims$1(payload);
|
|
2241
|
-
if (claims === null) return {
|
|
2242
|
-
ok: false,
|
|
2243
|
-
reason: "token claims malformed"
|
|
2244
|
-
};
|
|
2245
|
-
if (claims.exp <= nowSec) return {
|
|
2246
|
-
ok: false,
|
|
2247
|
-
reason: "token expired"
|
|
2248
|
-
};
|
|
2249
|
-
const expectedFp = caFingerprintCompact(input.ca.certPem);
|
|
2250
|
-
if (claims.caFingerprint !== expectedFp) return {
|
|
2251
|
-
ok: false,
|
|
2252
|
-
reason: "token caFingerprint does not match this hub CA"
|
|
2253
|
-
};
|
|
2254
|
-
if (input.expectedCaFingerprint !== void 0 && claims.caFingerprint !== normalizeFp(input.expectedCaFingerprint)) return {
|
|
2255
|
-
ok: false,
|
|
2256
|
-
reason: "token caFingerprint pin mismatch"
|
|
2257
|
-
};
|
|
2258
|
-
const store = input.jtiStore ?? processJtiStore;
|
|
2259
|
-
if (input.consume !== false) {
|
|
2260
|
-
if (!store.consume(claims.jti, claims.exp, nowSec)) return {
|
|
2261
|
-
ok: false,
|
|
2262
|
-
reason: "token already used"
|
|
2263
|
-
};
|
|
2264
|
-
} else if (store.isSpent(claims.jti, nowSec)) return {
|
|
2265
|
-
ok: false,
|
|
2266
|
-
reason: "token already used"
|
|
2267
|
-
};
|
|
2268
|
-
return {
|
|
2269
|
-
ok: true,
|
|
2270
|
-
claims
|
|
2271
|
-
};
|
|
2272
|
-
}
|
|
2273
|
-
function normalizeFp(fp) {
|
|
2274
|
-
return fp.replace(/:/g, "").toLowerCase();
|
|
2275
|
-
}
|
|
2276
|
-
function parseClaims$1(payload) {
|
|
2277
|
-
if (payload["v"] !== 1) return null;
|
|
2278
|
-
const hubUrl = payload["hubUrl"];
|
|
2279
|
-
const hubMeshAddress = payload["hubMeshAddress"];
|
|
2280
|
-
const caFingerprint = payload["caFingerprint"];
|
|
2281
|
-
const jti = typeof payload.jti === "string" ? payload.jti : payload["jti"];
|
|
2282
|
-
const exp = typeof payload.exp === "number" ? payload.exp : null;
|
|
2283
|
-
if (typeof hubUrl !== "string" || hubUrl.length === 0) return null;
|
|
2284
|
-
if (typeof hubMeshAddress !== "string" || hubMeshAddress.length === 0) return null;
|
|
2285
|
-
if (typeof caFingerprint !== "string" || caFingerprint.length === 0) return null;
|
|
2286
|
-
if (typeof jti !== "string" || jti.length === 0) return null;
|
|
2287
|
-
if (exp === null) return null;
|
|
2288
|
-
const nodeId = payload["nodeId"];
|
|
2289
|
-
if (typeof nodeId !== "string" || !isValidAgentNodeId(nodeId)) return null;
|
|
2290
|
-
return {
|
|
2291
|
-
v: 1,
|
|
2292
|
-
hubUrl,
|
|
2293
|
-
hubMeshAddress,
|
|
2294
|
-
caFingerprint: normalizeFp(caFingerprint),
|
|
2295
|
-
nodeId,
|
|
2296
|
-
jti,
|
|
2297
|
-
exp
|
|
2298
|
-
};
|
|
2299
|
-
}
|
|
2300
|
-
//#endregion
|
|
2301
|
-
//#region src/kernel/moleculer/mesh-mtls/mesh-enroll.ts
|
|
2302
|
-
/**
|
|
2303
|
-
* `POST /api/mesh/enroll` — verify join token, issue a 30-day leaf from CSR.
|
|
2304
|
-
*/
|
|
2305
|
-
async function enrollMeshNode(body, deps) {
|
|
2306
|
-
if (typeof body.token !== "string" || body.token.length === 0) return {
|
|
2307
|
-
ok: false,
|
|
2308
|
-
error: "token is required",
|
|
2309
|
-
status: 400
|
|
2310
|
-
};
|
|
2311
|
-
if (typeof body.csr !== "string" || !body.csr.includes("BEGIN CERTIFICATE REQUEST")) return {
|
|
2312
|
-
ok: false,
|
|
2313
|
-
error: "csr PEM is required",
|
|
2314
|
-
status: 400
|
|
2315
|
-
};
|
|
2316
|
-
const verified = await verifyMeshJoinToken({
|
|
2317
|
-
token: body.token,
|
|
2318
|
-
ca: deps.ca,
|
|
2319
|
-
jtiStore: deps.jtiStore ?? processJoinTokenJtiStore(),
|
|
2320
|
-
now: deps.now,
|
|
2321
|
-
consume: true
|
|
2322
|
-
});
|
|
2323
|
-
if (!verified.ok) {
|
|
2324
|
-
const status = verified.reason.includes("expired") ? 401 : verified.reason.includes("already used") ? 409 : 401;
|
|
2325
|
-
return {
|
|
2326
|
-
ok: false,
|
|
2327
|
-
error: verified.reason,
|
|
2328
|
-
status
|
|
2329
|
-
};
|
|
2330
|
-
}
|
|
2331
|
-
let leaf;
|
|
2332
|
-
try {
|
|
2333
|
-
leaf = await issueMeshLeafFromCsr(deps.ca, body.csr, {
|
|
2334
|
-
expectedNodeId: verified.claims.nodeId,
|
|
2335
|
-
now: deps.now
|
|
2336
|
-
});
|
|
2337
|
-
} catch (err) {
|
|
2338
|
-
return {
|
|
2339
|
-
ok: false,
|
|
2340
|
-
error: err instanceof Error ? err.message : String(err),
|
|
2341
|
-
status: 400
|
|
2342
|
-
};
|
|
2343
|
-
}
|
|
2344
|
-
try {
|
|
2345
|
-
await deps.onIssued?.(leaf.commonName, leaf.certPem);
|
|
2346
|
-
} catch (err) {
|
|
2347
|
-
deps.onRecordFailed?.(leaf.commonName, err);
|
|
2348
|
-
}
|
|
2349
|
-
return {
|
|
2350
|
-
ok: true,
|
|
2351
|
-
cert: leaf.certPem,
|
|
2352
|
-
caCert: deps.ca.certPem,
|
|
2353
|
-
nodeId: leaf.commonName,
|
|
2354
|
-
notAfter: leaf.notAfter.toISOString(),
|
|
2355
|
-
serialNumber: leaf.serialNumber
|
|
2356
|
-
};
|
|
2357
|
-
}
|
|
2358
|
-
//#endregion
|
|
2359
1384
|
//#region src/kernel/moleculer/mesh-mtls/mesh-tls-enabler.ts
|
|
2360
1385
|
var SLOT = Symbol.for("camstack.mesh.tls-enabler");
|
|
2361
1386
|
function setProcessMeshTlsEnabler(enabler) {
|
|
@@ -22342,7 +21367,7 @@ var require_kleur = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modul
|
|
|
22342
21367
|
//#region ../../node_modules/moleculer/src/utils.js
|
|
22343
21368
|
var require_utils$3 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
22344
21369
|
var kleur = require_kleur();
|
|
22345
|
-
var os$
|
|
21370
|
+
var os$19 = require("os");
|
|
22346
21371
|
var path$40 = require("path");
|
|
22347
21372
|
var fs$20 = require("fs");
|
|
22348
21373
|
var { TimeoutError } = require_errors$2();
|
|
@@ -22441,7 +21466,7 @@ var require_utils$3 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
22441
21466
|
* @returns
|
|
22442
21467
|
*/
|
|
22443
21468
|
getNodeID() {
|
|
22444
|
-
return os$
|
|
21469
|
+
return os$19.hostname().toLowerCase() + "-" + process.pid;
|
|
22445
21470
|
},
|
|
22446
21471
|
/**
|
|
22447
21472
|
* Get list of local IPs
|
|
@@ -22451,7 +21476,7 @@ var require_utils$3 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
22451
21476
|
getIpList() {
|
|
22452
21477
|
const list = [];
|
|
22453
21478
|
const ilist = [];
|
|
22454
|
-
const interfaces = os$
|
|
21479
|
+
const interfaces = os$19.networkInterfaces();
|
|
22455
21480
|
for (let iface in interfaces) for (let i in interfaces[iface]) {
|
|
22456
21481
|
const f = interfaces[iface]?.[i];
|
|
22457
21482
|
if (f.family === "IPv4") if (f.internal) {
|
|
@@ -24137,7 +23162,7 @@ var require_event$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
24137
23162
|
var require_datadog$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
24138
23163
|
var BaseReporter = require_base$8();
|
|
24139
23164
|
var _ = require_lodash();
|
|
24140
|
-
var os$
|
|
23165
|
+
var os$18 = require("os");
|
|
24141
23166
|
var { MoleculerError } = require_errors$2();
|
|
24142
23167
|
var METRIC = require_constants$6();
|
|
24143
23168
|
var { isFunction } = require_utils$3();
|
|
@@ -24170,7 +23195,7 @@ var require_datadog$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, m
|
|
|
24170
23195
|
super(opts);
|
|
24171
23196
|
/** @type {DatadogReporterOptions} */
|
|
24172
23197
|
this.opts = _.defaultsDeep(this.opts, {
|
|
24173
|
-
host: os$
|
|
23198
|
+
host: os$18.hostname(),
|
|
24174
23199
|
baseUrl: BASE_URL,
|
|
24175
23200
|
apiVersion: "v1",
|
|
24176
23201
|
path: "/series",
|
|
@@ -24846,18 +23871,18 @@ var require_cpu_usage$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports,
|
|
|
24846
23871
|
*
|
|
24847
23872
|
* Based on: https://github.com/icebob/cpu
|
|
24848
23873
|
*/
|
|
24849
|
-
var os$
|
|
23874
|
+
var os$17 = require("os");
|
|
24850
23875
|
/* istanbul ignore next */
|
|
24851
23876
|
module.exports = function getCpuUsage(sampleTime = 100) {
|
|
24852
23877
|
return new Promise((resolve, reject) => {
|
|
24853
23878
|
try {
|
|
24854
|
-
const first = os$
|
|
23879
|
+
const first = os$17.cpus().map((cpu) => cpu.times);
|
|
24855
23880
|
setTimeout(() => {
|
|
24856
23881
|
try {
|
|
24857
|
-
const second = os$
|
|
23882
|
+
const second = os$17.cpus().map((cpu) => cpu.times);
|
|
24858
23883
|
setTimeout(() => {
|
|
24859
23884
|
try {
|
|
24860
|
-
const third = os$
|
|
23885
|
+
const third = os$17.cpus().map((cpu) => cpu.times);
|
|
24861
23886
|
const usages = [];
|
|
24862
23887
|
for (let i = 0; i < first.length; i++) {
|
|
24863
23888
|
const first_idle = first[i].idle;
|
|
@@ -24890,7 +23915,7 @@ var require_cpu_usage$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports,
|
|
|
24890
23915
|
//#endregion
|
|
24891
23916
|
//#region ../../node_modules/moleculer/src/metrics/commons.js
|
|
24892
23917
|
var require_commons = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
24893
|
-
var os$
|
|
23918
|
+
var os$16 = require("os");
|
|
24894
23919
|
var METRIC = require_constants$6();
|
|
24895
23920
|
var cpuUsage = require_cpu_usage$1();
|
|
24896
23921
|
var v8;
|
|
@@ -25069,27 +24094,27 @@ var require_commons = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
25069
24094
|
name: METRIC.OS_TYPE,
|
|
25070
24095
|
type: METRIC.TYPE_INFO,
|
|
25071
24096
|
description: "OS type"
|
|
25072
|
-
}).set(os$
|
|
24097
|
+
}).set(os$16.type());
|
|
25073
24098
|
this.register({
|
|
25074
24099
|
name: METRIC.OS_RELEASE,
|
|
25075
24100
|
type: METRIC.TYPE_INFO,
|
|
25076
24101
|
description: "OS release"
|
|
25077
|
-
}).set(os$
|
|
24102
|
+
}).set(os$16.release());
|
|
25078
24103
|
this.register({
|
|
25079
24104
|
name: METRIC.OS_HOSTNAME,
|
|
25080
24105
|
type: METRIC.TYPE_INFO,
|
|
25081
24106
|
description: "Hostname"
|
|
25082
|
-
}).set(os$
|
|
24107
|
+
}).set(os$16.hostname());
|
|
25083
24108
|
this.register({
|
|
25084
24109
|
name: METRIC.OS_ARCH,
|
|
25085
24110
|
type: METRIC.TYPE_INFO,
|
|
25086
24111
|
description: "OS architecture"
|
|
25087
|
-
}).set(os$
|
|
24112
|
+
}).set(os$16.arch());
|
|
25088
24113
|
this.register({
|
|
25089
24114
|
name: METRIC.OS_PLATFORM,
|
|
25090
24115
|
type: METRIC.TYPE_INFO,
|
|
25091
24116
|
description: "OS platform"
|
|
25092
|
-
}).set(os$
|
|
24117
|
+
}).set(os$16.platform());
|
|
25093
24118
|
const userInfo = getUserInfo();
|
|
25094
24119
|
this.register({
|
|
25095
24120
|
name: METRIC.OS_USER_UID,
|
|
@@ -25240,22 +24265,22 @@ var require_commons = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
25240
24265
|
}
|
|
25241
24266
|
this.set(METRIC.PROCESS_UPTIME, process.uptime());
|
|
25242
24267
|
this.set(METRIC.PROCESS_INTERNAL_ACTIVE_HANDLES, process.getActiveResourcesInfo().length);
|
|
25243
|
-
const freeMem = os$
|
|
25244
|
-
const totalMem = os$
|
|
24268
|
+
const freeMem = os$16.freemem();
|
|
24269
|
+
const totalMem = os$16.totalmem();
|
|
25245
24270
|
const usedMem = totalMem - freeMem;
|
|
25246
24271
|
this.set(METRIC.OS_MEMORY_FREE, freeMem);
|
|
25247
24272
|
this.set(METRIC.OS_MEMORY_USED, usedMem);
|
|
25248
24273
|
this.set(METRIC.OS_MEMORY_TOTAL, totalMem);
|
|
25249
|
-
this.set(METRIC.OS_UPTIME, os$
|
|
25250
|
-
this.set(METRIC.OS_TYPE, os$
|
|
25251
|
-
this.set(METRIC.OS_RELEASE, os$
|
|
25252
|
-
this.set(METRIC.OS_HOSTNAME, os$
|
|
25253
|
-
this.set(METRIC.OS_ARCH, os$
|
|
25254
|
-
this.set(METRIC.OS_PLATFORM, os$
|
|
24274
|
+
this.set(METRIC.OS_UPTIME, os$16.uptime());
|
|
24275
|
+
this.set(METRIC.OS_TYPE, os$16.type());
|
|
24276
|
+
this.set(METRIC.OS_RELEASE, os$16.release());
|
|
24277
|
+
this.set(METRIC.OS_HOSTNAME, os$16.hostname());
|
|
24278
|
+
this.set(METRIC.OS_ARCH, os$16.arch());
|
|
24279
|
+
this.set(METRIC.OS_PLATFORM, os$16.platform());
|
|
25255
24280
|
const getNetworkInterfaces = () => {
|
|
25256
24281
|
const list = [];
|
|
25257
24282
|
const ilist = [];
|
|
25258
|
-
const interfaces = os$
|
|
24283
|
+
const interfaces = os$16.networkInterfaces();
|
|
25259
24284
|
for (let iface in interfaces) for (let i in interfaces[iface]) {
|
|
25260
24285
|
const f = interfaces[iface][i];
|
|
25261
24286
|
if (f.internal) ilist.push({
|
|
@@ -25285,7 +24310,7 @@ var require_commons = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
25285
24310
|
this.set(METRIC.OS_DATETIME_ISO, d.toISOString());
|
|
25286
24311
|
this.set(METRIC.OS_DATETIME_UTC, d.toUTCString());
|
|
25287
24312
|
this.set(METRIC.OS_DATETIME_TZ_OFFSET, d.getTimezoneOffset());
|
|
25288
|
-
const load = os$
|
|
24313
|
+
const load = os$16.loadavg();
|
|
25289
24314
|
this.set(METRIC.OS_CPU_LOAD_1, load[0]);
|
|
25290
24315
|
this.set(METRIC.OS_CPU_LOAD_5, load[1]);
|
|
25291
24316
|
this.set(METRIC.OS_CPU_LOAD_15, load[2]);
|
|
@@ -25293,7 +24318,7 @@ var require_commons = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
25293
24318
|
return this.broker.Promise.resolve().then(() => cpuUsage().then((res) => {
|
|
25294
24319
|
this.set(METRIC.OS_CPU_UTILIZATION, res.avg);
|
|
25295
24320
|
try {
|
|
25296
|
-
const cpus = os$
|
|
24321
|
+
const cpus = os$16.cpus();
|
|
25297
24322
|
this.set(METRIC.OS_CPU_TOTAL, cpus.length);
|
|
25298
24323
|
this.set(METRIC.OS_CPU_USER, cpus.reduce((a, b) => a + b.times.user, 0));
|
|
25299
24324
|
this.set(METRIC.OS_CPU_SYSTEM, cpus.reduce((a, b) => a + b.times.sys, 0));
|
|
@@ -25315,7 +24340,7 @@ var require_commons = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
25315
24340
|
*/
|
|
25316
24341
|
function getUserInfo() {
|
|
25317
24342
|
try {
|
|
25318
|
-
return os$
|
|
24343
|
+
return os$16.userInfo();
|
|
25319
24344
|
} catch {
|
|
25320
24345
|
/* istanbul ignore next */
|
|
25321
24346
|
return {};
|
|
@@ -27751,7 +26776,7 @@ var require_index_min = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) =
|
|
|
27751
26776
|
var require_shard = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
27752
26777
|
var _ = require_lodash();
|
|
27753
26778
|
var BaseStrategy = require_base$7();
|
|
27754
|
-
var crypto$
|
|
26779
|
+
var crypto$3 = require("crypto");
|
|
27755
26780
|
var { LRUCache } = require_index_min();
|
|
27756
26781
|
var { isFunction, randomInt } = require_utils$3();
|
|
27757
26782
|
/**
|
|
@@ -27857,7 +26882,7 @@ var require_shard = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modul
|
|
|
27857
26882
|
* @memberof ShardStrategy
|
|
27858
26883
|
*/
|
|
27859
26884
|
getHash(key) {
|
|
27860
|
-
const hash = crypto$
|
|
26885
|
+
const hash = crypto$3.createHash("md5").update(key).digest("hex");
|
|
27861
26886
|
const hashNum = parseInt(hash.substring(0, 8), 16);
|
|
27862
26887
|
return this.opts.ringSize ? hashNum % this.opts.ringSize : hashNum;
|
|
27863
26888
|
}
|
|
@@ -35537,7 +34562,7 @@ var require_node = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module
|
|
|
35537
34562
|
//#region ../../node_modules/moleculer/src/registry/node-catalog.js
|
|
35538
34563
|
var require_node_catalog = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
35539
34564
|
var _ = require_lodash();
|
|
35540
|
-
var os$
|
|
34565
|
+
var os$15 = require("os");
|
|
35541
34566
|
var Node = require_node();
|
|
35542
34567
|
var { getIpList } = require_utils$3();
|
|
35543
34568
|
/**
|
|
@@ -35583,7 +34608,7 @@ var require_node_catalog = /* @__PURE__ */ require_chunk.__commonJSMin(((exports
|
|
|
35583
34608
|
node.local = true;
|
|
35584
34609
|
node.ipList = getIpList();
|
|
35585
34610
|
node.instanceID = this.broker.instanceID;
|
|
35586
|
-
node.hostname = os$
|
|
34611
|
+
node.hostname = os$15.hostname();
|
|
35587
34612
|
node.client = {
|
|
35588
34613
|
type: "nodejs",
|
|
35589
34614
|
version: this.broker.MOLECULER_VERSION,
|
|
@@ -37657,7 +36682,7 @@ var require_console$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, m
|
|
|
37657
36682
|
var require_datadog$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
37658
36683
|
var BaseLogger = require_base$4();
|
|
37659
36684
|
var _ = require_lodash();
|
|
37660
|
-
var os$
|
|
36685
|
+
var os$14 = require("os");
|
|
37661
36686
|
var { MoleculerError } = require_errors$2();
|
|
37662
36687
|
var util$6 = require("util");
|
|
37663
36688
|
var { isObject } = require_utils$3();
|
|
@@ -37690,7 +36715,7 @@ var require_datadog$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, m
|
|
|
37690
36715
|
apiKey: process.env.DATADOG_API_KEY,
|
|
37691
36716
|
ddSource: "moleculer",
|
|
37692
36717
|
env: void 0,
|
|
37693
|
-
hostname: os$
|
|
36718
|
+
hostname: os$14.hostname(),
|
|
37694
36719
|
objectPrinter: null,
|
|
37695
36720
|
interval: 10 * 1e3
|
|
37696
36721
|
});
|
|
@@ -37886,7 +36911,7 @@ var require_file$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
37886
36911
|
var _ = require_lodash();
|
|
37887
36912
|
var fs$16 = require("fs/promises");
|
|
37888
36913
|
var path$37 = require("path");
|
|
37889
|
-
var os$
|
|
36914
|
+
var os$13 = require("os");
|
|
37890
36915
|
var { makeDirs } = require_utils$3();
|
|
37891
36916
|
/**
|
|
37892
36917
|
* Import types
|
|
@@ -37915,7 +36940,7 @@ var require_file$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
37915
36940
|
this.opts = _.defaultsDeep(this.opts, {
|
|
37916
36941
|
folder: "./logs",
|
|
37917
36942
|
filename: "moleculer-{date}.log",
|
|
37918
|
-
eol: os$
|
|
36943
|
+
eol: os$13.EOL,
|
|
37919
36944
|
interval: 1 * 1e3
|
|
37920
36945
|
});
|
|
37921
36946
|
this.opts.colors = false;
|
|
@@ -38335,7 +37360,7 @@ var require_lib$5 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modul
|
|
|
38335
37360
|
//#region ../../node_modules/log4js/lib/layouts.js
|
|
38336
37361
|
var require_layouts = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
38337
37362
|
var dateFormat = require_lib$5();
|
|
38338
|
-
var os$
|
|
37363
|
+
var os$12 = require("os");
|
|
38339
37364
|
var util$4 = require("util");
|
|
38340
37365
|
var path$36 = require("path");
|
|
38341
37366
|
var styles = {
|
|
@@ -38461,13 +37486,13 @@ var require_layouts = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mod
|
|
|
38461
37486
|
return dateFormat.asString(format, loggingEvent.startTime);
|
|
38462
37487
|
}
|
|
38463
37488
|
function hostname() {
|
|
38464
|
-
return os$
|
|
37489
|
+
return os$12.hostname().toString();
|
|
38465
37490
|
}
|
|
38466
37491
|
function formatMessage(loggingEvent) {
|
|
38467
37492
|
return util$4.format(...loggingEvent.data);
|
|
38468
37493
|
}
|
|
38469
37494
|
function endOfLine() {
|
|
38470
|
-
return os$
|
|
37495
|
+
return os$12.EOL;
|
|
38471
37496
|
}
|
|
38472
37497
|
function logLevel(loggingEvent) {
|
|
38473
37498
|
return loggingEvent.level.toString();
|
|
@@ -40066,11 +39091,11 @@ var require_mkdirs = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
40066
39091
|
//#region ../../node_modules/streamroller/node_modules/fs-extra/lib/util/utimes.js
|
|
40067
39092
|
var require_utimes = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
40068
39093
|
var fs = require_graceful_fs();
|
|
40069
|
-
var os$
|
|
39094
|
+
var os$11 = require("os");
|
|
40070
39095
|
var path$32 = require("path");
|
|
40071
39096
|
function hasMillisResSync() {
|
|
40072
39097
|
let tmpfile = path$32.join("millis-test-sync" + Date.now().toString() + Math.random().toString().slice(2));
|
|
40073
|
-
tmpfile = path$32.join(os$
|
|
39098
|
+
tmpfile = path$32.join(os$11.tmpdir(), tmpfile);
|
|
40074
39099
|
const d = /* @__PURE__ */ new Date(1435410243862);
|
|
40075
39100
|
fs.writeFileSync(tmpfile, "https://github.com/jprichardson/node-fs-extra/pull/141");
|
|
40076
39101
|
const fd = fs.openSync(tmpfile, "r+");
|
|
@@ -40080,7 +39105,7 @@ var require_utimes = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
40080
39105
|
}
|
|
40081
39106
|
function hasMillisRes(callback) {
|
|
40082
39107
|
let tmpfile = path$32.join("millis-test" + Date.now().toString() + Math.random().toString().slice(2));
|
|
40083
|
-
tmpfile = path$32.join(os$
|
|
39108
|
+
tmpfile = path$32.join(os$11.tmpdir(), tmpfile);
|
|
40084
39109
|
const d = /* @__PURE__ */ new Date(1435410243862);
|
|
40085
39110
|
fs.writeFile(tmpfile, "https://github.com/jprichardson/node-fs-extra/pull/141", (err) => {
|
|
40086
39111
|
if (err) return callback(err);
|
|
@@ -46382,7 +45407,7 @@ var require_multistream = /* @__PURE__ */ require_chunk.__commonJSMin(((exports,
|
|
|
46382
45407
|
//#endregion
|
|
46383
45408
|
//#region ../../node_modules/pino/pino.js
|
|
46384
45409
|
var require_pino$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
46385
|
-
var os$
|
|
45410
|
+
var os$10 = require("node:os");
|
|
46386
45411
|
var stdSerializers = require_pino_std_serializers();
|
|
46387
45412
|
var caller = require_caller();
|
|
46388
45413
|
var redaction = require_redaction();
|
|
@@ -46397,7 +45422,7 @@ var require_pino$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
46397
45422
|
var { chindingsSym, redactFmtSym, serializersSym, timeSym, timeSliceIndexSym, streamSym, stringifySym, stringifySafeSym, stringifiersSym, setLevelSym, endSym, formatOptsSym, messageKeySym, errorKeySym, nestedKeySym, mixinSym, levelCompSym, useOnlyCustomLevelsSym, formattersSym, hooksSym, nestedKeyStrSym, mixinMergeStrategySym, msgPrefixSym } = symbols;
|
|
46398
45423
|
var { epochTime, nullTime } = time;
|
|
46399
45424
|
var { pid } = process;
|
|
46400
|
-
var hostname = os$
|
|
45425
|
+
var hostname = os$10.hostname();
|
|
46401
45426
|
var defaultErrorSerializer = stdSerializers.err;
|
|
46402
45427
|
var normalize = createArgsNormalizer({
|
|
46403
45428
|
level: "info",
|
|
@@ -49115,7 +48140,7 @@ var require_validators$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports
|
|
|
49115
48140
|
//#region ../../node_modules/moleculer/src/cachers/base.js
|
|
49116
48141
|
var require_base$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
49117
48142
|
var _ = require_lodash();
|
|
49118
|
-
var crypto$
|
|
48143
|
+
var crypto$2 = require("crypto");
|
|
49119
48144
|
var { METRIC } = require_metrics$1();
|
|
49120
48145
|
var { isObject, isFunction, isDate } = require_utils$3();
|
|
49121
48146
|
/**
|
|
@@ -49379,7 +48404,7 @@ var require_base$2 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
49379
48404
|
const maxParamsLength = this.opts.maxParamsLength;
|
|
49380
48405
|
if (!maxParamsLength || maxParamsLength < 44 || key.length <= maxParamsLength) return key;
|
|
49381
48406
|
const prefixLength = maxParamsLength - 44;
|
|
49382
|
-
const base64Hash = crypto$
|
|
48407
|
+
const base64Hash = crypto$2.createHash("sha256").update(key).digest("base64");
|
|
49383
48408
|
if (prefixLength < 1) return base64Hash;
|
|
49384
48409
|
return key.substring(0, prefixLength) + base64Hash;
|
|
49385
48410
|
}
|
|
@@ -72502,7 +71527,7 @@ var require_ipaddr = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
72502
71527
|
//#region ../../node_modules/moleculer/src/transporters/tcp/udp-broadcaster.js
|
|
72503
71528
|
var require_udp_broadcaster = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
72504
71529
|
var EventEmitter$2 = require("events");
|
|
72505
|
-
var os$
|
|
71530
|
+
var os$9 = require("os");
|
|
72506
71531
|
var dgram = require("dgram");
|
|
72507
71532
|
var ipaddr = require_ipaddr();
|
|
72508
71533
|
var { randomInt } = require_utils$3();
|
|
@@ -72713,7 +71738,7 @@ var require_udp_broadcaster = /* @__PURE__ */ require_chunk.__commonJSMin(((expo
|
|
|
72713
71738
|
*/
|
|
72714
71739
|
getBroadcastAddresses() {
|
|
72715
71740
|
const list = [];
|
|
72716
|
-
const interfaces = os$
|
|
71741
|
+
const interfaces = os$9.networkInterfaces();
|
|
72717
71742
|
for (let iface in interfaces) for (let i in interfaces[iface]) {
|
|
72718
71743
|
const f = interfaces[iface][i];
|
|
72719
71744
|
if (f.family === "IPv4") list.push(ipaddr.IPv4.broadcastAddressFromCIDR(f.cidr).toString());
|
|
@@ -72728,7 +71753,7 @@ var require_udp_broadcaster = /* @__PURE__ */ require_chunk.__commonJSMin(((expo
|
|
|
72728
71753
|
*/
|
|
72729
71754
|
getInterfaceAddresses() {
|
|
72730
71755
|
const list = [];
|
|
72731
|
-
const interfaces = os$
|
|
71756
|
+
const interfaces = os$9.networkInterfaces();
|
|
72732
71757
|
for (let iface in interfaces) for (let i in interfaces[iface]) {
|
|
72733
71758
|
const f = interfaces[iface][i];
|
|
72734
71759
|
if (f.family === "IPv4") list.push(f.address);
|
|
@@ -74011,7 +73036,7 @@ var init_package = require_chunk.__esmMin((() => {
|
|
|
74011
73036
|
//#endregion
|
|
74012
73037
|
//#region ../../node_modules/moleculer/src/health.js
|
|
74013
73038
|
var require_health = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
74014
|
-
var os$
|
|
73039
|
+
var os$8 = require("os");
|
|
74015
73040
|
var { getIpList } = require_utils$3();
|
|
74016
73041
|
var MOLECULER_VERSION = (init_package(), require_chunk.__toCommonJS(package_exports).default).version;
|
|
74017
73042
|
/**
|
|
@@ -74027,9 +73052,9 @@ var require_health = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
74027
73052
|
};
|
|
74028
73053
|
};
|
|
74029
73054
|
var getCpuInfo = () => {
|
|
74030
|
-
const cpus = os$
|
|
74031
|
-
const load = os$
|
|
74032
|
-
const cores = Array.isArray(cpus) ? os$
|
|
73055
|
+
const cpus = os$8.cpus();
|
|
73056
|
+
const load = os$8.loadavg();
|
|
73057
|
+
const cores = Array.isArray(cpus) ? os$8.cpus().length : null;
|
|
74033
73058
|
return {
|
|
74034
73059
|
load1: load[0],
|
|
74035
73060
|
load5: load[1],
|
|
@@ -74040,8 +73065,8 @@ var require_health = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
74040
73065
|
};
|
|
74041
73066
|
var getMemoryInfo = () => {
|
|
74042
73067
|
const mem = {
|
|
74043
|
-
free: os$
|
|
74044
|
-
total: os$
|
|
73068
|
+
free: os$8.freemem(),
|
|
73069
|
+
total: os$8.totalmem(),
|
|
74045
73070
|
percent: null
|
|
74046
73071
|
};
|
|
74047
73072
|
mem.percent = mem.free * 100 / mem.total;
|
|
@@ -74053,19 +73078,19 @@ var require_health = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
74053
73078
|
*/
|
|
74054
73079
|
var getUserInfo = () => {
|
|
74055
73080
|
try {
|
|
74056
|
-
return os$
|
|
73081
|
+
return os$8.userInfo();
|
|
74057
73082
|
} catch {
|
|
74058
73083
|
return {};
|
|
74059
73084
|
}
|
|
74060
73085
|
};
|
|
74061
73086
|
var getOsInfo = () => {
|
|
74062
73087
|
return {
|
|
74063
|
-
uptime: os$
|
|
74064
|
-
type: os$
|
|
74065
|
-
release: os$
|
|
74066
|
-
hostname: os$
|
|
74067
|
-
arch: os$
|
|
74068
|
-
platform: os$
|
|
73088
|
+
uptime: os$8.uptime(),
|
|
73089
|
+
type: os$8.type(),
|
|
73090
|
+
release: os$8.release(),
|
|
73091
|
+
hostname: os$8.hostname(),
|
|
73092
|
+
arch: os$8.arch(),
|
|
73093
|
+
platform: os$8.platform(),
|
|
74069
73094
|
user: getUserInfo()
|
|
74070
73095
|
};
|
|
74071
73096
|
};
|
|
@@ -75758,11 +74783,11 @@ var require_ttl = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module)
|
|
|
75758
74783
|
//#endregion
|
|
75759
74784
|
//#region ../../node_modules/recursive-watch/index.js
|
|
75760
74785
|
var require_recursive_watch = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
75761
|
-
var os$
|
|
74786
|
+
var os$7 = require("os");
|
|
75762
74787
|
var fs$9 = require("fs");
|
|
75763
74788
|
var path$11 = require("path");
|
|
75764
74789
|
var Cache = require_ttl();
|
|
75765
|
-
var watchDirectory = os$
|
|
74790
|
+
var watchDirectory = os$7.platform() === "linux" ? watchFallback : watchRecursive;
|
|
75766
74791
|
module.exports = watch;
|
|
75767
74792
|
function watch(name, onchange) {
|
|
75768
74793
|
var clear = null;
|
|
@@ -76127,7 +75152,7 @@ var require_hot_reload = /* @__PURE__ */ require_chunk.__commonJSMin(((exports,
|
|
|
76127
75152
|
//#endregion
|
|
76128
75153
|
//#region ../../node_modules/moleculer/src/middlewares/transmit/encryption.js
|
|
76129
75154
|
var require_encryption = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
76130
|
-
var crypto$
|
|
75155
|
+
var crypto$1 = require("crypto");
|
|
76131
75156
|
/**
|
|
76132
75157
|
* This is a AES encryption middleware to protect the whole
|
|
76133
75158
|
* Moleculer transporter communication with AES.
|
|
@@ -76150,14 +75175,14 @@ var require_encryption = /* @__PURE__ */ require_chunk.__commonJSMin(((exports,
|
|
|
76150
75175
|
},
|
|
76151
75176
|
transporterSend(next) {
|
|
76152
75177
|
return (topic, data, meta) => {
|
|
76153
|
-
const encrypter = iv ? crypto$
|
|
75178
|
+
const encrypter = iv ? crypto$1.createCipheriv(algorithm, password, iv) : crypto$1.createCipher(algorithm, password);
|
|
76154
75179
|
return next(topic, Buffer.concat([encrypter.update(data), encrypter.final()]), meta);
|
|
76155
75180
|
};
|
|
76156
75181
|
},
|
|
76157
75182
|
transporterReceive(next) {
|
|
76158
75183
|
return (cmd, data, s) => {
|
|
76159
75184
|
try {
|
|
76160
|
-
const decrypter = iv ? crypto$
|
|
75185
|
+
const decrypter = iv ? crypto$1.createDecipheriv(algorithm, password, iv) : crypto$1.createDecipher(algorithm, password);
|
|
76161
75186
|
return next(cmd, Buffer.concat([decrypter.update(data), decrypter.final()]), s);
|
|
76162
75187
|
} catch (err) {
|
|
76163
75188
|
logger.error("Received packet decryption error.", err);
|
|
@@ -82738,7 +81763,7 @@ var require_has_flag = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, mo
|
|
|
82738
81763
|
//#endregion
|
|
82739
81764
|
//#region ../../node_modules/args/node_modules/supports-color/index.js
|
|
82740
81765
|
var require_supports_color = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
82741
|
-
var os$
|
|
81766
|
+
var os$6 = require("os");
|
|
82742
81767
|
var hasFlag = require_has_flag();
|
|
82743
81768
|
var env = process.env;
|
|
82744
81769
|
var forceColor;
|
|
@@ -82761,7 +81786,7 @@ var require_supports_color = /* @__PURE__ */ require_chunk.__commonJSMin(((expor
|
|
|
82761
81786
|
if (stream && !stream.isTTY && forceColor !== true) return 0;
|
|
82762
81787
|
const min = forceColor ? 1 : 0;
|
|
82763
81788
|
if (process.platform === "win32") {
|
|
82764
|
-
const osRelease = os$
|
|
81789
|
+
const osRelease = os$6.release().split(".");
|
|
82765
81790
|
if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
82766
81791
|
return 1;
|
|
82767
81792
|
}
|
|
@@ -83651,8 +82676,8 @@ var require_lib = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module)
|
|
|
83651
82676
|
var require_main = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
83652
82677
|
var fs$4 = require("fs");
|
|
83653
82678
|
var path$3 = require("path");
|
|
83654
|
-
var os$
|
|
83655
|
-
var crypto
|
|
82679
|
+
var os$5 = require("os");
|
|
82680
|
+
var crypto = require("crypto");
|
|
83656
82681
|
var TIPS = [
|
|
83657
82682
|
"◈ encrypted .env [www.dotenvx.com]",
|
|
83658
82683
|
"◈ secrets for agents [www.dotenvx.com]",
|
|
@@ -83784,7 +82809,7 @@ var require_main = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module
|
|
|
83784
82809
|
return null;
|
|
83785
82810
|
}
|
|
83786
82811
|
function _resolveHome(envPath) {
|
|
83787
|
-
return envPath[0] === "~" ? path$3.join(os$
|
|
82812
|
+
return envPath[0] === "~" ? path$3.join(os$5.homedir(), envPath.slice(1)) : envPath;
|
|
83788
82813
|
}
|
|
83789
82814
|
function _configVault(options) {
|
|
83790
82815
|
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
@@ -83857,7 +82882,7 @@ var require_main = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module
|
|
|
83857
82882
|
const authTag = ciphertext.subarray(-16);
|
|
83858
82883
|
ciphertext = ciphertext.subarray(12, -16);
|
|
83859
82884
|
try {
|
|
83860
|
-
const aesgcm = crypto
|
|
82885
|
+
const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
|
|
83861
82886
|
aesgcm.setAuthTag(authTag);
|
|
83862
82887
|
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
83863
82888
|
} catch (error) {
|
|
@@ -83932,7 +82957,7 @@ var require_runner = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
83932
82957
|
var inspect$1 = require("util").inspect;
|
|
83933
82958
|
var _ = require_lodash();
|
|
83934
82959
|
var Args = require_lib();
|
|
83935
|
-
var os$
|
|
82960
|
+
var os$4 = require("os");
|
|
83936
82961
|
/** @type {Cluster} */
|
|
83937
82962
|
var cluster$2 = require("cluster");
|
|
83938
82963
|
var kleur = require_kleur();
|
|
@@ -84238,7 +83263,7 @@ var require_runner = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, modu
|
|
|
84238
83263
|
logger.info(`Worker #${worker.id} restarted`);
|
|
84239
83264
|
} else process.exit(code);
|
|
84240
83265
|
});
|
|
84241
|
-
const workerCount = Number.isInteger(instances) && instances > 0 ? instances : os$
|
|
83266
|
+
const workerCount = Number.isInteger(instances) && instances > 0 ? instances : os$4.cpus().length;
|
|
84242
83267
|
logger.info(`Starting ${workerCount} workers...`);
|
|
84243
83268
|
for (let i = 0; i < workerCount; i++) cluster$2.fork();
|
|
84244
83269
|
stopSignals.forEach(function(signal) {
|
|
@@ -84376,7 +83401,7 @@ var Gt = (n, t, e) => {
|
|
|
84376
83401
|
}
|
|
84377
83402
|
return h;
|
|
84378
83403
|
};
|
|
84379
|
-
var fe = "\0SLASH" + Math.random() + "\0", ue = "\0OPEN" + Math.random() + "\0", qt = "\0CLOSE" + Math.random() + "\0", de = "\0COMMA" + Math.random() + "\0", pe = "\0PERIOD" + Math.random() + "\0", is = new RegExp(fe, "g"), rs = new RegExp(ue, "g"), ns = new RegExp(qt, "g"), os$
|
|
83404
|
+
var fe = "\0SLASH" + Math.random() + "\0", ue = "\0OPEN" + Math.random() + "\0", qt = "\0CLOSE" + Math.random() + "\0", de = "\0COMMA" + Math.random() + "\0", pe = "\0PERIOD" + Math.random() + "\0", is = new RegExp(fe, "g"), rs = new RegExp(ue, "g"), ns = new RegExp(qt, "g"), os$3 = new RegExp(de, "g"), hs = new RegExp(pe, "g"), as = /\\\\/g, ls = /\\{/g, cs = /\\}/g, fs$2 = /\\,/g, us = /\\./g, ds = 1e5;
|
|
84380
83405
|
function Ht(n) {
|
|
84381
83406
|
return isNaN(n) ? n.charCodeAt(0) : parseInt(n, 10);
|
|
84382
83407
|
}
|
|
@@ -84384,7 +83409,7 @@ function ps(n) {
|
|
|
84384
83409
|
return n.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs$2, de).replace(us, pe);
|
|
84385
83410
|
}
|
|
84386
83411
|
function ms(n) {
|
|
84387
|
-
return n.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os$
|
|
83412
|
+
return n.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os$3, ",").replace(hs, ".");
|
|
84388
83413
|
}
|
|
84389
83414
|
function me(n) {
|
|
84390
83415
|
if (!n) return [""];
|
|
@@ -88018,6 +87043,11 @@ var TlsTcpTransporter = class extends TcpTransporterBase {
|
|
|
88018
87043
|
this.logger.warn("Dropping mesh packet — an enrolled agent accepts TLS from the hub only");
|
|
88019
87044
|
return;
|
|
88020
87045
|
}
|
|
87046
|
+
const wireSender = peekSender(this, type, message);
|
|
87047
|
+
if (wireSender === null || wireSender === this.nodeID) {
|
|
87048
|
+
this.logger.warn(wireSender === null ? "Dropping mesh packet - it names no sender" : "Dropping mesh packet - it claims this node as its sender");
|
|
87049
|
+
return;
|
|
87050
|
+
}
|
|
88021
87051
|
if (socket !== void 0 && isTlsSocket(socket)) {
|
|
88022
87052
|
const tlsSock = socket;
|
|
88023
87053
|
const identity = tlsSock.meshPeerCn ? {
|
|
@@ -88033,9 +87063,8 @@ var TlsTcpTransporter = class extends TcpTransporterBase {
|
|
|
88033
87063
|
tlsSock.destroy();
|
|
88034
87064
|
return;
|
|
88035
87065
|
}
|
|
88036
|
-
|
|
88037
|
-
|
|
88038
|
-
this.logger.warn(`Dropping forged mesh packet — sender=${sender} peerCN=${identity.cn}`);
|
|
87066
|
+
if (wireSender !== identity.cn) {
|
|
87067
|
+
this.logger.warn(`Dropping forged mesh packet — sender=${wireSender} peerCN=${identity.cn}`);
|
|
88039
87068
|
return;
|
|
88040
87069
|
}
|
|
88041
87070
|
tlsSock.meshPeerCn = identity.cn;
|
|
@@ -89297,170 +88326,10 @@ var HubPairing = class {
|
|
|
89297
88326
|
}
|
|
89298
88327
|
};
|
|
89299
88328
|
//#endregion
|
|
89300
|
-
//#region src/builtins/system-config/cluster-secret-keeper.ts
|
|
89301
|
-
/**
|
|
89302
|
-
* Keeps the hub's cluster-secret gate in step with System → Cluster (D797,
|
|
89303
|
-
* D802).
|
|
89304
|
-
*
|
|
89305
|
-
* The field is a `password` of `system-config`: its `system-settings` row
|
|
89306
|
-
* (`cluster.clusterSecret`) holds a keychain marker, the value lives in the
|
|
89307
|
-
* keychain (owner `system`). The gate the mesh join reads:
|
|
89308
|
-
*
|
|
89309
|
-
* - no marker → the secret is MANDATORY (D802): the keeper asks
|
|
89310
|
-
* its owner to generate one (`generateSecret`), and
|
|
89311
|
-
* until that succeeds the gate is `off` — no node can
|
|
89312
|
-
* authenticate (mesh auth is always enforced, D821);
|
|
89313
|
-
* - marker + value → `on` — nodes prove the secret;
|
|
89314
|
-
* - marker, no answer → `unknown` — refused, retryably, and retried here.
|
|
89315
|
-
* A locked keychain or a value lost to a reset NEVER opens the gate, and
|
|
89316
|
-
* never triggers a generation (the operator decides what replaces a value
|
|
89317
|
-
* the keychain lost).
|
|
89318
|
-
*
|
|
89319
|
-
* It also publishes the mesh mode (`cluster.meshAuth`, `mesh-auth-mode.ts`).
|
|
89320
|
-
*/
|
|
89321
|
-
/** The field key inside the `cluster` section. */
|
|
89322
|
-
var CLUSTER_SECRET_FIELD = "clusterSecret";
|
|
89323
|
-
var ClusterSecretKeeper = class {
|
|
89324
|
-
deps;
|
|
89325
|
-
retryTimer = null;
|
|
89326
|
-
unsubscribe = null;
|
|
89327
|
-
stopped = false;
|
|
89328
|
-
last = null;
|
|
89329
|
-
constructor(deps) {
|
|
89330
|
-
this.deps = deps;
|
|
89331
|
-
}
|
|
89332
|
-
async start() {
|
|
89333
|
-
this.unsubscribe = this.deps.secrets?.onChange((ref) => {
|
|
89334
|
-
if (ref === require_constants$8.CLUSTER_SECRET_REF) this.reload();
|
|
89335
|
-
}) ?? null;
|
|
89336
|
-
await this.reload();
|
|
89337
|
-
}
|
|
89338
|
-
stop() {
|
|
89339
|
-
this.stopped = true;
|
|
89340
|
-
if (this.retryTimer !== null) clearTimeout(this.retryTimer);
|
|
89341
|
-
this.retryTimer = null;
|
|
89342
|
-
this.unsubscribe?.();
|
|
89343
|
-
this.unsubscribe = null;
|
|
89344
|
-
}
|
|
89345
|
-
/** Re-read the row and the keychain; publish the gate. */
|
|
89346
|
-
async reload() {
|
|
89347
|
-
if (this.stopped) return;
|
|
89348
|
-
let gate = await this.compute();
|
|
89349
|
-
if (gate.kind === "off" && this.deps.generateSecret !== void 0 && !this.stopped) gate = await this.generate();
|
|
89350
|
-
if (this.stopped) return;
|
|
89351
|
-
require_constants$8.setProcessClusterSecretGate(gate);
|
|
89352
|
-
this.report(gate);
|
|
89353
|
-
if (gate.kind === "unknown" || gate.kind === "off" && this.deps.generateSecret !== void 0) this.scheduleRetry();
|
|
89354
|
-
}
|
|
89355
|
-
async generate() {
|
|
89356
|
-
try {
|
|
89357
|
-
await this.deps.generateSecret?.();
|
|
89358
|
-
} catch (err) {
|
|
89359
|
-
this.deps.logger.error("The cluster secret is mandatory but could not be generated yet — retrying. Agents cannot authenticate until it exists.", { meta: { error: errText(err) } });
|
|
89360
|
-
return { kind: "off" };
|
|
89361
|
-
}
|
|
89362
|
-
this.deps.logger.info("Generated the cluster secret (none was stored). Reveal it on System → Cluster and enter it in each agent.");
|
|
89363
|
-
return this.compute();
|
|
89364
|
-
}
|
|
89365
|
-
async compute() {
|
|
89366
|
-
let section;
|
|
89367
|
-
try {
|
|
89368
|
-
section = await this.deps.readSection();
|
|
89369
|
-
} catch (err) {
|
|
89370
|
-
return {
|
|
89371
|
-
kind: "unknown",
|
|
89372
|
-
reason: `settings unreadable: ${errText(err)}`
|
|
89373
|
-
};
|
|
89374
|
-
}
|
|
89375
|
-
setProcessMeshAuthMode("enforced");
|
|
89376
|
-
const stored = section[CLUSTER_SECRET_FIELD];
|
|
89377
|
-
if (stored === void 0 || stored === null || stored === "") return { kind: "off" };
|
|
89378
|
-
if (!require_dist.isSecretMarker(stored)) return {
|
|
89379
|
-
kind: "unknown",
|
|
89380
|
-
reason: "stored inline, not in the keychain — set it again in System → Cluster"
|
|
89381
|
-
};
|
|
89382
|
-
const secrets = this.deps.secrets;
|
|
89383
|
-
if (secrets === null) return {
|
|
89384
|
-
kind: "unknown",
|
|
89385
|
-
reason: "no keychain door in this process"
|
|
89386
|
-
};
|
|
89387
|
-
let entry;
|
|
89388
|
-
try {
|
|
89389
|
-
entry = (await secrets.resolve([require_constants$8.CLUSTER_SECRET_REF]))[require_constants$8.CLUSTER_SECRET_REF];
|
|
89390
|
-
} catch (err) {
|
|
89391
|
-
return {
|
|
89392
|
-
kind: "unknown",
|
|
89393
|
-
reason: errText(err)
|
|
89394
|
-
};
|
|
89395
|
-
}
|
|
89396
|
-
if (entry === void 0) return {
|
|
89397
|
-
kind: "unknown",
|
|
89398
|
-
reason: "no-answer"
|
|
89399
|
-
};
|
|
89400
|
-
switch (entry.kind) {
|
|
89401
|
-
case "value": return {
|
|
89402
|
-
kind: "on",
|
|
89403
|
-
hash: require_constants$8.hashClusterSecret(entry.value)
|
|
89404
|
-
};
|
|
89405
|
-
case "unavailable": return {
|
|
89406
|
-
kind: "unknown",
|
|
89407
|
-
reason: entry.reason
|
|
89408
|
-
};
|
|
89409
|
-
case "missing": return {
|
|
89410
|
-
kind: "unknown",
|
|
89411
|
-
reason: "the stored value is gone — set it again in System → Cluster"
|
|
89412
|
-
};
|
|
89413
|
-
case "forbidden": return {
|
|
89414
|
-
kind: "unknown",
|
|
89415
|
-
reason: "forbidden"
|
|
89416
|
-
};
|
|
89417
|
-
}
|
|
89418
|
-
}
|
|
89419
|
-
report(gate) {
|
|
89420
|
-
const changed = this.last !== gate.kind;
|
|
89421
|
-
this.last = gate.kind;
|
|
89422
|
-
if (gate.kind === "unknown") {
|
|
89423
|
-
this.deps.logger.error("Agents cannot register: a cluster secret is set but cannot be read from the keychain. Registrations are refused until it can (no fallback).", { meta: { reason: gate.reason } });
|
|
89424
|
-
return;
|
|
89425
|
-
}
|
|
89426
|
-
if (changed) this.deps.logger.info(gate.kind === "on" ? "Cluster secret set — agents prove it to join the mesh" : "No cluster secret yet — no node can authenticate to the mesh");
|
|
89427
|
-
}
|
|
89428
|
-
scheduleRetry() {
|
|
89429
|
-
if (this.stopped || this.retryTimer !== null) return;
|
|
89430
|
-
this.retryTimer = setTimeout(() => {
|
|
89431
|
-
this.retryTimer = null;
|
|
89432
|
-
this.reload();
|
|
89433
|
-
}, this.deps.retryMs ?? 3e4);
|
|
89434
|
-
this.retryTimer.unref?.();
|
|
89435
|
-
}
|
|
89436
|
-
};
|
|
89437
|
-
function errText(err) {
|
|
89438
|
-
return err instanceof Error ? err.message : String(err);
|
|
89439
|
-
}
|
|
89440
|
-
//#endregion
|
|
89441
88329
|
//#region src/builtins/system-config/mesh-actions.ts
|
|
89442
88330
|
/**
|
|
89443
|
-
* System → Cluster —
|
|
89444
|
-
* agent-ui unlock tickets (D821).
|
|
88331
|
+
* System → Cluster — agent-ui unlock tickets (D821).
|
|
89445
88332
|
*/
|
|
89446
|
-
var mintJoinTokenInputSchema = zod.z.object({
|
|
89447
|
-
/** The node id the token is for - mandatory: the CSR CN must be exactly this. */
|
|
89448
|
-
nodeId: zod.z.string().min(1),
|
|
89449
|
-
/** Override hub HTTPS base (default: local-network publicEndpoint). */
|
|
89450
|
-
hubUrl: zod.z.string().url().optional(),
|
|
89451
|
-
/** Override `host:6443` TLS mesh address carried in the token. */
|
|
89452
|
-
hubMeshAddress: zod.z.string().min(3).optional(),
|
|
89453
|
-
/** Seconds until expiry; capped at 1 h. */
|
|
89454
|
-
ttlSec: zod.z.number().int().positive().max(3600).optional()
|
|
89455
|
-
});
|
|
89456
|
-
var mintJoinTokenOutputSchema = zod.z.object({
|
|
89457
|
-
token: zod.z.string().min(1),
|
|
89458
|
-
exp: zod.z.number().int(),
|
|
89459
|
-
hubUrl: zod.z.string(),
|
|
89460
|
-
hubMeshAddress: zod.z.string(),
|
|
89461
|
-
caFingerprint: zod.z.string(),
|
|
89462
|
-
nodeId: zod.z.string()
|
|
89463
|
-
});
|
|
89464
88333
|
var mintAgentUiUnlockInputSchema = zod.z.object({
|
|
89465
88334
|
nodeId: zod.z.string().min(1),
|
|
89466
88335
|
/**
|
|
@@ -89475,17 +88344,12 @@ var mintAgentUiUnlockOutputSchema = zod.z.object({
|
|
|
89475
88344
|
nodeId: zod.z.string().min(1),
|
|
89476
88345
|
dashboardUrl: zod.z.string().url().optional()
|
|
89477
88346
|
});
|
|
89478
|
-
var systemConfigMeshActions = require_dist.defineCustomActions({
|
|
89479
|
-
|
|
89480
|
-
|
|
89481
|
-
|
|
89482
|
-
|
|
89483
|
-
|
|
89484
|
-
mintAgentUiUnlockTicket: require_dist.customAction(mintAgentUiUnlockInputSchema, mintAgentUiUnlockOutputSchema, {
|
|
89485
|
-
kind: "mutation",
|
|
89486
|
-
auth: "admin"
|
|
89487
|
-
})
|
|
89488
|
-
});
|
|
88347
|
+
var systemConfigMeshActions = require_dist.defineCustomActions({
|
|
88348
|
+
/** Hub admin → short-lived ticket the agent redeems for a tab session (D821). */
|
|
88349
|
+
mintAgentUiUnlockTicket: require_dist.customAction(mintAgentUiUnlockInputSchema, mintAgentUiUnlockOutputSchema, {
|
|
88350
|
+
kind: "mutation",
|
|
88351
|
+
auth: "admin"
|
|
88352
|
+
}) });
|
|
89489
88353
|
//#endregion
|
|
89490
88354
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
89491
88355
|
/** How often superseded and expired mesh certificate rows are reaped. */
|
|
@@ -89500,13 +88364,13 @@ var MESH_REAP_MS = 24 * 36e5;
|
|
|
89500
88364
|
* state of their own (the session token lifetime).
|
|
89501
88365
|
*
|
|
89502
88366
|
* Sections exposed — this list is the whole of it:
|
|
89503
|
-
* - server (port, host, dataPath — READ-ONLY, loaded from config.yaml at bootstrap
|
|
88367
|
+
* - server (port, host, dataPath — READ-ONLY, loaded from config.yaml at bootstrap;
|
|
88368
|
+
* name = the hub's human name, `server.name`, editable — D861)
|
|
89504
88369
|
* - auth (tokenExpiry = session lifetime, accessTokenExpiry, trustedProxies,
|
|
89505
88370
|
* trustedNetworks)
|
|
89506
|
-
* - cluster (
|
|
89507
|
-
*
|
|
89508
|
-
*
|
|
89509
|
-
* boot; `meshAuth` — transition / enforced. D802)
|
|
88371
|
+
* - cluster (no operator field remains: the cluster secret and the mesh auth
|
|
88372
|
+
* mode were removed by D857 — a node's identity is its mesh
|
|
88373
|
+
* certificate, and agents are paired, not given a secret)
|
|
89510
88374
|
*
|
|
89511
88375
|
* Sections NOT exposed (each owned by the addon that implements them):
|
|
89512
88376
|
* - logging → `winston-logging` addon (level + retention)
|
|
@@ -89540,21 +88404,25 @@ var SECTION_TITLES = {
|
|
|
89540
88404
|
};
|
|
89541
88405
|
/** The keychain owner of the hub's own secrets (D797). */
|
|
89542
88406
|
var SYSTEM_SECRET_OWNER = "system";
|
|
88407
|
+
/** The form key (and the `server` section key) of the hub's human name (D861). */
|
|
88408
|
+
var SERVER_NAME_FIELD = "name";
|
|
89543
88409
|
/** Keys that map 1:1 to a given yml section — used by `updateGlobalSettings`
|
|
89544
88410
|
* to figure out which section owns each key in the incoming patch. */
|
|
89545
88411
|
var KEY_TO_SECTION = {
|
|
89546
88412
|
port: "server",
|
|
89547
88413
|
host: "server",
|
|
89548
88414
|
dataPath: "server",
|
|
88415
|
+
[SERVER_NAME_FIELD]: "server",
|
|
89549
88416
|
tokenExpiry: "auth",
|
|
89550
88417
|
accessTokenExpiry: "auth",
|
|
89551
88418
|
trustedProxies: "auth",
|
|
89552
|
-
trustedNetworks: "auth"
|
|
89553
|
-
[CLUSTER_SECRET_FIELD]: "cluster",
|
|
89554
|
-
[MESH_AUTH_MODE_FIELD]: "cluster"
|
|
88419
|
+
trustedNetworks: "auth"
|
|
89555
88420
|
};
|
|
89556
|
-
/**
|
|
89557
|
-
|
|
88421
|
+
/**
|
|
88422
|
+
* Keys a pre-D857 form may still send. They are dropped with a line, never
|
|
88423
|
+
* written: the cluster secret and the mesh auth mode no longer exist.
|
|
88424
|
+
*/
|
|
88425
|
+
var RETIRED_CLUSTER_KEYS = new Set(["clusterSecret", "meshAuth"]);
|
|
89558
88426
|
/**
|
|
89559
88427
|
* Auth keys holding a list of networks (CIDR or single address). A save with
|
|
89560
88428
|
* an entry that does not parse is REFUSED whole: dropping it would trust less
|
|
@@ -89565,7 +88433,6 @@ var CIDR_LIST_KEYS = new Set(["trustedProxies", "trustedNetworks"]);
|
|
|
89565
88433
|
var SYSTEM_CONFIG_CLUSTER_SECTION_ID = "system-config-cluster";
|
|
89566
88434
|
var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
89567
88435
|
id = "system-config";
|
|
89568
|
-
clusterSecretKeeper = null;
|
|
89569
88436
|
meshCaKeeper = null;
|
|
89570
88437
|
meshReapTimer = null;
|
|
89571
88438
|
meshGateTimers = /* @__PURE__ */ new Set();
|
|
@@ -89575,20 +88442,6 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89575
88442
|
super({});
|
|
89576
88443
|
}
|
|
89577
88444
|
async onInitialize() {
|
|
89578
|
-
this.clusterSecretKeeper = new ClusterSecretKeeper({
|
|
89579
|
-
secrets: this.systemSecrets(),
|
|
89580
|
-
readSection: async () => await this.ctx.settings?.getSection("cluster") ?? {},
|
|
89581
|
-
logger: this.ctx.logger,
|
|
89582
|
-
generateSecret: () => this.generateClusterSecret()
|
|
89583
|
-
});
|
|
89584
|
-
setProcessMeshEnforcer(async (reason) => {
|
|
89585
|
-
await this.writeMeshAuthMode("enforced");
|
|
89586
|
-
this.ctx.logger.info("Mesh authentication is now ENFORCED", { meta: { reason } });
|
|
89587
|
-
});
|
|
89588
|
-
await this.clusterSecretKeeper.start();
|
|
89589
|
-
try {
|
|
89590
|
-
await this.writeMeshAuthMode("enforced");
|
|
89591
|
-
} catch {}
|
|
89592
88445
|
this.meshCaKeeper = new MeshCaKeeper({
|
|
89593
88446
|
secrets: this.systemSecrets(),
|
|
89594
88447
|
readClusterSection: async () => await this.ctx.settings?.getSection("cluster") ?? {},
|
|
@@ -89602,14 +88455,10 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89602
88455
|
this.ctx.logger.info("Initialized — exposes yml-backed sections via getGlobalSettings");
|
|
89603
88456
|
return {
|
|
89604
88457
|
customActions: systemConfigMeshActions,
|
|
89605
|
-
actionHandlers: {
|
|
89606
|
-
mintJoinToken: async (input) => this.mintJoinToken(parseMintJoinTokenInput(input)),
|
|
89607
|
-
mintAgentUiUnlockTicket: async (input) => this.mintAgentUiUnlock(parseMintUnlockInput(input))
|
|
89608
|
-
}
|
|
88458
|
+
actionHandlers: { mintAgentUiUnlockTicket: async (input) => this.mintAgentUiUnlock(parseMintUnlockInput(input)) }
|
|
89609
88459
|
};
|
|
89610
88460
|
}
|
|
89611
88461
|
async onShutdown() {
|
|
89612
|
-
setProcessMeshEnforcer(null);
|
|
89613
88462
|
setProcessMeshCertificateRegistry(null);
|
|
89614
88463
|
setProcessMeshTlsListenerState(null);
|
|
89615
88464
|
require_agent_https.setProcessAgentHttpsNames(null);
|
|
@@ -89620,8 +88469,6 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89620
88469
|
this.meshGateTimers.clear();
|
|
89621
88470
|
this.meshCaKeeper?.stop();
|
|
89622
88471
|
this.meshCaKeeper = null;
|
|
89623
|
-
this.clusterSecretKeeper?.stop();
|
|
89624
|
-
this.clusterSecretKeeper = null;
|
|
89625
88472
|
}
|
|
89626
88473
|
/**
|
|
89627
88474
|
* The hub's record of mesh leaves (D856): declared and loaded BEFORE the TLS
|
|
@@ -89712,32 +88559,9 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89712
88559
|
onError: (err) => this.ctx.logger.error("Mesh certificate registry failed to load", { meta: { error: err instanceof Error ? err.message : String(err) } })
|
|
89713
88560
|
});
|
|
89714
88561
|
}
|
|
89715
|
-
async mintJoinToken(input) {
|
|
89716
|
-
const ca = requireProcessMeshCa();
|
|
89717
|
-
const hubUrl = input.hubUrl ?? await this.resolveHubUrl();
|
|
89718
|
-
const hubMeshAddress = input.hubMeshAddress ?? await this.resolveHubMeshAddress();
|
|
89719
|
-
const token = await mintMeshJoinToken({
|
|
89720
|
-
ca,
|
|
89721
|
-
hubUrl,
|
|
89722
|
-
hubMeshAddress,
|
|
89723
|
-
nodeId: input.nodeId,
|
|
89724
|
-
...input.ttlSec !== void 0 ? { ttlSec: input.ttlSec } : {}
|
|
89725
|
-
});
|
|
89726
|
-
return {
|
|
89727
|
-
token,
|
|
89728
|
-
exp: readJwtExp(token),
|
|
89729
|
-
hubUrl,
|
|
89730
|
-
hubMeshAddress,
|
|
89731
|
-
caFingerprint: caFingerprintCompact(ca.certPem),
|
|
89732
|
-
nodeId: input.nodeId
|
|
89733
|
-
};
|
|
89734
|
-
}
|
|
89735
88562
|
/** D821 — short-lived ticket for the agent's `:4444` unlock session. */
|
|
89736
88563
|
async mintAgentUiUnlock(input) {
|
|
89737
|
-
const
|
|
89738
|
-
if (secrets === null) throw new Error("system-config: no keychain door — cannot mint an unlock ticket");
|
|
89739
|
-
const entry = (await secrets.resolve([require_constants$8.CLUSTER_SECRET_REF]))[require_constants$8.CLUSTER_SECRET_REF];
|
|
89740
|
-
if (entry?.kind !== "value") throw new Error("system-config: cluster secret is not available — cannot mint an unlock ticket");
|
|
88564
|
+
const ca = requireProcessMeshCa();
|
|
89741
88565
|
if (input.dashboardBaseUrl !== void 0) {
|
|
89742
88566
|
const origins = await this.readAgentDashboardOrigins();
|
|
89743
88567
|
if (!isAllowedAgentDashboardReturnTo(input.dashboardBaseUrl, origins)) throw new Error("dashboardBaseUrl is not an allowed agent dashboard origin (:4444 or agentDashboardOrigins)");
|
|
@@ -89745,10 +88569,10 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89745
88569
|
if (!isKnownAgentAddress(input.dashboardBaseUrl, known, origins)) throw new Error(`dashboardBaseUrl is not an address this hub knows for "${input.nodeId}" - open the agent at its own address`);
|
|
89746
88570
|
}
|
|
89747
88571
|
const ticket = mintAgentUiUnlockTicket({
|
|
89748
|
-
|
|
88572
|
+
caKeyPem: ca.keyPem,
|
|
89749
88573
|
nodeId: input.nodeId
|
|
89750
88574
|
});
|
|
89751
|
-
const payloadJson = Buffer.from(ticket.split(".")[
|
|
88575
|
+
const payloadJson = Buffer.from(ticket.split(".")[1] ?? "", "base64url").toString("utf8");
|
|
89752
88576
|
const exp = JSON.parse(payloadJson).exp ?? 0;
|
|
89753
88577
|
const dashboardUrl = input.dashboardBaseUrl === void 0 ? void 0 : (() => {
|
|
89754
88578
|
const u = new URL(input.dashboardBaseUrl);
|
|
@@ -89769,24 +88593,6 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89769
88593
|
return [];
|
|
89770
88594
|
}
|
|
89771
88595
|
}
|
|
89772
|
-
async resolveHubUrl() {
|
|
89773
|
-
try {
|
|
89774
|
-
const book = await this.ctx.api?.localNetwork?.getAddresses?.query({ scheme: "https" });
|
|
89775
|
-
const url = book?.roles?.publicEndpoint?.resolved ?? book?.roles?.internal?.resolved ?? null;
|
|
89776
|
-
if (typeof url === "string" && url.length > 0) return url;
|
|
89777
|
-
} catch {}
|
|
89778
|
-
const host = (await this.ctx.settings?.getSection("server"))?.["host"];
|
|
89779
|
-
const port = (await this.ctx.settings?.getSection("server"))?.["port"];
|
|
89780
|
-
return `https://${typeof host === "string" && host.length > 0 && host !== "0.0.0.0" ? host : "127.0.0.1"}:${typeof port === "number" ? port : Number(port) || 4443}`;
|
|
89781
|
-
}
|
|
89782
|
-
async resolveHubMeshAddress() {
|
|
89783
|
-
try {
|
|
89784
|
-
const base = (await this.ctx.api?.localNetwork?.getAddresses?.query({}))?.roles?.internal?.resolved;
|
|
89785
|
-
if (typeof base === "string" && base.length > 0) return `${new URL(base).hostname}:${require_constants$8.DEFAULT_HUB_TLS_TCP_PORT}`;
|
|
89786
|
-
} catch {}
|
|
89787
|
-
const host = (await this.ctx.settings?.getSection("server"))?.["host"];
|
|
89788
|
-
return `${typeof host === "string" && host.length > 0 && host !== "0.0.0.0" ? host : "127.0.0.1"}:${require_constants$8.DEFAULT_HUB_TLS_TCP_PORT}`;
|
|
89789
|
-
}
|
|
89790
88596
|
/** The keychain handle for owner `system`; `null` where there is no door. */
|
|
89791
88597
|
systemSecrets() {
|
|
89792
88598
|
const forOwner = this.ctx.secrets?.forOwner ?? null;
|
|
@@ -89797,14 +88603,22 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89797
88603
|
{
|
|
89798
88604
|
id: "system-config-server",
|
|
89799
88605
|
title: SECTION_TITLES["server"],
|
|
89800
|
-
description: "
|
|
88606
|
+
description: "The name of this server, and its connection settings (read-only, loaded from config.yaml at bootstrap).",
|
|
89801
88607
|
columns: 2,
|
|
89802
88608
|
fields: [
|
|
88609
|
+
{
|
|
88610
|
+
type: "text",
|
|
88611
|
+
key: SERVER_NAME_FIELD,
|
|
88612
|
+
label: "Server name",
|
|
88613
|
+
description: `Shown in the admin UI and on the apps' sign-in screen (1 to 48 characters). Leave empty to use this machine's hostname.`,
|
|
88614
|
+
placeholder: hostnameWithoutDomain(),
|
|
88615
|
+
span: 2
|
|
88616
|
+
},
|
|
89803
88617
|
{
|
|
89804
88618
|
type: "info",
|
|
89805
88619
|
key: "server-restart-note",
|
|
89806
88620
|
label: "Restart required",
|
|
89807
|
-
content: "
|
|
88621
|
+
content: "Port, host and data path are read-only. Change them in config.yaml and restart.",
|
|
89808
88622
|
variant: "warning"
|
|
89809
88623
|
},
|
|
89810
88624
|
{
|
|
@@ -89879,14 +88693,9 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89879
88693
|
{
|
|
89880
88694
|
id: SYSTEM_CONFIG_CLUSTER_SECTION_ID,
|
|
89881
88695
|
title: SECTION_TITLES["cluster"],
|
|
89882
|
-
description: "Agents
|
|
88696
|
+
description: "Agents join this hub by pairing (System → Cluster → Agents): the hub signs a certificate for the agent after the operator confirms the same 6-digit code on the hub and in the agent's own page. There is no shared cluster secret.",
|
|
89883
88697
|
columns: 1,
|
|
89884
|
-
fields: [
|
|
89885
|
-
type: "password",
|
|
89886
|
-
key: CLUSTER_SECRET_FIELD,
|
|
89887
|
-
label: "Cluster secret",
|
|
89888
|
-
description: "Reveal and copy into each agent to pair. Saving a new value rotates it for every agent."
|
|
89889
|
-
}]
|
|
88698
|
+
fields: []
|
|
89890
88699
|
}
|
|
89891
88700
|
] };
|
|
89892
88701
|
}
|
|
@@ -89909,13 +88718,32 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89909
88718
|
}
|
|
89910
88719
|
/**
|
|
89911
88720
|
* The admin UI / `addonSettings` cap prefer {@link BaseAddon.updateGlobalSettingsAsOperator}.
|
|
89912
|
-
* That BaseAddon path writes the generic addon store and never reaches
|
|
89913
|
-
*
|
|
89914
|
-
*
|
|
88721
|
+
* That BaseAddon path writes the generic addon store and never reaches the
|
|
88722
|
+
* yml sections. Route the operator write through the same section-aware path
|
|
88723
|
+
* as {@link updateGlobalSettings}.
|
|
89915
88724
|
*/
|
|
89916
88725
|
async updateGlobalSettingsAsOperator(patch, _nodeId) {
|
|
89917
88726
|
await this.updateGlobalSettings(patch);
|
|
89918
88727
|
}
|
|
88728
|
+
/**
|
|
88729
|
+
* The value to store for a `name` in a save, or `undefined` for "leave the row
|
|
88730
|
+
* alone". The whole form posts every field, so an empty box on a hub that was
|
|
88731
|
+
* never named is the NORMAL case and must write nothing (D861: a seed never
|
|
88732
|
+
* overwrites); an empty box over a stored name is the operator clearing it,
|
|
88733
|
+
* which stores `''` (readers treat it as unset). Anything else must be a valid
|
|
88734
|
+
* name — refused whole, like the network lists.
|
|
88735
|
+
*/
|
|
88736
|
+
async normalizeServerName(value) {
|
|
88737
|
+
if (value === void 0 || value === null) return void 0;
|
|
88738
|
+
if (typeof value !== "string") throw new Error("The server name must be text");
|
|
88739
|
+
if (value.trim() === "") {
|
|
88740
|
+
const current = (await this.ctx.settings.getSection("server"))[SERVER_NAME_FIELD];
|
|
88741
|
+
return typeof current === "string" && current !== "" ? "" : void 0;
|
|
88742
|
+
}
|
|
88743
|
+
const parsed = require_dist.ServerNameSchema.safeParse(value);
|
|
88744
|
+
if (!parsed.success) throw new Error(parsed.error.issues[0]?.message ?? "The server name is not valid");
|
|
88745
|
+
return parsed.data;
|
|
88746
|
+
}
|
|
89919
88747
|
async updateGlobalSettings(patch) {
|
|
89920
88748
|
if (!this.ctx.settings) throw new Error("system-config: ctx.settings not available — cannot write sections");
|
|
89921
88749
|
const perSection = /* @__PURE__ */ new Map();
|
|
@@ -89928,11 +88756,23 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89928
88756
|
this.ctx.logger.warn("cluster.agentDashboardOrigins is no longer writable from settings — ignoring this patch");
|
|
89929
88757
|
continue;
|
|
89930
88758
|
}
|
|
88759
|
+
if (RETIRED_CLUSTER_KEYS.has(key)) {
|
|
88760
|
+
this.ctx.logger.warn(`cluster.${key} is retired (D857) — agents are paired by certificate; ignoring this patch`);
|
|
88761
|
+
continue;
|
|
88762
|
+
}
|
|
89931
88763
|
const section = KEY_TO_SECTION[key];
|
|
89932
88764
|
if (section === void 0) {
|
|
89933
88765
|
this.ctx.logger.warn("update ignored unknown key (not mapped to any section)", { meta: { key } });
|
|
89934
88766
|
continue;
|
|
89935
88767
|
}
|
|
88768
|
+
if (key === SERVER_NAME_FIELD) {
|
|
88769
|
+
const name = await this.normalizeServerName(value);
|
|
88770
|
+
if (name === void 0) continue;
|
|
88771
|
+
const bucket = perSection.get("server") ?? {};
|
|
88772
|
+
bucket[key] = name;
|
|
88773
|
+
perSection.set("server", bucket);
|
|
88774
|
+
continue;
|
|
88775
|
+
}
|
|
89936
88776
|
if (section === "server") {
|
|
89937
88777
|
this.ctx.logger.warn("update ignored read-only server-section key", { meta: { key } });
|
|
89938
88778
|
continue;
|
|
@@ -89949,10 +88789,6 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89949
88789
|
bucket[key] = value;
|
|
89950
88790
|
}
|
|
89951
88791
|
for (const [section, sectionPatch] of perSection) {
|
|
89952
|
-
if (section === "cluster") {
|
|
89953
|
-
await this.writeClusterSection(sectionPatch);
|
|
89954
|
-
continue;
|
|
89955
|
-
}
|
|
89956
88792
|
await this.ctx.settings.setSection(section, sectionPatch);
|
|
89957
88793
|
this.ctx.logger.info("Wrote keys to section", { meta: {
|
|
89958
88794
|
section,
|
|
@@ -89960,78 +88796,10 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
89960
88796
|
} });
|
|
89961
88797
|
}
|
|
89962
88798
|
}
|
|
89963
|
-
/**
|
|
89964
|
-
* The cluster secret's save path: the value goes to the keychain (owner
|
|
89965
|
-
* `system`), the row gets the marker; `''` / a view keeps. `$secretClear` is
|
|
89966
|
-
* REFUSED: the secret is mandatory (D802). A value the keychain cannot store
|
|
89967
|
-
* is REFUSED — never written inline (D787, P5). Mesh auth mode is always
|
|
89968
|
-
* enforced (D821) — a legacy `meshAuth` in the patch is ignored.
|
|
89969
|
-
*/
|
|
89970
|
-
async writeClusterSection(patch) {
|
|
89971
|
-
const { [MESH_AUTH_MODE_FIELD]: _legacyMode, ...secretPatch } = patch;
|
|
89972
|
-
await this.writeMeshAuthMode("enforced");
|
|
89973
|
-
if (Object.keys(secretPatch).length === 0) return;
|
|
89974
|
-
if (require_dist.isSecretClear(secretPatch["clusterSecret"])) throw new Error("The cluster secret is mandatory and cannot be cleared — save a new value to rotate it");
|
|
89975
|
-
await this.storeClusterSecret(secretPatch);
|
|
89976
|
-
this.ctx.logger.info("Cluster secret updated");
|
|
89977
|
-
await this.clusterSecretKeeper?.reload();
|
|
89978
|
-
}
|
|
89979
|
-
/** Persist + publish mesh auth mode (always `enforced` after D821). */
|
|
89980
|
-
async writeMeshAuthMode(mode) {
|
|
89981
|
-
await this.ctx.settings.setSection("cluster", { [MESH_AUTH_MODE_FIELD]: mode });
|
|
89982
|
-
setProcessMeshAuthMode(mode);
|
|
89983
|
-
}
|
|
89984
|
-
/**
|
|
89985
|
-
* First boot, or a keychain reset that cleared the marker (D802): a fresh
|
|
89986
|
-
* random secret, stored like an operator save. Mesh auth stays enforced
|
|
89987
|
-
* (D821) — every agent must present the secret; there is no transition window.
|
|
89988
|
-
*/
|
|
89989
|
-
async generateClusterSecret() {
|
|
89990
|
-
const settings = this.ctx.settings;
|
|
89991
|
-
const secrets = this.systemSecrets();
|
|
89992
|
-
if (!settings || secrets === null) throw new Error("system-config: no keychain door — the cluster secret cannot be generated");
|
|
89993
|
-
const existing = (await secrets.resolve([require_constants$8.CLUSTER_SECRET_REF]))[require_constants$8.CLUSTER_SECRET_REF];
|
|
89994
|
-
if (existing?.kind === "value") {
|
|
89995
|
-
await settings.setSection("cluster", { [CLUSTER_SECRET_FIELD]: require_dist.makeSecretMarker(require_constants$8.CLUSTER_SECRET_REF) });
|
|
89996
|
-
this.ctx.logger.warn("The cluster secret row was empty but the keychain holds a value — re-adopted it");
|
|
89997
|
-
return;
|
|
89998
|
-
}
|
|
89999
|
-
if (existing?.kind !== "missing") throw new Error(`the keychain cannot answer for the cluster secret (${existing?.kind ?? "no answer"})`);
|
|
90000
|
-
const value = (0, node_crypto.randomBytes)(GENERATED_SECRET_BYTES).toString("base64url");
|
|
90001
|
-
await this.storeClusterSecret({ [CLUSTER_SECRET_FIELD]: value });
|
|
90002
|
-
await settings.setSection("cluster", { [MESH_AUTH_MODE_FIELD]: "enforced" });
|
|
90003
|
-
setProcessMeshAuthMode("enforced");
|
|
90004
|
-
}
|
|
90005
|
-
async storeClusterSecret(patch) {
|
|
90006
|
-
const settings = this.ctx.settings;
|
|
90007
|
-
if (!settings) throw new Error("system-config: ctx.settings not available");
|
|
90008
|
-
const secrets = this.systemSecrets();
|
|
90009
|
-
if (secrets === null) throw new Error("system-config: no keychain door — the cluster secret cannot be stored");
|
|
90010
|
-
const stored = await settings.getSection("cluster");
|
|
90011
|
-
const result = await require_dist.transformSecretWrite({
|
|
90012
|
-
tree: require_dist.secretTreeFromSchema(this.buildGlobalSchema()),
|
|
90013
|
-
secrets,
|
|
90014
|
-
patch,
|
|
90015
|
-
stored,
|
|
90016
|
-
operatorWrite: true
|
|
90017
|
-
});
|
|
90018
|
-
if (Object.keys(result.patch).length > 0) await settings.setSection("cluster", result.patch);
|
|
90019
|
-
const { orphaned } = await result.afterWrite();
|
|
90020
|
-
if (orphaned.length > 0) this.ctx.logger.warn("an old cluster secret value could not be deleted from the keychain", { meta: { refs: orphaned } });
|
|
90021
|
-
}
|
|
90022
88799
|
};
|
|
90023
|
-
|
|
90024
|
-
|
|
90025
|
-
|
|
90026
|
-
if (typeof nodeId !== "string" || nodeId.length === 0) throw new Error("system-config: mintJoinToken requires { nodeId } - the node the token is for");
|
|
90027
|
-
const out = { nodeId };
|
|
90028
|
-
const hubUrl = Reflect.get(input, "hubUrl");
|
|
90029
|
-
const hubMeshAddress = Reflect.get(input, "hubMeshAddress");
|
|
90030
|
-
const ttlSec = Reflect.get(input, "ttlSec");
|
|
90031
|
-
if (typeof hubUrl === "string") out.hubUrl = hubUrl;
|
|
90032
|
-
if (typeof hubMeshAddress === "string") out.hubMeshAddress = hubMeshAddress;
|
|
90033
|
-
if (typeof ttlSec === "number") out.ttlSec = ttlSec;
|
|
90034
|
-
return out;
|
|
88800
|
+
/** This machine's hostname without its domain: what an unnamed hub is called. */
|
|
88801
|
+
function hostnameWithoutDomain() {
|
|
88802
|
+
return require_dist.shortHostname(node_os.default.hostname());
|
|
90035
88803
|
}
|
|
90036
88804
|
function parseMintUnlockInput(input) {
|
|
90037
88805
|
if (input === null || typeof input !== "object") throw new Error("system-config: mintAgentUiUnlockTicket requires { nodeId }");
|
|
@@ -90043,19 +88811,8 @@ function parseMintUnlockInput(input) {
|
|
|
90043
88811
|
...typeof dashboardBaseUrl === "string" ? { dashboardBaseUrl } : {}
|
|
90044
88812
|
};
|
|
90045
88813
|
}
|
|
90046
|
-
/** Read `exp` from an unencrypted JWT payload (no verify — already minted here). */
|
|
90047
|
-
function readJwtExp(token) {
|
|
90048
|
-
const parts = token.split(".");
|
|
90049
|
-
if (parts.length < 2 || parts[1] === void 0) return 0;
|
|
90050
|
-
const json = Buffer.from(parts[1], "base64url").toString("utf8");
|
|
90051
|
-
const payload = JSON.parse(json);
|
|
90052
|
-
if (payload === null || typeof payload !== "object") return 0;
|
|
90053
|
-
const exp = Reflect.get(payload, "exp");
|
|
90054
|
-
return typeof exp === "number" ? exp : 0;
|
|
90055
|
-
}
|
|
90056
88814
|
//#endregion
|
|
90057
88815
|
exports.AGENT_DASHBOARD_ORIGINS_FIELD = AGENT_DASHBOARD_ORIGINS_FIELD;
|
|
90058
|
-
exports.AGENT_UI_UNLOCK_DOMAIN = AGENT_UI_UNLOCK_DOMAIN;
|
|
90059
88816
|
exports.AGENT_UI_UNLOCK_TTL_MS = AGENT_UI_UNLOCK_TTL_MS;
|
|
90060
88817
|
exports.AGENT_UI_UNLOCK_TYP = AGENT_UI_UNLOCK_TYP;
|
|
90061
88818
|
exports.AGENT_UI_UNLOCK_USE = AGENT_UI_UNLOCK_USE;
|
|
@@ -90063,8 +88820,6 @@ exports.AGENT_UI_UNLOCK_VERSION = AGENT_UI_UNLOCK_VERSION;
|
|
|
90063
88820
|
exports.AgentPairing = AgentPairing;
|
|
90064
88821
|
exports.Errors = Errors;
|
|
90065
88822
|
exports.HubPairing = HubPairing;
|
|
90066
|
-
exports.JoinTokenJtiStore = JoinTokenJtiStore;
|
|
90067
|
-
exports.MESH_AUTH_MODE_FIELD = MESH_AUTH_MODE_FIELD;
|
|
90068
88823
|
exports.MESH_NODE_CERTIFICATES_COLLECTION = MESH_NODE_CERTIFICATES_COLLECTION;
|
|
90069
88824
|
exports.MESH_NODE_CERTIFICATES_COLUMNS = MESH_NODE_CERTIFICATES_COLUMNS;
|
|
90070
88825
|
exports.MESH_TLS_PORT_HELLO_FIELD = MESH_TLS_PORT_HELLO_FIELD;
|
|
@@ -90085,7 +88840,6 @@ exports.ServiceBroker = ServiceBroker;
|
|
|
90085
88840
|
exports.SystemConfigAddon = SystemConfigAddon;
|
|
90086
88841
|
exports.default = SystemConfigAddon;
|
|
90087
88842
|
exports.TlsTcpTransporter = TlsTcpTransporter;
|
|
90088
|
-
exports.Transporters = Transporters;
|
|
90089
88843
|
exports.UnlockTicketJtiStore = UnlockTicketJtiStore;
|
|
90090
88844
|
exports.caFingerprint = caFingerprint;
|
|
90091
88845
|
exports.caFingerprintCompact = caFingerprintCompact;
|
|
@@ -90097,12 +88851,9 @@ exports.describeCsr = describeCsr;
|
|
|
90097
88851
|
exports.describeMeshLeaf = describeMeshLeaf;
|
|
90098
88852
|
exports.dropProcessPeer = dropProcessPeer;
|
|
90099
88853
|
exports.emitProcessNodeRegistered = emitProcessNodeRegistered;
|
|
90100
|
-
exports.enrollMeshNode = enrollMeshNode;
|
|
90101
88854
|
exports.exportMeshPrivateKeyPem = exportMeshPrivateKeyPem;
|
|
90102
88855
|
exports.generateMeshCa = generateMeshCa;
|
|
90103
88856
|
exports.generateMeshKeyPair = generateMeshKeyPair;
|
|
90104
|
-
exports.getProcessMeshAuthMode = getProcessMeshAuthMode;
|
|
90105
|
-
exports.getProcessMeshAuthStatus = getProcessMeshAuthStatus;
|
|
90106
88857
|
exports.getProcessMeshCaState = getProcessMeshCaState;
|
|
90107
88858
|
exports.getProcessMeshCertificateRegistry = getProcessMeshCertificateRegistry;
|
|
90108
88859
|
exports.getProcessMeshTlsListenerState = getProcessMeshTlsListenerState;
|
|
@@ -90110,7 +88861,6 @@ exports.getProcessNodeMeshTransport = getProcessNodeMeshTransport;
|
|
|
90110
88861
|
exports.getProcessPeerLeaf = getProcessPeerLeaf;
|
|
90111
88862
|
exports.hubHostFromMeshAddress = hubHostFromMeshAddress;
|
|
90112
88863
|
exports.isAllowedAgentDashboardReturnTo = isAllowedAgentDashboardReturnTo;
|
|
90113
|
-
exports.isMeshAuthMode = isMeshAuthMode;
|
|
90114
88864
|
exports.isProcessVerifiedMeshPeer = isProcessVerifiedMeshPeer;
|
|
90115
88865
|
exports.isValidAgentNodeId = isValidAgentNodeId;
|
|
90116
88866
|
exports.issueMeshLeafForNode = issueMeshLeafForNode;
|
|
@@ -90118,31 +88868,21 @@ exports.issueMeshLeafFromCsr = issueMeshLeafFromCsr;
|
|
|
90118
88868
|
exports.keyFingerprintShort = keyFingerprintShort;
|
|
90119
88869
|
exports.loadMeshCa = loadMeshCa;
|
|
90120
88870
|
exports.mintAgentUiUnlockTicket = mintAgentUiUnlockTicket;
|
|
90121
|
-
exports.mintAgentUiUnlockTicketEs256 = mintAgentUiUnlockTicketEs256;
|
|
90122
|
-
exports.mintMeshJoinToken = mintMeshJoinToken;
|
|
90123
88871
|
exports.normalizeIp = normalizeIp;
|
|
90124
88872
|
exports.onProcessNodeRegistered = onProcessNodeRegistered;
|
|
90125
88873
|
exports.openMeshTlsWhenRevocationsLoaded = openMeshTlsWhenRevocationsLoaded;
|
|
90126
88874
|
exports.parseAgentDashboardOrigins = parseAgentDashboardOrigins;
|
|
90127
88875
|
exports.parseCidrList = parseCidrList;
|
|
90128
|
-
exports.parseMeshAuthMode = parseMeshAuthMode;
|
|
90129
|
-
exports.processJoinTokenJtiStore = processJoinTokenJtiStore;
|
|
90130
88876
|
exports.processMeshCrl = processMeshCrl;
|
|
90131
88877
|
exports.readCidrSetting = readCidrSetting;
|
|
90132
88878
|
exports.renewMeshCertificate = renewMeshCertificate;
|
|
90133
|
-
exports.requestProcessMeshEnforcement = requestProcessMeshEnforcement;
|
|
90134
88879
|
exports.requireProcessMeshCa = requireProcessMeshCa;
|
|
90135
88880
|
exports.revokeMeshCertificate = revokeMeshCertificate;
|
|
90136
|
-
exports.setProcessMeshAuthMode = setProcessMeshAuthMode;
|
|
90137
|
-
exports.setProcessMeshAuthStatusSource = setProcessMeshAuthStatusSource;
|
|
90138
88881
|
exports.setProcessMeshCertificateRegistry = setProcessMeshCertificateRegistry;
|
|
90139
|
-
exports.setProcessMeshEnforcer = setProcessMeshEnforcer;
|
|
90140
88882
|
exports.setProcessMeshPeerTransportLookup = setProcessMeshPeerTransportLookup;
|
|
90141
88883
|
exports.setProcessMeshTlsEnabler = setProcessMeshTlsEnabler;
|
|
90142
88884
|
exports.setProcessMeshTlsListenerState = setProcessMeshTlsListenerState;
|
|
90143
88885
|
exports.signPairingProof = signPairingProof;
|
|
90144
88886
|
exports.systemConfigMeshActions = systemConfigMeshActions;
|
|
90145
88887
|
exports.verifyAgentUiUnlockTicket = verifyAgentUiUnlockTicket;
|
|
90146
|
-
exports.verifyAgentUiUnlockTicketEs256 = verifyAgentUiUnlockTicketEs256;
|
|
90147
|
-
exports.verifyMeshJoinToken = verifyMeshJoinToken;
|
|
90148
88888
|
exports.verifyPairingProof = verifyPairingProof;
|