home-hosted 0.7.6 → 0.7.8
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/cli.js
CHANGED
|
@@ -2437,6 +2437,11 @@ function createAuthRoute(deps) {
|
|
|
2437
2437
|
statusCode: 400,
|
|
2438
2438
|
code: "EXPOSED_WITHOUT_PASSWORD"
|
|
2439
2439
|
});
|
|
2440
|
+
const proxyExposure = checkProxyExposure(deps.proxy.config, false, false, false);
|
|
2441
|
+
if (proxyExposure !== null) throw new DetailedError(proxyExposure, {
|
|
2442
|
+
statusCode: 400,
|
|
2443
|
+
code: "PROXY_EXPOSURE_BLOCKED"
|
|
2444
|
+
});
|
|
2440
2445
|
deps.auth.clearPassword();
|
|
2441
2446
|
deps.panel.settings.updateControl({ auth: { enabled: false } });
|
|
2442
2447
|
return c.json({ ok: true });
|
|
@@ -6028,9 +6033,20 @@ var init_logs = __esmMin((() => {
|
|
|
6028
6033
|
}));
|
|
6029
6034
|
//#endregion
|
|
6030
6035
|
//#region src/api/metrics.ts
|
|
6036
|
+
/**
|
|
6037
|
+
* Escapes a value for the quoted form of a Prometheus label, per the exposition
|
|
6038
|
+
* format: only `\\`, `"` and a newline are special, and each needs a backslash.
|
|
6039
|
+
*
|
|
6040
|
+
* A raw Windows path is the reachable case — `diskPaths` is user config and
|
|
6041
|
+
* `C:\Users\me` emits `\U`, which is not a valid escape, so the scraper rejects the
|
|
6042
|
+
* whole sample. The ids are charset-constrained by their schemas, but the paths are not.
|
|
6043
|
+
*/
|
|
6044
|
+
function labelValue(value) {
|
|
6045
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n");
|
|
6046
|
+
}
|
|
6031
6047
|
/** A server id repeats across workspaces, so every sample names both. */
|
|
6032
6048
|
function labels(server) {
|
|
6033
|
-
return `server="${server.id}",workspace="${server.workspaceId ?? ""}"`;
|
|
6049
|
+
return `server="${labelValue(server.id)}",workspace="${labelValue(server.workspaceId ?? "")}"`;
|
|
6034
6050
|
}
|
|
6035
6051
|
/**
|
|
6036
6052
|
* Prometheus text for whatever wants to scrape the panel (Beszel, Grafana,
|
|
@@ -6061,7 +6077,7 @@ function createMetricsRoute(deps) {
|
|
|
6061
6077
|
metric("hh_server_response_ms", "Last health probe latency in milliseconds", servers.filter((server) => server.responseMs !== null).map((server) => `hh_server_response_ms{${labels(server)}} ${server.responseMs}`));
|
|
6062
6078
|
metric("hh_server_rss_bytes", "RSS of the server process tree", servers.filter((server) => server.resources?.rssBytes != null).map((server) => `hh_server_rss_bytes{${labels(server)}} ${server.resources.rssBytes}`));
|
|
6063
6079
|
metric("hh_server_cpu_percent", "CPU percent of the server process tree", servers.filter((server) => server.resources?.cpuPercent != null).map((server) => `hh_server_cpu_percent{${labels(server)}} ${server.resources.cpuPercent}`));
|
|
6064
|
-
metric("hh_host_disk_used_percent", "Disk usage percent per configured path", host.disks.map((disk) => `hh_host_disk_used_percent{mount="${disk.path}"} ${disk.usedPercent.toFixed(2)}`));
|
|
6080
|
+
metric("hh_host_disk_used_percent", "Disk usage percent per configured path", host.disks.map((disk) => `hh_host_disk_used_percent{mount="${labelValue(disk.path)}"} ${disk.usedPercent.toFixed(2)}`));
|
|
6065
6081
|
metric("hh_host_memory_used_percent", "Memory usage percent", [`hh_host_memory_used_percent ${host.memoryUsedPercent.toFixed(2)}`]);
|
|
6066
6082
|
metric("hh_host_swap_used_percent", "Swap usage percent", [`hh_host_swap_used_percent ${host.swapUsedPercent.toFixed(2)}`]);
|
|
6067
6083
|
metric("hh_host_load1_per_cpu", "1 minute load average per cpu", [`hh_host_load1_per_cpu ${((host.loadAvg[0] ?? 0) / Math.max(1, host.cpus)).toFixed(3)}`]);
|
|
@@ -6561,7 +6577,29 @@ function splitCommandLine(line) {
|
|
|
6561
6577
|
let current = "";
|
|
6562
6578
|
let quoted = false;
|
|
6563
6579
|
let started = false;
|
|
6564
|
-
|
|
6580
|
+
const chars = [...line.trim()];
|
|
6581
|
+
for (let index = 0; index < chars.length; index += 1) {
|
|
6582
|
+
const char = chars[index];
|
|
6583
|
+
if (char === "\\") {
|
|
6584
|
+
let run = 0;
|
|
6585
|
+
while (chars[index + run] === "\\") run += 1;
|
|
6586
|
+
if (chars[index + run] !== "\"") {
|
|
6587
|
+
current += "\\".repeat(run);
|
|
6588
|
+
started = true;
|
|
6589
|
+
index += run - 1;
|
|
6590
|
+
continue;
|
|
6591
|
+
}
|
|
6592
|
+
current += "\\".repeat(Math.floor(run / 2));
|
|
6593
|
+
started = true;
|
|
6594
|
+
if (run % 2 === 1) {
|
|
6595
|
+
current += "\"";
|
|
6596
|
+
index += run;
|
|
6597
|
+
continue;
|
|
6598
|
+
}
|
|
6599
|
+
quoted = !quoted;
|
|
6600
|
+
index += run;
|
|
6601
|
+
continue;
|
|
6602
|
+
}
|
|
6565
6603
|
if (char === "\"") {
|
|
6566
6604
|
quoted = !quoted;
|
|
6567
6605
|
started = true;
|
|
@@ -9425,7 +9463,7 @@ function createServersRoute(deps) {
|
|
|
9425
9463
|
responses: {
|
|
9426
9464
|
201: {
|
|
9427
9465
|
description: "Created",
|
|
9428
|
-
content: jsonBody(
|
|
9466
|
+
content: jsonBody(storedServerResponse)
|
|
9429
9467
|
},
|
|
9430
9468
|
400: ERROR_RESPONSES[400]
|
|
9431
9469
|
}
|
|
@@ -9618,7 +9656,7 @@ function createServersRoute(deps) {
|
|
|
9618
9656
|
responses: {
|
|
9619
9657
|
200: {
|
|
9620
9658
|
description: "The server",
|
|
9621
|
-
content: jsonBody(
|
|
9659
|
+
content: jsonBody(storedServerResponse)
|
|
9622
9660
|
},
|
|
9623
9661
|
400: ERROR_RESPONSES[400],
|
|
9624
9662
|
404: ERROR_RESPONSES[404]
|
|
@@ -9660,7 +9698,7 @@ function createServersRoute(deps) {
|
|
|
9660
9698
|
}
|
|
9661
9699
|
});
|
|
9662
9700
|
}
|
|
9663
|
-
var idParam$1, MAX_PENDING_WRITES, serverResponse, serversResponse, okResponse, bufferedLogsQuery;
|
|
9701
|
+
var idParam$1, MAX_PENDING_WRITES, serverResponse, serversResponse, storedServerResponse, okResponse, bufferedLogsQuery;
|
|
9664
9702
|
var init_$_routes$1 = __esmMin((() => {
|
|
9665
9703
|
init_store();
|
|
9666
9704
|
init_action_result();
|
|
@@ -9674,6 +9712,7 @@ var init_$_routes$1 = __esmMin((() => {
|
|
|
9674
9712
|
MAX_PENDING_WRITES = 200;
|
|
9675
9713
|
serverResponse = type({ server: serverViewSchema });
|
|
9676
9714
|
serversResponse = type({ servers: serverViewSchema.array() });
|
|
9715
|
+
storedServerResponse = type({ server: serverSchema });
|
|
9677
9716
|
okResponse = type({ ok: "boolean" });
|
|
9678
9717
|
bufferedLogsQuery = logQuerySchema.merge(workspaceQuerySchema);
|
|
9679
9718
|
}));
|
|
@@ -9736,6 +9775,11 @@ function createSettingsRoute(deps) {
|
|
|
9736
9775
|
statusCode: 400,
|
|
9737
9776
|
code: "EXPOSURE_BLOCKED"
|
|
9738
9777
|
});
|
|
9778
|
+
const proxyExposure = checkProxyExposure(deps.proxy.config, patch.control?.auth?.enabled ?? current.auth.enabled, deps.auth.passwordSet, deps.auth.usingDefaultPassword);
|
|
9779
|
+
if (proxyExposure !== null) throw new DetailedError(proxyExposure, {
|
|
9780
|
+
statusCode: 400,
|
|
9781
|
+
code: "PROXY_EXPOSURE_BLOCKED"
|
|
9782
|
+
});
|
|
9739
9783
|
const previous = {
|
|
9740
9784
|
trustProxy: current.auth.trustProxy,
|
|
9741
9785
|
tlsEnabled: current.tls.enabled
|