From d5db40f40d1ab12c6549c48e38540a677b4f6e34 Mon Sep 17 00:00:00 2001 From: M1CK431 Date: Mon, 31 Jul 2023 23:08:03 +0200 Subject: [PATCH] API: make all resources users-agnostic --- server/client.js | 10 ++-- server/docker.js | 7 ++- server/notification.js | 20 ++------ server/proxy.js | 12 ++--- server/server.js | 46 ++----------------- .../socket-handlers/api-key-socket-handler.js | 5 +- .../maintenance-socket-handler.js | 14 +----- server/uptime-kuma-server.js | 18 +++----- 8 files changed, 30 insertions(+), 102 deletions(-) diff --git a/server/client.js b/server/client.js index 72f0a4e8..0890ec8b 100644 --- a/server/client.js +++ b/server/client.js @@ -19,9 +19,7 @@ async function sendNotificationList(socket) { const timeLogger = new TimeLogger(); let result = []; - let list = await R.find("notification", " user_id = ? ", [ - socket.userID, - ]); + let list = await R.findAll("notification"); for (let bean of list) { let notificationObject = bean.export(); @@ -102,7 +100,7 @@ async function sendImportantHeartbeatList(socket, monitorID, toUser = false, ove async function sendProxyList(socket) { const timeLogger = new TimeLogger(); - const list = await R.find("proxy", " user_id = ? ", [ socket.userID ]); + const list = await R.findAll("proxy"); io.to(socket.userID).emit("proxyList", list.map(bean => bean.export())); timeLogger.print("Send Proxy List"); @@ -174,9 +172,7 @@ async function sendDockerHostList(socket) { const timeLogger = new TimeLogger(); let result = []; - let list = await R.find("docker_host", " user_id = ? ", [ - socket.userID, - ]); + let list = await R.findAll("docker_host"); for (let bean of list) { result.push(bean.toJSON()); diff --git a/server/docker.js b/server/docker.js index ee6051df..8330c201 100644 --- a/server/docker.js +++ b/server/docker.js @@ -23,7 +23,7 @@ class DockerHost { let bean; if (dockerHostID) { - bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [ dockerHostID, userID ]); + bean = await R.findOne("docker_host", " id = ? ", [ dockerHostID ]); if (!bean) { throw new Error("docker host not found"); @@ -46,11 +46,10 @@ class DockerHost { /** * Delete a Docker host * @param {number} dockerHostID ID of the Docker host to delete - * @param {number} userID ID of the user who created the Docker host * @returns {Promise} */ - static async delete(dockerHostID, userID) { - let bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [ dockerHostID, userID ]); + static async delete(dockerHostID) { + let bean = await R.findOne("docker_host", " id = ? ", [ dockerHostID ]); if (!bean) { throw new Error("docker host not found"); diff --git a/server/notification.js b/server/notification.js index 26daeb04..6ed6f605 100644 --- a/server/notification.js +++ b/server/notification.js @@ -194,10 +194,7 @@ class Notification { let bean; if (notificationID) { - bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ - notificationID, - userID, - ]); + bean = await R.findOne("notification", " id = ? ", [ notificationID ]); if (! bean) { throw new Error("notification not found"); @@ -223,14 +220,10 @@ class Notification { /** * Delete a notification * @param {number} notificationID ID of notification to delete - * @param {number} userID ID of user who created notification * @returns {Promise} */ - static async delete(notificationID, userID) { - let bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ - notificationID, - userID, - ]); + static async delete(notificationID) { + let bean = await R.findOne("notification", " id = ? ", [ notificationID ]); if (! bean) { throw new Error("notification not found"); @@ -254,13 +247,10 @@ class Notification { /** * Apply the notification to every monitor * @param {number} notificationID ID of notification to apply - * @param {number} userID ID of user who created notification * @returns {Promise} */ -async function applyNotificationEveryMonitor(notificationID, userID) { - let monitors = await R.getAll("SELECT id FROM monitor WHERE user_id = ?", [ - userID - ]); +async function applyNotificationEveryMonitor(notificationID) { + let monitors = await R.getAll("SELECT id FROM monitor"); for (let i = 0; i < monitors.length; i++) { let checkNotification = await R.findOne("monitor_notification", " monitor_id = ? AND notification_id = ? ", [ diff --git a/server/proxy.js b/server/proxy.js index 3f3771ab..2100b3e9 100644 --- a/server/proxy.js +++ b/server/proxy.js @@ -22,7 +22,7 @@ class Proxy { let bean; if (proxyID) { - bean = await R.findOne("proxy", " id = ? AND user_id = ? ", [ proxyID, userID ]); + bean = await R.findOne("proxy", " id = ? ", [ proxyID ]); if (!bean) { throw new Error("proxy not found"); @@ -67,11 +67,10 @@ class Proxy { /** * Deletes proxy with given id and removes it from monitors * @param {number} proxyID ID of proxy to delete - * @param {number} userID ID of proxy owner * @returns {Promise} */ - static async delete(proxyID, userID) { - const bean = await R.findOne("proxy", " id = ? AND user_id = ? ", [ proxyID, userID ]); + static async delete(proxyID) { + const bean = await R.findOne("proxy", " id = ? ", [ proxyID ]); if (!bean) { throw new Error("proxy not found"); @@ -182,12 +181,11 @@ class Proxy { /** * Applies given proxy id to monitors * @param {number} proxyID ID of proxy to apply - * @param {number} userID ID of proxy owner * @returns {Promise} */ -async function applyProxyEveryMonitor(proxyID, userID) { +async function applyProxyEveryMonitor(proxyID) { // Find all monitors with id and proxy id - const monitors = await R.getAll("SELECT id, proxy_id FROM monitor WHERE user_id = ?", [ userID ]); + const monitors = await R.getAll("SELECT id, proxy_id FROM monitor"); // Update proxy id not match with given proxy id for (const monitor of monitors) { diff --git a/server/server.js b/server/server.js index db58ae82..009dffc3 100644 --- a/server/server.js +++ b/server/server.js @@ -761,10 +761,6 @@ let needSetup = false; let bean = await R.findOne("monitor", " id = ? ", [ monitor.id ]); - if (bean.user_id !== socket.userID) { - throw new Error("Permission denied."); - } - // Check if Parent is Descendant (would cause endless loop) if (monitor.parent !== null) { const childIDs = await Monitor.getAllChildrenIDs(monitor.id); @@ -924,10 +920,7 @@ let needSetup = false; log.info("monitor", `Get Monitor: ${monitorID} User ID: ${socket.userID}`); - let monitor = await R.findOne("monitor", " id = ? AND user_id = ? ", [ - monitorID, - socket.userID, - ]); + let monitor = await R.findOne("monitor", " id = ? ", [ monitorID ]); const monitorData = [{ id: monitor.id, active: monitor.active }]; @@ -1034,10 +1027,7 @@ let needSetup = false; const startTime = Date.now(); - await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [ - monitorID, - socket.userID, - ]); + await R.exec("DELETE FROM monitor WHERE id = ? ", [ monitorID ]); // Fix #2880 apicache.clear(); @@ -1638,24 +1628,6 @@ async function updateMonitorNotification(monitorID, notificationIDList) { } } -/** - * Check if a given user owns a specific monitor - * @param {number} userID ID of user to check - * @param {number} monitorID ID of monitor to check - * @returns {Promise} - * @throws {Error} The specified user does not own the monitor - */ -async function checkOwner(userID, monitorID) { - let row = await R.getRow("SELECT id FROM monitor WHERE id = ? AND user_id = ? ", [ - monitorID, - userID, - ]); - - if (! row) { - throw new Error("You do not own this monitor."); - } -} - /** * Function called after user login * This function is used to send the heartbeat list of a monitor. @@ -1739,14 +1711,9 @@ async function initDatabase(testMode = false) { * @returns {Promise} */ async function startMonitor(userID, monitorID) { - await checkOwner(userID, monitorID); - log.info("manage", `Resume Monitor: ${monitorID} User ID: ${userID}`); - await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [ - monitorID, - userID, - ]); + await R.exec("UPDATE monitor SET active = 1 WHERE id = ? ", [ monitorID ]); let monitor = await R.findOne("monitor", " id = ? ", [ monitorID, @@ -1777,14 +1744,9 @@ async function restartMonitor(userID, monitorID) { * @returns {Promise} */ async function pauseMonitor(userID, monitorID) { - await checkOwner(userID, monitorID); - log.info("manage", `Pause Monitor: ${monitorID} User ID: ${userID}`); - await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [ - monitorID, - userID, - ]); + await R.exec("UPDATE monitor SET active = 0 WHERE id = ? ", [ monitorID ]); if (monitorID in server.monitorList) { await server.monitorList[monitorID].stop(); diff --git a/server/socket-handlers/api-key-socket-handler.js b/server/socket-handlers/api-key-socket-handler.js index f76b9099..7c57d358 100644 --- a/server/socket-handlers/api-key-socket-handler.js +++ b/server/socket-handlers/api-key-socket-handler.js @@ -74,10 +74,7 @@ module.exports.apiKeySocketHandler = (socket) => { log.debug("apikeys", `Deleted API Key: ${keyID} User ID: ${socket.userID}`); - await R.exec("DELETE FROM api_key WHERE id = ? AND user_id = ? ", [ - keyID, - socket.userID, - ]); + await R.exec("DELETE FROM api_key WHERE id = ? ", [ keyID ]); apicache.clear(); diff --git a/server/socket-handlers/maintenance-socket-handler.js b/server/socket-handlers/maintenance-socket-handler.js index 7de13fe5..08681196 100644 --- a/server/socket-handlers/maintenance-socket-handler.js +++ b/server/socket-handlers/maintenance-socket-handler.js @@ -50,10 +50,6 @@ module.exports.maintenanceSocketHandler = (socket) => { let bean = server.getMaintenance(maintenance.id); - if (bean.user_id !== socket.userID) { - throw new Error("Permission denied."); - } - await Maintenance.jsonToBean(bean, maintenance); await R.store(bean); await bean.run(true); @@ -151,10 +147,7 @@ module.exports.maintenanceSocketHandler = (socket) => { log.debug("maintenance", `Get Maintenance: ${maintenanceID} User ID: ${socket.userID}`); - let bean = await R.findOne("maintenance", " id = ? AND user_id = ? ", [ - maintenanceID, - socket.userID, - ]); + let bean = await R.findOne("maintenance", " id = ? ", [ maintenanceID ]); callback({ ok: true, @@ -244,10 +237,7 @@ module.exports.maintenanceSocketHandler = (socket) => { delete server.maintenanceList[maintenanceID]; } - await R.exec("DELETE FROM maintenance WHERE id = ? AND user_id = ? ", [ - maintenanceID, - socket.userID, - ]); + await R.exec("DELETE FROM maintenance WHERE id = ? ", [ maintenanceID ]); apicache.clear(); diff --git a/server/uptime-kuma-server.js b/server/uptime-kuma-server.js index 76bf4256..13f6cb74 100644 --- a/server/uptime-kuma-server.js +++ b/server/uptime-kuma-server.js @@ -200,7 +200,7 @@ class UptimeKumaServer { * @returns {Promise} List of monitors */ async sendMonitorList(socket) { - let list = await this.getMonitorJSONList(socket.userID); + let list = await this.getMonitorJSONList(); this.io.to(socket.userID).emit("monitorList", list); return list; } @@ -227,25 +227,21 @@ class UptimeKumaServer { } /** - * Get a list of monitors for the given user. - * @param {string} userID - The ID of the user to get monitors for. + * Get a list of monitors. * @param {number} monitorID - The ID of monitor for. * @returns {Promise} A promise that resolves to an object with monitor IDs as keys and monitor objects as values. * * Generated by Trelent */ - async getMonitorJSONList(userID, monitorID = null) { - - let query = " user_id = ? "; - let queryParams = [ userID ]; + async getMonitorJSONList(monitorID = null) { + let monitorList = []; if (monitorID) { - query += "AND id = ? "; - queryParams.push(monitorID); + monitorList = await R.find("monitor", "id = ? ORDER BY weight DESC, name", [ monitorID ]); + } else { + monitorList = await R.findAll("monitor", "ORDER BY weight DESC, name"); } - let monitorList = await R.find("monitor", query + "ORDER BY weight DESC, name", queryParams); - const monitorData = monitorList.map(monitor => ({ id: monitor.id, active: monitor.active,