@camstack/system 1.2.394 → 1.2.396
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.
|
@@ -7,6 +7,8 @@ export declare class SystemConfigAddon extends BaseAddon {
|
|
|
7
7
|
readonly id = "system-config";
|
|
8
8
|
private clusterSecretKeeper;
|
|
9
9
|
private meshCaKeeper;
|
|
10
|
+
/** One warn per process when a retired cutover key is posted with a cluster save. */
|
|
11
|
+
private retiredClusterCutoverPatchWarned;
|
|
10
12
|
constructor();
|
|
11
13
|
protected onInitialize(): Promise<AddonInitResult<typeof systemConfigMeshActions>>;
|
|
12
14
|
protected onShutdown(): Promise<void>;
|
|
@@ -30,7 +32,7 @@ export declare class SystemConfigAddon extends BaseAddon {
|
|
|
30
32
|
/**
|
|
31
33
|
* The admin UI / `addonSettings` cap prefer {@link BaseAddon.updateGlobalSettingsAsOperator}.
|
|
32
34
|
* That BaseAddon path writes the generic addon store and never reaches
|
|
33
|
-
* {@link writeClusterSection}
|
|
35
|
+
* {@link writeClusterSection}. Route the operator
|
|
34
36
|
* write through the same section-aware path as {@link updateGlobalSettings}.
|
|
35
37
|
*/
|
|
36
38
|
override updateGlobalSettingsAsOperator(patch: Record<string, unknown>, _nodeId?: string): Promise<void>;
|
|
@@ -43,12 +45,8 @@ export declare class SystemConfigAddon extends BaseAddon {
|
|
|
43
45
|
* enforced (D821) — a legacy `meshAuth` in the patch is ignored.
|
|
44
46
|
*/
|
|
45
47
|
private writeClusterSection;
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
* connects in clear (or the TLS listener is not up); the refusal names them.
|
|
49
|
-
* Persist, then apply — an `on` save always passes.
|
|
50
|
-
*/
|
|
51
|
-
private writeMeshClearPort;
|
|
48
|
+
/** Cutover keys were removed from the Cluster form; ignore stray posts from stale clients. */
|
|
49
|
+
private warnRetiredClusterCutoverPatch;
|
|
52
50
|
/** Persist + publish mesh auth mode (always `enforced` after D821). */
|
|
53
51
|
private writeMeshAuthMode;
|
|
54
52
|
/**
|
|
@@ -88102,6 +88102,8 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
88102
88102
|
id = "system-config";
|
|
88103
88103
|
clusterSecretKeeper = null;
|
|
88104
88104
|
meshCaKeeper = null;
|
|
88105
|
+
/** One warn per process when a retired cutover key is posted with a cluster save. */
|
|
88106
|
+
retiredClusterCutoverPatchWarned = false;
|
|
88105
88107
|
constructor() {
|
|
88106
88108
|
super({});
|
|
88107
88109
|
}
|
|
@@ -88337,52 +88339,18 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
88337
88339
|
title: SECTION_TITLES["cluster"],
|
|
88338
88340
|
description: "Agents joining this hub. Every agent proves the cluster secret when it connects (challenge–response; the secret never crosses the network).",
|
|
88339
88341
|
columns: 1,
|
|
88340
|
-
fields: [
|
|
88341
|
-
|
|
88342
|
-
|
|
88343
|
-
|
|
88344
|
-
|
|
88345
|
-
|
|
88346
|
-
|
|
88347
|
-
|
|
88348
|
-
|
|
88349
|
-
|
|
88350
|
-
|
|
88351
|
-
|
|
88352
|
-
default: "on",
|
|
88353
|
-
options: [{
|
|
88354
|
-
value: "on",
|
|
88355
|
-
label: "On — accept clear agents"
|
|
88356
|
-
}, {
|
|
88357
|
-
value: "off",
|
|
88358
|
-
label: "Off — mutual TLS only"
|
|
88359
|
-
}]
|
|
88360
|
-
},
|
|
88361
|
-
{
|
|
88362
|
-
type: "info",
|
|
88363
|
-
key: "meshAuthStatus",
|
|
88364
|
-
label: "Mesh authentication",
|
|
88365
|
-
content: describeMeshStatus(getProcessMeshAuthStatus()),
|
|
88366
|
-
variant: "info"
|
|
88367
|
-
},
|
|
88368
|
-
{
|
|
88369
|
-
type: "text",
|
|
88370
|
-
key: AGENT_DASHBOARD_ORIGINS_FIELD,
|
|
88371
|
-
label: "Agent dashboard origins (NPM)",
|
|
88372
|
-
description: "Extra origins allowed for Continue-with-hub unlock redirects (comma-separated), e.g. https://agent.example.com. LAN agents on :4444 are always allowed."
|
|
88373
|
-
},
|
|
88374
|
-
{
|
|
88375
|
-
type: "addon-action-button",
|
|
88376
|
-
key: "mintJoinTokenAction",
|
|
88377
|
-
label: "Add agent",
|
|
88378
|
-
description: "Mint a single-use join token (≤ 1 hour). Paste it into the agent setup instead of copying the cluster secret. The token is shown once in the result.",
|
|
88379
|
-
addonId: "system-config",
|
|
88380
|
-
action: "mintJoinToken",
|
|
88381
|
-
buttonLabel: "Add agent",
|
|
88382
|
-
variant: "primary",
|
|
88383
|
-
successMessage: "Join token (copy now): {token}"
|
|
88384
|
-
}
|
|
88385
|
-
]
|
|
88342
|
+
fields: [{
|
|
88343
|
+
type: "password",
|
|
88344
|
+
key: CLUSTER_SECRET_FIELD,
|
|
88345
|
+
label: "Cluster secret",
|
|
88346
|
+
description: "Mandatory — generated by the hub at first boot and stored in the keychain. To pair an agent: Reveal and copy it here, then enter it in the agent (its status page, or the desktop setup window). Saving a new value rotates it: every agent must then be given the new one."
|
|
88347
|
+
}, {
|
|
88348
|
+
type: "info",
|
|
88349
|
+
key: "meshAuthStatus",
|
|
88350
|
+
label: "Mesh authentication",
|
|
88351
|
+
content: describeMeshStatus(getProcessMeshAuthStatus()),
|
|
88352
|
+
variant: "info"
|
|
88353
|
+
}]
|
|
88386
88354
|
}
|
|
88387
88355
|
] };
|
|
88388
88356
|
}
|
|
@@ -88406,7 +88374,7 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
88406
88374
|
/**
|
|
88407
88375
|
* The admin UI / `addonSettings` cap prefer {@link BaseAddon.updateGlobalSettingsAsOperator}.
|
|
88408
88376
|
* That BaseAddon path writes the generic addon store and never reaches
|
|
88409
|
-
* {@link writeClusterSection}
|
|
88377
|
+
* {@link writeClusterSection}. Route the operator
|
|
88410
88378
|
* write through the same section-aware path as {@link updateGlobalSettings}.
|
|
88411
88379
|
*/
|
|
88412
88380
|
async updateGlobalSettingsAsOperator(patch, _nodeId) {
|
|
@@ -88457,8 +88425,7 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
88457
88425
|
*/
|
|
88458
88426
|
async writeClusterSection(patch) {
|
|
88459
88427
|
const { [MESH_AUTH_MODE_FIELD]: _legacyMode, [MESH_CLEAR_PORT_FIELD]: clearPort, [AGENT_DASHBOARD_ORIGINS_FIELD]: dashboardOrigins, ...secretPatch } = patch;
|
|
88460
|
-
if (clearPort !== void 0)
|
|
88461
|
-
if (dashboardOrigins !== void 0) await this.ctx.settings.setSection("cluster", { [AGENT_DASHBOARD_ORIGINS_FIELD]: typeof dashboardOrigins === "string" ? dashboardOrigins : "" });
|
|
88428
|
+
if (clearPort !== void 0 || dashboardOrigins !== void 0) this.warnRetiredClusterCutoverPatch(clearPort !== void 0, dashboardOrigins !== void 0);
|
|
88462
88429
|
await this.writeMeshAuthMode("enforced");
|
|
88463
88430
|
if (Object.keys(secretPatch).length === 0) return;
|
|
88464
88431
|
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");
|
|
@@ -88466,26 +88433,14 @@ var SystemConfigAddon = class extends require_dist.BaseAddon {
|
|
|
88466
88433
|
this.ctx.logger.info("Cluster secret updated");
|
|
88467
88434
|
await this.clusterSecretKeeper?.reload();
|
|
88468
88435
|
}
|
|
88469
|
-
/**
|
|
88470
|
-
|
|
88471
|
-
|
|
88472
|
-
|
|
88473
|
-
|
|
88474
|
-
|
|
88475
|
-
|
|
88476
|
-
|
|
88477
|
-
if (parseMeshClearPortMode(stored) === value) return;
|
|
88478
|
-
const decision = checkProcessMeshClearPort(value);
|
|
88479
|
-
if (!decision.allowed) {
|
|
88480
|
-
this.ctx.logger.warn("mesh clear port switch-off refused", { meta: {
|
|
88481
|
-
blocking: decision.blocking,
|
|
88482
|
-
error: decision.error
|
|
88483
|
-
} });
|
|
88484
|
-
throw new Error(decision.error);
|
|
88485
|
-
}
|
|
88486
|
-
await this.ctx.settings.setSection("cluster", { [MESH_CLEAR_PORT_FIELD]: value });
|
|
88487
|
-
await applyProcessMeshClearPort(value);
|
|
88488
|
-
this.ctx.logger.info("Mesh clear port switched", { meta: { mode: value } });
|
|
88436
|
+
/** Cutover keys were removed from the Cluster form; ignore stray posts from stale clients. */
|
|
88437
|
+
warnRetiredClusterCutoverPatch(hadMeshClearPort, hadAgentDashboardOrigins) {
|
|
88438
|
+
if (this.retiredClusterCutoverPatchWarned) return;
|
|
88439
|
+
this.retiredClusterCutoverPatchWarned = true;
|
|
88440
|
+
this.ctx.logger.warn("cluster save ignored retired cutover field(s) — use Pipeline → Cluster / Nodes", { meta: {
|
|
88441
|
+
meshClearPort: hadMeshClearPort,
|
|
88442
|
+
agentDashboardOrigins: hadAgentDashboardOrigins
|
|
88443
|
+
} });
|
|
88489
88444
|
}
|
|
88490
88445
|
/** Persist + publish mesh auth mode (always `enforced` after D821). */
|
|
88491
88446
|
async writeMeshAuthMode(mode) {
|
|
@@ -88092,6 +88092,8 @@ var SystemConfigAddon = class extends BaseAddon {
|
|
|
88092
88092
|
id = "system-config";
|
|
88093
88093
|
clusterSecretKeeper = null;
|
|
88094
88094
|
meshCaKeeper = null;
|
|
88095
|
+
/** One warn per process when a retired cutover key is posted with a cluster save. */
|
|
88096
|
+
retiredClusterCutoverPatchWarned = false;
|
|
88095
88097
|
constructor() {
|
|
88096
88098
|
super({});
|
|
88097
88099
|
}
|
|
@@ -88327,52 +88329,18 @@ var SystemConfigAddon = class extends BaseAddon {
|
|
|
88327
88329
|
title: SECTION_TITLES["cluster"],
|
|
88328
88330
|
description: "Agents joining this hub. Every agent proves the cluster secret when it connects (challenge–response; the secret never crosses the network).",
|
|
88329
88331
|
columns: 1,
|
|
88330
|
-
fields: [
|
|
88331
|
-
|
|
88332
|
-
|
|
88333
|
-
|
|
88334
|
-
|
|
88335
|
-
|
|
88336
|
-
|
|
88337
|
-
|
|
88338
|
-
|
|
88339
|
-
|
|
88340
|
-
|
|
88341
|
-
|
|
88342
|
-
default: "on",
|
|
88343
|
-
options: [{
|
|
88344
|
-
value: "on",
|
|
88345
|
-
label: "On — accept clear agents"
|
|
88346
|
-
}, {
|
|
88347
|
-
value: "off",
|
|
88348
|
-
label: "Off — mutual TLS only"
|
|
88349
|
-
}]
|
|
88350
|
-
},
|
|
88351
|
-
{
|
|
88352
|
-
type: "info",
|
|
88353
|
-
key: "meshAuthStatus",
|
|
88354
|
-
label: "Mesh authentication",
|
|
88355
|
-
content: describeMeshStatus(getProcessMeshAuthStatus()),
|
|
88356
|
-
variant: "info"
|
|
88357
|
-
},
|
|
88358
|
-
{
|
|
88359
|
-
type: "text",
|
|
88360
|
-
key: AGENT_DASHBOARD_ORIGINS_FIELD,
|
|
88361
|
-
label: "Agent dashboard origins (NPM)",
|
|
88362
|
-
description: "Extra origins allowed for Continue-with-hub unlock redirects (comma-separated), e.g. https://agent.example.com. LAN agents on :4444 are always allowed."
|
|
88363
|
-
},
|
|
88364
|
-
{
|
|
88365
|
-
type: "addon-action-button",
|
|
88366
|
-
key: "mintJoinTokenAction",
|
|
88367
|
-
label: "Add agent",
|
|
88368
|
-
description: "Mint a single-use join token (≤ 1 hour). Paste it into the agent setup instead of copying the cluster secret. The token is shown once in the result.",
|
|
88369
|
-
addonId: "system-config",
|
|
88370
|
-
action: "mintJoinToken",
|
|
88371
|
-
buttonLabel: "Add agent",
|
|
88372
|
-
variant: "primary",
|
|
88373
|
-
successMessage: "Join token (copy now): {token}"
|
|
88374
|
-
}
|
|
88375
|
-
]
|
|
88332
|
+
fields: [{
|
|
88333
|
+
type: "password",
|
|
88334
|
+
key: CLUSTER_SECRET_FIELD,
|
|
88335
|
+
label: "Cluster secret",
|
|
88336
|
+
description: "Mandatory — generated by the hub at first boot and stored in the keychain. To pair an agent: Reveal and copy it here, then enter it in the agent (its status page, or the desktop setup window). Saving a new value rotates it: every agent must then be given the new one."
|
|
88337
|
+
}, {
|
|
88338
|
+
type: "info",
|
|
88339
|
+
key: "meshAuthStatus",
|
|
88340
|
+
label: "Mesh authentication",
|
|
88341
|
+
content: describeMeshStatus(getProcessMeshAuthStatus()),
|
|
88342
|
+
variant: "info"
|
|
88343
|
+
}]
|
|
88376
88344
|
}
|
|
88377
88345
|
] };
|
|
88378
88346
|
}
|
|
@@ -88396,7 +88364,7 @@ var SystemConfigAddon = class extends BaseAddon {
|
|
|
88396
88364
|
/**
|
|
88397
88365
|
* The admin UI / `addonSettings` cap prefer {@link BaseAddon.updateGlobalSettingsAsOperator}.
|
|
88398
88366
|
* That BaseAddon path writes the generic addon store and never reaches
|
|
88399
|
-
* {@link writeClusterSection}
|
|
88367
|
+
* {@link writeClusterSection}. Route the operator
|
|
88400
88368
|
* write through the same section-aware path as {@link updateGlobalSettings}.
|
|
88401
88369
|
*/
|
|
88402
88370
|
async updateGlobalSettingsAsOperator(patch, _nodeId) {
|
|
@@ -88447,8 +88415,7 @@ var SystemConfigAddon = class extends BaseAddon {
|
|
|
88447
88415
|
*/
|
|
88448
88416
|
async writeClusterSection(patch) {
|
|
88449
88417
|
const { [MESH_AUTH_MODE_FIELD]: _legacyMode, [MESH_CLEAR_PORT_FIELD]: clearPort, [AGENT_DASHBOARD_ORIGINS_FIELD]: dashboardOrigins, ...secretPatch } = patch;
|
|
88450
|
-
if (clearPort !== void 0)
|
|
88451
|
-
if (dashboardOrigins !== void 0) await this.ctx.settings.setSection("cluster", { [AGENT_DASHBOARD_ORIGINS_FIELD]: typeof dashboardOrigins === "string" ? dashboardOrigins : "" });
|
|
88418
|
+
if (clearPort !== void 0 || dashboardOrigins !== void 0) this.warnRetiredClusterCutoverPatch(clearPort !== void 0, dashboardOrigins !== void 0);
|
|
88452
88419
|
await this.writeMeshAuthMode("enforced");
|
|
88453
88420
|
if (Object.keys(secretPatch).length === 0) return;
|
|
88454
88421
|
if (isSecretClear(secretPatch["clusterSecret"])) throw new Error("The cluster secret is mandatory and cannot be cleared — save a new value to rotate it");
|
|
@@ -88456,26 +88423,14 @@ var SystemConfigAddon = class extends BaseAddon {
|
|
|
88456
88423
|
this.ctx.logger.info("Cluster secret updated");
|
|
88457
88424
|
await this.clusterSecretKeeper?.reload();
|
|
88458
88425
|
}
|
|
88459
|
-
/**
|
|
88460
|
-
|
|
88461
|
-
|
|
88462
|
-
|
|
88463
|
-
|
|
88464
|
-
|
|
88465
|
-
|
|
88466
|
-
|
|
88467
|
-
if (parseMeshClearPortMode(stored) === value) return;
|
|
88468
|
-
const decision = checkProcessMeshClearPort(value);
|
|
88469
|
-
if (!decision.allowed) {
|
|
88470
|
-
this.ctx.logger.warn("mesh clear port switch-off refused", { meta: {
|
|
88471
|
-
blocking: decision.blocking,
|
|
88472
|
-
error: decision.error
|
|
88473
|
-
} });
|
|
88474
|
-
throw new Error(decision.error);
|
|
88475
|
-
}
|
|
88476
|
-
await this.ctx.settings.setSection("cluster", { [MESH_CLEAR_PORT_FIELD]: value });
|
|
88477
|
-
await applyProcessMeshClearPort(value);
|
|
88478
|
-
this.ctx.logger.info("Mesh clear port switched", { meta: { mode: value } });
|
|
88426
|
+
/** Cutover keys were removed from the Cluster form; ignore stray posts from stale clients. */
|
|
88427
|
+
warnRetiredClusterCutoverPatch(hadMeshClearPort, hadAgentDashboardOrigins) {
|
|
88428
|
+
if (this.retiredClusterCutoverPatchWarned) return;
|
|
88429
|
+
this.retiredClusterCutoverPatchWarned = true;
|
|
88430
|
+
this.ctx.logger.warn("cluster save ignored retired cutover field(s) — use Pipeline → Cluster / Nodes", { meta: {
|
|
88431
|
+
meshClearPort: hadMeshClearPort,
|
|
88432
|
+
agentDashboardOrigins: hadAgentDashboardOrigins
|
|
88433
|
+
} });
|
|
88479
88434
|
}
|
|
88480
88435
|
/** Persist + publish mesh auth mode (always `enforced` after D821). */
|
|
88481
88436
|
async writeMeshAuthMode(mode) {
|