@@ -42,6 +45,23 @@ export default function Widget({ options }) {
);
}
+ const wan = defaultSite.health.find(h => h.subsystem === "wan");
+ const lan = defaultSite.health.find(h => h.subsystem === "lan");
+ const wlan = defaultSite.health.find(h => h.subsystem === "wlan");
+ const data = {
+ name: wan.gw_name,
+ uptime: wan["gw_system-stats"].uptime,
+ up: wan.status === 'ok',
+ wlan: {
+ users: wlan.num_user,
+ status: wlan.status
+ },
+ lan: {
+ users: lan.num_user,
+ status: lan.status
+ }
+ };
+
return (
diff --git a/src/pages/api/widgets/unifi.js b/src/pages/api/widgets/unifi.js
deleted file mode 100644
index f8cbcc1e6..000000000
--- a/src/pages/api/widgets/unifi.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Controller } from "node-unifi";
-
-export default async function handler(req, res) {
- const { host, port, username, password } = req.query;
-
- if (!host) {
- return res.status(400).json({ error: "Missing host" });
- }
-
- if (!username) {
- return res.status(400).json({ error: "Missing username" });
- }
-
- if (!password) {
- return res.status(400).json({ error: "Missing password" });
- }
-
- const controller = new Controller({
- host: host,
- port: port,
- sslverify: false
- });
-
- try {
- //login to the controller
- await controller.login(username, password);
-
- //retrieve sites
- const sites = await controller.getSitesStats();
- const default_site = sites.find(s => s.name == "default");
- const wan = default_site.health.find(h => h.subsystem == "wan");
- const lan = default_site.health.find(h => h.subsystem == "lan");
- const wlan = default_site.health.find(h => h.subsystem == "wlan");
-
- return res.status(200).json({
- name: wan.gw_name,
- uptime: wan['gw_system-stats']['uptime'],
- up: wan.status == 'ok',
- wlan: {
- users: wlan.num_user,
- status: wlan.status
- },
- lan: {
- users: lan.num_user,
- status: lan.status
- }
- });
- } catch (e) {
- return res.status(400).json({
- error: `Error communicating with UniFi Console: ${e.message}`
- })
- }
-}
diff --git a/src/utils/proxy/api-helpers.js b/src/utils/proxy/api-helpers.js
index 55cd333c5..904c9e967 100644
--- a/src/utils/proxy/api-helpers.js
+++ b/src/utils/proxy/api-helpers.js
@@ -2,7 +2,7 @@ export function formatApiCall(url, args) {
const find = /\{.*?\}/g;
const replace = (match) => {
const key = match.replace(/\{|\}/g, "");
- return args[key];
+ return args[key] || "";
};
return url.replace(/\/+$/, "").replace(find, replace);
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
new file mode 100644
index 000000000..d4d50e0d6
--- /dev/null
+++ b/src/widgets/unifi/proxy.js
@@ -0,0 +1,103 @@
+import { formatApiCall } from "utils/proxy/api-helpers";
+import { httpProxy } from "utils/proxy/http";
+import { addCookieToJar, setCookieHeader } from "utils/proxy/cookie-jar";
+import { getSettings } from "utils/config/config";
+import getServiceWidget from "utils/config/service-helpers";
+import createLogger from "utils/logger";
+import widgets from "widgets/widgets";
+
+const logger = createLogger("unifiProxyHandler");
+
+async function getWidget(req) {
+ const { group, service, type } = req.query;
+
+ let widget = null;
+ if (type === 'unifi_console') {
+ const settings = getSettings();
+ widget = settings.unifi_console;
+ if (!widget) {
+ logger.debug("There is no unifi_console section in settings.yaml");
+ return null;
+ }
+ widget.type = "unifi";
+ } else {
+ if (!group || !service) {
+ logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
+ return null;
+ }
+
+ widget = await getServiceWidget(group, service);
+
+ if (!widget) {
+ logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
+ return null;
+ }
+ }
+
+ return widget;
+}
+
+async function login(widget) {
+ logger.debug("Unifi isn't logged in or is rejecting the reqeust, logging in.");
+
+ const loginBody = { username: widget.username, password: widget.password, remember: true };
+ let loginUrl = `${widget.url}/api`;
+ if (widget.version === "udm-pro") {
+ loginUrl += "/auth"
+ }
+ loginUrl += "/login";
+
+ const loginParams = { method: "POST", body: JSON.stringify(loginBody) };
+ const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, loginParams);
+ return [status, contentType, data, responseHeaders];
+}
+
+export default async function unifiProxyHandler(req, res) {
+ const widget = await getWidget(req);
+ if (!widget) {
+ return res.status(400).json({ error: "Invalid proxy service type" });
+ }
+
+ const api = widgets?.[widget.type]?.api;
+ if (!api) {
+ return res.status(403).json({ error: "Service does not support API calls" });
+ }
+
+ widget.prefx = "";
+ if (widget.version === "udm-pro") {
+ widget.prefix = "/proxy/network"
+ }
+
+ const { endpoint } = req.query;
+ const url = new URL(formatApiCall(api, { endpoint, ...widget }));
+ const params = { method: "GET", headers: {} };
+ setCookieHeader(url, params);
+
+ let [status, contentType, data, responseHeaders] = await httpProxy(url, params);
+ if (status === 401) {
+ [status, contentType, data, responseHeaders] = await login(widget);
+
+ if (status !== 200) {
+ logger.error("HTTP %d logging in to Unifi. Data: %s", status, data);
+ return res.status(status).end(data);
+ }
+
+ const json = JSON.parse(data.toString());
+ if (json?.meta?.rc !== "ok") {
+ logger.error("Error logging in to Unifi: Data: %s", data);
+ return res.status(401).end(data);
+ }
+
+ addCookieToJar(url, responseHeaders);
+ setCookieHeader(url, params);
+ }
+
+ [status, contentType, data] = await httpProxy(url, params);
+
+ if (status !== 200) {
+ logger.error("HTTP %d getting data from Unifi. Data: %s", status, data);
+ }
+
+ if (contentType) res.setHeader("Content-Type", contentType);
+ return res.status(status).send(data);
+}
diff --git a/src/widgets/unifi/widget.js b/src/widgets/unifi/widget.js
new file mode 100644
index 000000000..928ebd766
--- /dev/null
+++ b/src/widgets/unifi/widget.js
@@ -0,0 +1,14 @@
+import unifiProxyHandler from "./proxy";
+
+const widget = {
+ api: "{url}{prefix}/api/{endpoint}",
+ proxyHandler: unifiProxyHandler,
+
+ mappings: {
+ "stat/sites": {
+ endpoint: "stat/sites",
+ },
+ }
+};
+
+export default widget;
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index 04665c782..a4cab76b0 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -27,6 +27,7 @@ import strelaysrv from "./strelaysrv/widget";
import tautulli from "./tautulli/widget";
import traefik from "./traefik/widget";
import transmission from "./transmission/widget";
+import unifi from "./unifi/widget";
const widgets = {
adguard,
@@ -59,6 +60,8 @@ const widgets = {
tautulli,
traefik,
transmission,
+ unifi,
+ unifi_console: unifi
};
export default widgets;
From ad1d1e751dd9edf54c951b0cb93953892443b9cb Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Fri, 7 Oct 2022 23:26:16 -0700
Subject: [PATCH 05/15] Refactor unifi proxy for udm-pro compatibility
---
src/widgets/unifi/proxy.js | 51 ++++++++++++++++++++++++++-----------
src/widgets/unifi/widget.js | 2 +-
2 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index d4d50e0d6..914460512 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -38,17 +38,22 @@ async function getWidget(req) {
}
async function login(widget) {
- logger.debug("Unifi isn't logged in or is rejecting the reqeust, logging in.");
+ let endpoint = widget.udmp ? "auth/login" : "login";
+ widget.prefix = ""; // never use prefix for login
+ const api = widgets?.[widget.type]?.api;
+ const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
const loginBody = { username: widget.username, password: widget.password, remember: true };
- let loginUrl = `${widget.url}/api`;
- if (widget.version === "udm-pro") {
- loginUrl += "/auth"
- }
- loginUrl += "/login";
- const loginParams = { method: "POST", body: JSON.stringify(loginBody) };
- const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, loginParams);
+ const headers = {
+ "Content-Type": "application/json"
+ };
+
+ const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, {
+ method: "POST",
+ body: JSON.stringify(loginBody),
+ headers
+ });
return [status, contentType, data, responseHeaders];
}
@@ -62,9 +67,22 @@ export default async function unifiProxyHandler(req, res) {
if (!api) {
return res.status(403).json({ error: "Service does not support API calls" });
}
+
+ // determine if udm-pro from base url
+ let [status, contentType, data, responseHeaders] = await httpProxy(`https://${widget.host}`);
+ if (responseHeaders['x-csrf-token']) {
+ widget.udmp = true
+ }
- widget.prefx = "";
- if (widget.version === "udm-pro") {
+ if (!widget.port) {
+ widget.port = 8443;
+ if (widget.udmp) {
+ widget.port = 443
+ }
+ }
+
+ widget.prefix = "";
+ if (widget.udmp) {
widget.prefix = "/proxy/network"
}
@@ -73,29 +91,32 @@ export default async function unifiProxyHandler(req, res) {
const params = { method: "GET", headers: {} };
setCookieHeader(url, params);
- let [status, contentType, data, responseHeaders] = await httpProxy(url, params);
+ [status, contentType, data, responseHeaders] = await httpProxy(url, params);
if (status === 401) {
+ logger.debug("Unifi isn't logged in or rejected the reqeust, attempting login.");
[status, contentType, data, responseHeaders] = await login(widget);
if (status !== 200) {
- logger.error("HTTP %d logging in to Unifi. Data: %s", status, data);
+ logger.error("HTTP %d logging in to Unifi. Data: %s", status, data);
return res.status(status).end(data);
}
const json = JSON.parse(data.toString());
- if (json?.meta?.rc !== "ok") {
+ if (!(json?.meta?.rc === "ok" || json.login_time)) {
logger.error("Error logging in to Unifi: Data: %s", data);
return res.status(401).end(data);
}
addCookieToJar(url, responseHeaders);
setCookieHeader(url, params);
+
+ logger.debug("Retrying Unifi reqeust after login.");
+ [status, contentType, data, responseHeaders] = await httpProxy(url, params);
}
- [status, contentType, data] = await httpProxy(url, params);
if (status !== 200) {
- logger.error("HTTP %d getting data from Unifi. Data: %s", status, data);
+ logger.error("HTTP %d getting data from Unifi endpoint %s. Data: %s", status, url.href, data);
}
if (contentType) res.setHeader("Content-Type", contentType);
diff --git a/src/widgets/unifi/widget.js b/src/widgets/unifi/widget.js
index 928ebd766..f4b1366fe 100644
--- a/src/widgets/unifi/widget.js
+++ b/src/widgets/unifi/widget.js
@@ -1,7 +1,7 @@
import unifiProxyHandler from "./proxy";
const widget = {
- api: "{url}{prefix}/api/{endpoint}",
+ api: "https://{host}:{port}{prefix}/api/{endpoint}",
proxyHandler: unifiProxyHandler,
mappings: {
From e03822df6eabc2ab98272c656112cb9823e0e5a4 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sat, 8 Oct 2022 00:45:00 -0700
Subject: [PATCH 06/15] Add UniFI console service widget
---
public/locales/en/common.json | 4 +++
src/widgets/components.js | 1 +
src/widgets/unifi/component.jsx | 56 +++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
create mode 100644 src/widgets/unifi/component.jsx
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index af8fc1974..669ebd276 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -36,6 +36,10 @@
"uptime": "System Uptime",
"days": "Days",
"wan": "WAN",
+ "lan": "LAN",
+ "wlan": "WLAN",
+ "up": "UP",
+ "down": "DOWN",
"wait": "Please wait"
},
"docker": {
diff --git a/src/widgets/components.js b/src/widgets/components.js
index 5357c0704..0ff197afb 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -32,6 +32,7 @@ const components = {
tautulli: dynamic(() => import("./tautulli/component")),
traefik: dynamic(() => import("./traefik/component")),
transmission: dynamic(() => import("./transmission/component")),
+ unifi_console: dynamic(() => import("./unifi/component")),
};
export default components;
diff --git a/src/widgets/unifi/component.jsx b/src/widgets/unifi/component.jsx
new file mode 100644
index 000000000..82b339415
--- /dev/null
+++ b/src/widgets/unifi/component.jsx
@@ -0,0 +1,56 @@
+import { useTranslation } from "next-i18next";
+
+import Container from "components/services/widget/container";
+import Block from "components/services/widget/block";
+import useWidgetAPI from "utils/proxy/use-widget-api";
+
+export default function Component({ service }) {
+ const { t } = useTranslation();
+
+ const { widget } = service;
+
+ const { data: statsData, error: statsError } = useWidgetAPI(widget, "stat/sites");
+
+ if (statsError || statsData?.error) {
+ return ;
+ }
+
+ const defaultSite = statsData?.data?.find(s => s.name === "default");
+
+ if (!defaultSite) {
+ return (
+
+
+
+
+
+
+ );
+ }
+
+ const wan = defaultSite.health.find(h => h.subsystem === "wan");
+ const lan = defaultSite.health.find(h => h.subsystem === "lan");
+ const wlan = defaultSite.health.find(h => h.subsystem === "wlan");
+ const data = {
+ name: wan.gw_name,
+ uptime: wan["gw_system-stats"].uptime,
+ up: wan.status === 'ok',
+ wlan: {
+ users: wlan.num_user,
+ status: wlan.status
+ },
+ lan: {
+ users: lan.num_user,
+ status: lan.status
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ );
+}
From 2bd9c8eddcca78bc30817e33f1388d17fd0231b6 Mon Sep 17 00:00:00 2001
From: Jason Fischer
Date: Sat, 8 Oct 2022 13:52:07 -0700
Subject: [PATCH 07/15] Cache console version check result
---
src/widgets/unifi/component.jsx | 10 +++++--
src/widgets/unifi/proxy.js | 52 ++++++++++++++++-----------------
src/widgets/unifi/widget.js | 2 +-
3 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/src/widgets/unifi/component.jsx b/src/widgets/unifi/component.jsx
index 82b339415..0ab862bd6 100644
--- a/src/widgets/unifi/component.jsx
+++ b/src/widgets/unifi/component.jsx
@@ -45,12 +45,16 @@ export default function Component({ service }) {
}
};
+ const uptime = `${t("common.number", { value: data.uptime / 86400, maximumFractionDigits: 1 })} ${t("unifi.days")}`;
+ const lanUsers = `${t("common.number", { value: data.lan.users })} ${t("unifi.users")}`;
+ const wanUsers = `${t("common.number", { value: data.wlan.users })} ${t("unifi.users")}`;
+
return (
-
+
-
-
+
+
);
}
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index 914460512..181f43d7a 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -1,3 +1,5 @@
+import cache from "memory-cache";
+
import { formatApiCall } from "utils/proxy/api-helpers";
import { httpProxy } from "utils/proxy/http";
import { addCookieToJar, setCookieHeader } from "utils/proxy/cookie-jar";
@@ -6,7 +8,10 @@ import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
import widgets from "widgets/widgets";
-const logger = createLogger("unifiProxyHandler");
+const udmpPrefix = "/proxy/network";
+const proxyName = "unifiProxyHandler";
+const prefixCacheKey = `${proxyName}__prefix`;
+const logger = createLogger(proxyName);
async function getWidget(req) {
const { group, service, type } = req.query;
@@ -38,21 +43,18 @@ async function getWidget(req) {
}
async function login(widget) {
- let endpoint = widget.udmp ? "auth/login" : "login";
- widget.prefix = ""; // never use prefix for login
- const api = widgets?.[widget.type]?.api;
- const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
+ let loginUrl = `${widget.url}/api`;
+ if (widget.prefix === udmpPrefix) {
+ loginUrl += "/auth"
+ }
+ loginUrl += "/login";
const loginBody = { username: widget.username, password: widget.password, remember: true };
-
- const headers = {
- "Content-Type": "application/json"
- };
-
+ const headers = { "Content-Type": "application/json" };
const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, {
method: "POST",
body: JSON.stringify(loginBody),
- headers
+ headers,
});
return [status, contentType, data, responseHeaders];
}
@@ -67,24 +69,21 @@ export default async function unifiProxyHandler(req, res) {
if (!api) {
return res.status(403).json({ error: "Service does not support API calls" });
}
-
- // determine if udm-pro from base url
- let [status, contentType, data, responseHeaders] = await httpProxy(`https://${widget.host}`);
- if (responseHeaders['x-csrf-token']) {
- widget.udmp = true
- }
- if (!widget.port) {
- widget.port = 8443;
- if (widget.udmp) {
- widget.port = 443
+ let [status, contentType, data, responseHeaders] = [];
+ let prefix = cache.get(prefixCacheKey);
+ if (prefix === null) {
+ // auto detect if we're talking to a UDM Pro, and cache the result so that we
+ // don't make two requests each time data from Unifi is required
+ [status, contentType, data, responseHeaders] = await httpProxy(widget.url);
+ prefix = "";
+ if (responseHeaders["x-csrf-token"]) {
+ prefix = udmpPrefix;
}
+ cache.put(prefixCacheKey, prefix);
}
- widget.prefix = "";
- if (widget.udmp) {
- widget.prefix = "/proxy/network"
- }
+ widget.prefix = prefix;
const { endpoint } = req.query;
const url = new URL(formatApiCall(api, { endpoint, ...widget }));
@@ -110,11 +109,10 @@ export default async function unifiProxyHandler(req, res) {
addCookieToJar(url, responseHeaders);
setCookieHeader(url, params);
- logger.debug("Retrying Unifi reqeust after login.");
+ logger.debug("Retrying Unifi request after login.");
[status, contentType, data, responseHeaders] = await httpProxy(url, params);
}
-
if (status !== 200) {
logger.error("HTTP %d getting data from Unifi endpoint %s. Data: %s", status, url.href, data);
}
diff --git a/src/widgets/unifi/widget.js b/src/widgets/unifi/widget.js
index f4b1366fe..928ebd766 100644
--- a/src/widgets/unifi/widget.js
+++ b/src/widgets/unifi/widget.js
@@ -1,7 +1,7 @@
import unifiProxyHandler from "./proxy";
const widget = {
- api: "https://{host}:{port}{prefix}/api/{endpoint}",
+ api: "{url}{prefix}/api/{endpoint}",
proxyHandler: unifiProxyHandler,
mappings: {
From 7ee3113d8a2525f3b46f5c3fa9d98bfc67e86001 Mon Sep 17 00:00:00 2001
From: Jason Fischer
Date: Sat, 8 Oct 2022 13:58:19 -0700
Subject: [PATCH 08/15] Rename unifi_console service widget to unifi - This
rename is necessary as the Unifi service widet gets its config data from a
different location than the unifi_console information widget
---
src/widgets/components.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/widgets/components.js b/src/widgets/components.js
index 0ff197afb..c2a6705ed 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -32,7 +32,7 @@ const components = {
tautulli: dynamic(() => import("./tautulli/component")),
traefik: dynamic(() => import("./traefik/component")),
transmission: dynamic(() => import("./transmission/component")),
- unifi_console: dynamic(() => import("./unifi/component")),
+ unifi: dynamic(() => import("./unifi/component")),
};
export default components;
From 42da3eca28c9744eb99264b4e658120c1918d4b7 Mon Sep 17 00:00:00 2001
From: Jason Fischer
Date: Sat, 8 Oct 2022 13:59:09 -0700
Subject: [PATCH 09/15] Standardize on double quoted strings
---
src/widgets/unifi/proxy.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index 181f43d7a..43a2e46fa 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -17,7 +17,7 @@ async function getWidget(req) {
const { group, service, type } = req.query;
let widget = null;
- if (type === 'unifi_console') {
+ if (type === "unifi_console") {
const settings = getSettings();
widget = settings.unifi_console;
if (!widget) {
From fe1064b173be9a9093ed2afbfbdb0b4793c5c56e Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sat, 8 Oct 2022 14:02:12 -0700
Subject: [PATCH 10/15] Rename unifi_console info widget to unifi
---
.../{unifi_console/unifi_console.jsx => unifi/unifi.jsx} | 2 +-
src/components/widgets/widget.jsx | 2 +-
src/widgets/unifi/proxy.js | 6 +++---
src/widgets/widgets.js | 1 -
4 files changed, 5 insertions(+), 6 deletions(-)
rename src/components/widgets/{unifi_console/unifi_console.jsx => unifi/unifi.jsx} (99%)
diff --git a/src/components/widgets/unifi_console/unifi_console.jsx b/src/components/widgets/unifi/unifi.jsx
similarity index 99%
rename from src/components/widgets/unifi_console/unifi_console.jsx
rename to src/components/widgets/unifi/unifi.jsx
index 7427bd23c..ae7f1a7f3 100644
--- a/src/components/widgets/unifi_console/unifi_console.jsx
+++ b/src/components/widgets/unifi/unifi.jsx
@@ -9,7 +9,7 @@ export default function Widget({ options }) {
const { t } = useTranslation();
// eslint-disable-next-line no-param-reassign
- options.type = "unifi_console";
+ options.type = "unifi";
const { data: statsData, error: statsError } = useWidgetAPI(options, "stat/sites");
if (statsError || statsData?.error) {
diff --git a/src/components/widgets/widget.jsx b/src/components/widgets/widget.jsx
index ac5353eb9..fc5a72a53 100644
--- a/src/components/widgets/widget.jsx
+++ b/src/components/widgets/widget.jsx
@@ -10,7 +10,7 @@ const widgetMappings = {
greeting: dynamic(() => import("components/widgets/greeting/greeting")),
datetime: dynamic(() => import("components/widgets/datetime/datetime")),
logo: dynamic(() => import("components/widgets/logo/logo"), { ssr: false }),
- unifi_console: dynamic(() => import("components/widgets/unifi_console/unifi_console")),
+ unifi: dynamic(() => import("components/widgets/unifi/unifi")),
};
export default function Widget({ widget }) {
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index 43a2e46fa..61682ef8a 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -17,11 +17,11 @@ async function getWidget(req) {
const { group, service, type } = req.query;
let widget = null;
- if (type === "unifi_console") {
+ if (type === "unifi") {
const settings = getSettings();
- widget = settings.unifi_console;
+ widget = settings.unifi;
if (!widget) {
- logger.debug("There is no unifi_console section in settings.yaml");
+ logger.debug("There is no unifi section in settings.yaml");
return null;
}
widget.type = "unifi";
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index a4cab76b0..c922a9458 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -61,7 +61,6 @@ const widgets = {
traefik,
transmission,
unifi,
- unifi_console: unifi
};
export default widgets;
From d1b6dad14dca425b94c8acfc82d5559ed718c9b0 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sat, 8 Oct 2022 14:36:08 -0700
Subject: [PATCH 11/15] Infer unifi port, use api widget property for login
---
src/widgets/unifi/proxy.js | 16 ++++++++++------
src/widgets/unifi/widget.js | 2 +-
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index 61682ef8a..601e42421 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -43,12 +43,9 @@ async function getWidget(req) {
}
async function login(widget) {
- let loginUrl = `${widget.url}/api`;
- if (widget.prefix === udmpPrefix) {
- loginUrl += "/auth"
- }
- loginUrl += "/login";
-
+ const endpoint = (widget.prefix === udmpPrefix) ? "auth/login" : "login";
+ const api = widgets?.[widget.type]?.api?.replace("{prefix}", ""); // no prefix for login url
+ const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
const loginBody = { username: widget.username, password: widget.password, remember: true };
const headers = { "Content-Type": "application/json" };
const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, {
@@ -85,6 +82,13 @@ export default async function unifiProxyHandler(req, res) {
widget.prefix = prefix;
+ if (!widget.port) {
+ widget.port = 8443;
+ if (widget.prefix == udmpPrefix) {
+ widget.port = 443
+ }
+ }
+
const { endpoint } = req.query;
const url = new URL(formatApiCall(api, { endpoint, ...widget }));
const params = { method: "GET", headers: {} };
diff --git a/src/widgets/unifi/widget.js b/src/widgets/unifi/widget.js
index 928ebd766..0ac3c311e 100644
--- a/src/widgets/unifi/widget.js
+++ b/src/widgets/unifi/widget.js
@@ -1,7 +1,7 @@
import unifiProxyHandler from "./proxy";
const widget = {
- api: "{url}{prefix}/api/{endpoint}",
+ api: "{url}:{port}{prefix}/api/{endpoint}",
proxyHandler: unifiProxyHandler,
mappings: {
From fbac27f504f07ce2a3557d8f70e6fe424a8ecbad Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sat, 8 Oct 2022 17:47:52 -0700
Subject: [PATCH 12/15] Fix unifi service lan/wlan labels
---
src/widgets/unifi/component.jsx | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/widgets/unifi/component.jsx b/src/widgets/unifi/component.jsx
index 0ab862bd6..aa4204e4f 100644
--- a/src/widgets/unifi/component.jsx
+++ b/src/widgets/unifi/component.jsx
@@ -15,6 +15,9 @@ export default function Component({ service }) {
return ;
}
+ const wlanLabel = t("unifi.wlan") + " " + t("unifi.users")
+ const lanLabel = t("unifi.lan") + " " + t("unifi.users")
+
const defaultSite = statsData?.data?.find(s => s.name === "default");
if (!defaultSite) {
@@ -22,8 +25,8 @@ export default function Component({ service }) {
-
-
+
+
);
}
@@ -46,15 +49,13 @@ export default function Component({ service }) {
};
const uptime = `${t("common.number", { value: data.uptime / 86400, maximumFractionDigits: 1 })} ${t("unifi.days")}`;
- const lanUsers = `${t("common.number", { value: data.lan.users })} ${t("unifi.users")}`;
- const wanUsers = `${t("common.number", { value: data.wlan.users })} ${t("unifi.users")}`;
return (
-
-
+
+
);
}
From 69c9a449b11740ddf16a0c6384b498fe99cc2f4f Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sun, 9 Oct 2022 09:15:46 -0700
Subject: [PATCH 13/15] Revert "Rename unifi_console info widget to unifi"
---
.../{unifi/unifi.jsx => unifi_console/unifi_console.jsx} | 2 +-
src/components/widgets/widget.jsx | 2 +-
src/widgets/unifi/proxy.js | 6 +++---
src/widgets/widgets.js | 1 +
4 files changed, 6 insertions(+), 5 deletions(-)
rename src/components/widgets/{unifi/unifi.jsx => unifi_console/unifi_console.jsx} (99%)
diff --git a/src/components/widgets/unifi/unifi.jsx b/src/components/widgets/unifi_console/unifi_console.jsx
similarity index 99%
rename from src/components/widgets/unifi/unifi.jsx
rename to src/components/widgets/unifi_console/unifi_console.jsx
index ae7f1a7f3..7427bd23c 100644
--- a/src/components/widgets/unifi/unifi.jsx
+++ b/src/components/widgets/unifi_console/unifi_console.jsx
@@ -9,7 +9,7 @@ export default function Widget({ options }) {
const { t } = useTranslation();
// eslint-disable-next-line no-param-reassign
- options.type = "unifi";
+ options.type = "unifi_console";
const { data: statsData, error: statsError } = useWidgetAPI(options, "stat/sites");
if (statsError || statsData?.error) {
diff --git a/src/components/widgets/widget.jsx b/src/components/widgets/widget.jsx
index fc5a72a53..ac5353eb9 100644
--- a/src/components/widgets/widget.jsx
+++ b/src/components/widgets/widget.jsx
@@ -10,7 +10,7 @@ const widgetMappings = {
greeting: dynamic(() => import("components/widgets/greeting/greeting")),
datetime: dynamic(() => import("components/widgets/datetime/datetime")),
logo: dynamic(() => import("components/widgets/logo/logo"), { ssr: false }),
- unifi: dynamic(() => import("components/widgets/unifi/unifi")),
+ unifi_console: dynamic(() => import("components/widgets/unifi_console/unifi_console")),
};
export default function Widget({ widget }) {
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index 601e42421..60ef44035 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -17,11 +17,11 @@ async function getWidget(req) {
const { group, service, type } = req.query;
let widget = null;
- if (type === "unifi") {
+ if (type === "unifi_console") {
const settings = getSettings();
- widget = settings.unifi;
+ widget = settings.unifi_console;
if (!widget) {
- logger.debug("There is no unifi section in settings.yaml");
+ logger.debug("There is no unifi_console section in settings.yaml");
return null;
}
widget.type = "unifi";
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index c922a9458..a4cab76b0 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -61,6 +61,7 @@ const widgets = {
traefik,
transmission,
unifi,
+ unifi_console: unifi
};
export default widgets;
From 86b12debc58e5c9a8ba1cc3ac25b89e2d5c33ddb Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sun, 9 Oct 2022 09:17:50 -0700
Subject: [PATCH 14/15] Revert "Infer unifi port"
---
src/widgets/unifi/proxy.js | 7 -------
src/widgets/unifi/widget.js | 2 +-
2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/widgets/unifi/proxy.js b/src/widgets/unifi/proxy.js
index 60ef44035..53ee49f03 100644
--- a/src/widgets/unifi/proxy.js
+++ b/src/widgets/unifi/proxy.js
@@ -82,13 +82,6 @@ export default async function unifiProxyHandler(req, res) {
widget.prefix = prefix;
- if (!widget.port) {
- widget.port = 8443;
- if (widget.prefix == udmpPrefix) {
- widget.port = 443
- }
- }
-
const { endpoint } = req.query;
const url = new URL(formatApiCall(api, { endpoint, ...widget }));
const params = { method: "GET", headers: {} };
diff --git a/src/widgets/unifi/widget.js b/src/widgets/unifi/widget.js
index 0ac3c311e..928ebd766 100644
--- a/src/widgets/unifi/widget.js
+++ b/src/widgets/unifi/widget.js
@@ -1,7 +1,7 @@
import unifiProxyHandler from "./proxy";
const widget = {
- api: "{url}:{port}{prefix}/api/{endpoint}",
+ api: "{url}{prefix}/api/{endpoint}",
proxyHandler: unifiProxyHandler,
mappings: {
From 04da8f3925f43f9695805d6b1118e18b4cba37ed Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Sun, 9 Oct 2022 15:13:27 -0700
Subject: [PATCH 15/15] lint
---
src/widgets/unifi/component.jsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/widgets/unifi/component.jsx b/src/widgets/unifi/component.jsx
index aa4204e4f..8a654a516 100644
--- a/src/widgets/unifi/component.jsx
+++ b/src/widgets/unifi/component.jsx
@@ -15,8 +15,8 @@ export default function Component({ service }) {
return ;
}
- const wlanLabel = t("unifi.wlan") + " " + t("unifi.users")
- const lanLabel = t("unifi.lan") + " " + t("unifi.users")
+ const wlanLabel = `${t("unifi.wlan")} ${t("unifi.users")}`
+ const lanLabel = `${t("unifi.lan")} ${t("unifi.users")}`
const defaultSite = statsData?.data?.find(s => s.name === "default");