Switch to /api/current as that seems less likely to be removed, use pure jsonrpc

This commit is contained in:
shamoon
2026-01-04 10:21:38 -08:00
parent 46228148b2
commit 84311895ad
2 changed files with 12 additions and 24 deletions

View File

@@ -2,20 +2,17 @@ import WebSocket from "ws";
import getServiceWidget from "utils/config/service-helpers"; import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger"; import createLogger from "utils/logger";
import { sanitizeErrorURL } from "utils/proxy/api-helpers"; import { formatApiCall, sanitizeErrorURL } from "utils/proxy/api-helpers";
import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
import validateWidgetData from "utils/proxy/validate-widget-data"; import validateWidgetData from "utils/proxy/validate-widget-data";
import widgets from "widgets/widgets"; import widgets from "widgets/widgets";
const logger = createLogger("truenasProxyHandler"); const logger = createLogger("truenasProxyHandler");
function buildWebsocketUrl(baseUrl) { function buildWebsocketUrl(widget) {
const url = new URL(baseUrl); let restUrl = formatApiCall(widgets?.[widget.type]?.wsAPI, { ...widget });
const pathname = url.pathname.replace(/\/$/, ""); const url = new URL(restUrl);
url.protocol = url.protocol === "https:" ? "wss:" : "ws:"; url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
url.pathname = `${pathname}/websocket`;
url.search = "";
url.hash = "";
return url.toString(); return url.toString();
} }
@@ -79,28 +76,19 @@ function waitForEvent(ws, handler, { event = "message", parseJson = true } = {})
}); });
} }
async function ensureConnected(ws) {
ws.send(JSON.stringify({ msg: "connect", version: "1", support: ["1"] }));
await waitForEvent(ws, (message) => (message?.msg === "connected" ? true : undefined));
}
let nextId = 1; let nextId = 1;
async function sendMethod(ws, method, params = []) { async function sendMethod(ws, method, params = []) {
const id = nextId++; const id = nextId++;
const payload = { jsonrpc: "2.0", id, method, params };
logger.info("Sending TrueNAS websocket method %s with id %d", method, id); logger.info("Sending TrueNAS websocket method %s with id %d", method, id);
ws.send(JSON.stringify({ id, msg: "method", method, params })); ws.send(JSON.stringify(payload));
return waitForEvent(ws, (message) => { return waitForEvent(ws, (message) => {
if (message?.msg === "result" && message.id === id) { if (message?.id !== id) return undefined;
if (message.error) { if (message?.error) {
return new Error(message.error.reason || JSON.stringify(message.error)); return new Error(message.error?.message || JSON.stringify(message.error));
}
return message.result;
} }
if (message?.msg === "error" && message.id === id) { return message?.result ?? message;
return new Error(message.error || "Unknown websocket error");
}
return undefined;
}); });
} }
@@ -125,14 +113,13 @@ async function authenticate(ws, widget) {
} }
async function callWebsocket(widget, method) { async function callWebsocket(widget, method) {
const wsUrl = buildWebsocketUrl(widget.url); const wsUrl = buildWebsocketUrl(widget);
logger.info("Connecting to TrueNAS websocket at %s", wsUrl); logger.info("Connecting to TrueNAS websocket at %s", wsUrl);
const ws = new WebSocket(wsUrl, { rejectUnauthorized: false }); const ws = new WebSocket(wsUrl, { rejectUnauthorized: false });
await waitForEvent(ws, () => true, { event: "open", parseJson: false }); await waitForEvent(ws, () => true, { event: "open", parseJson: false });
logger.info("Connected to TrueNAS websocket at %s", wsUrl); logger.info("Connected to TrueNAS websocket at %s", wsUrl);
try { try {
await ensureConnected(ws);
await authenticate(ws, widget); await authenticate(ws, widget);
const result = await sendMethod(ws, method); const result = await sendMethod(ws, method);
return result; return result;

View File

@@ -4,6 +4,7 @@ import { asJson, jsonArrayFilter } from "utils/proxy/api-helpers";
const widget = { const widget = {
api: "{url}/api/v2.0/{endpoint}", api: "{url}/api/v2.0/{endpoint}",
wsAPI: "{url}/api/current",
proxyHandler: truenasProxyHandler, proxyHandler: truenasProxyHandler,
mappings: { mappings: {