import { httpProxy } from "utils/proxy/http"; import getServiceWidget from "utils/config/service-helpers"; import createLogger from "utils/logger"; const proxyName = "omadaProxyHandler"; const logger = createLogger(proxyName); async function login(loginUrl, username, password, controllerVersionMajor) { const params = { username, password } if (controllerVersionMajor === 3) { params.method = "login"; params.params = { name: username, password }; } // eslint-disable-next-line no-unused-vars const [status, contentType, data] = await httpProxy(loginUrl, { method: "POST", body: JSON.stringify(params), headers: { "Content-Type": "application/json", }, }); return [status, JSON.parse(data.toString())]; } export default async function omadaProxyHandler(req, res) { const { group, service } = req.query; if (group && service) { const widget = await getServiceWidget(group, service); if (widget) { const {url} = widget; const controllerInfoURL = `${widget.url}/api/info`; let [status, contentType, data] = await httpProxy(controllerInfoURL, { headers: { "Content-Type": "application/json", }, }); if (status !== 200) { logger.error("Unable to retrieve Omada controller info"); return res.status(status).json({error: {message: `HTTP Error ${status}`, url: controllerInfoURL, data}}); } let cId; let controllerVersion; try { cId = JSON.parse(data).result.omadacId; controllerVersion = JSON.parse(data).result.controllerVer; } catch (e) { controllerVersion = "3.2.x" } const controllerVersionMajor = parseInt(controllerVersion.split('.')[0], 10) if (![3,4,5].includes(controllerVersionMajor)) { return res.status(500).json({error: {message: "Error determining controller version", data}}); } let loginUrl; switch (controllerVersionMajor) { case 3: loginUrl = `${widget.url}/api/user/login?ajax`; break; case 4: loginUrl = `${widget.url}/api/v2/login`; break; case 5: loginUrl = `${widget.url}/${cId}/api/v2/login`; break; default: break; } const [loginStatus, loginResponseData] = await login(loginUrl, widget.username, widget.password, controllerVersionMajor); if (loginStatus !== 200 || loginResponseData.errorCode > 0) { return res.status(status).json({error: {message: "Error logging in to Oamda controller", url: loginUrl, data: loginResponseData}}); } const { token } = loginResponseData.result; let sitesUrl; let body = {}; let params = { token }; let headers = { "Csrf-Token": token }; let method = "GET"; switch (controllerVersionMajor) { case 3: sitesUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`; body = { "method": "getUserSites", "params": { "userName": widget.username } }; method = "POST"; break; case 4: sitesUrl = `${widget.url}/api/v2/sites?token=${token}¤tPage=1¤tPageSize=1000`; break; case 5: sitesUrl = `${widget.url}/${cId}/api/v2/sites?token=${token}¤tPage=1¤tPageSize=1000`; break; default: break; } [status, contentType, data] = await httpProxy(sitesUrl, { method, params, body: JSON.stringify(body), headers, }); const sitesResponseData = JSON.parse(data); if (sitesResponseData.errorCode > 0) { logger.debug(`HTTTP ${status} getting sites list: ${sitesResponseData.msg}`); return res.status(status).json({error: {message: "Error getting sites list", url, data: sitesResponseData}}); } const site = (controllerVersionMajor === 3) ? sitesResponseData.result.siteList.find(s => s.name === widget.site): sitesResponseData.result.data.find(s => s.name === widget.site); if (!site) { return res.status(status).json({error: {message: `Site ${widget.site} is not found`, url, data}}); } let siteResponseData; let connectedAp; let activeUser; let connectedSwitches; let connectedGateways; let alerts; if (controllerVersionMajor === 3) { // Omada v3 controller requires switching site const switchUrl = `${widget.url}/web/v1/controller?ajax=&token=${token}`; method = "POST"; body = { method: "switchSite", params: { siteName: site.siteName, userName: widget.username } }; headers = { "Content-Type": "application/json" }; params = { token }; [status, contentType, data] = await httpProxy(switchUrl, { method, params, body: JSON.stringify(body), headers, }); const switchResponseData = JSON.parse(data); if (status !== 200 || switchResponseData.errorCode > 0) { logger.error(`HTTP ${status} getting sites list: ${data}`); return res.status(status).json({error: {message: "Error switching site", url: switchUrl, data}}); } const statsUrl = `${widget.url}/web/v1/controller?getGlobalStat=&token=${token}`; [status, contentType, data] = await httpProxy(statsUrl, { method, params, body: JSON.stringify({ "method": "getGlobalStat", }), headers }); siteResponseData = JSON.parse(data); if (status !== 200 || siteResponseData.errorCode > 0) { return res.status(status).json({error: {message: "Error getting stats", url: statsUrl, data}}); } connectedAp = siteResponseData.result.connectedAp; activeUser = siteResponseData.result.activeUser; alerts = siteResponseData.result.alerts; } else if (controllerVersionMajor === 4 || controllerVersionMajor === 5) { const siteName = (controllerVersionMajor === 5) ? site.id : site.key; const siteStatsUrl = (controllerVersionMajor === 4) ? `${url}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}¤tPage=1¤tPageSize=1000` : `${url}/${cId}/api/v2/sites/${siteName}/dashboard/overviewDiagram?token=${token}¤tPage=1¤tPageSize=1000`; [status, contentType, data] = await httpProxy(siteStatsUrl, { headers: { "Csrf-Token": token, }, }); siteResponseData = JSON.parse(data); if (status !== 200 || siteResponseData.errorCode > 0) { logger.debug(`HTTP ${status} getting stats for site ${widget.site} with message ${siteResponseData.msg}`); return res.status(500).send(data); } const alertUrl = (controllerVersionMajor === 4) ? `${url}/api/v2/sites/${siteName}/alerts/num?token=${token}¤tPage=1¤tPageSize=1000` : `${url}/${cId}/api/v2/sites/${siteName}/alerts/num?token=${token}¤tPage=1¤tPageSize=1000`; // eslint-disable-next-line no-unused-vars [status, contentType, data] = await httpProxy(alertUrl, { headers: { "Csrf-Token": token, }, }); const alertResponseData = JSON.parse(data); activeUser = siteResponseData.result.totalClientNum; connectedAp = siteResponseData.result.connectedApNum; connectedGateways = siteResponseData.result.connectedGatewayNum; connectedSwitches = siteResponseData.result.connectedSwitchNum; alerts = alertResponseData.result.alertNum; } return res.send(JSON.stringify({ connectedAp, activeUser, alerts, connectedGateways, connectedSwitches, })); } } return res.status(400).json({ error: "Invalid proxy service type" }); }