|  | @ -8,12 +8,12 @@ console.log("Node Env: " + process.env.NODE_ENV); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | const { sleep, debug, TimeLogger, getRandomInt } = require("../src/util"); |  |  | const { sleep, debug, TimeLogger, getRandomInt } = require("../src/util"); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | console.log("Importing Node libraries") |  |  | console.log("Importing Node libraries"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | const fs = require("fs"); |  |  | const fs = require("fs"); | 
			
		
	
		
		
			
				
					|  |  | const http = require("http"); |  |  | const http = require("http"); | 
			
		
	
		
		
			
				
					|  |  | const https = require("https"); |  |  | const https = require("https"); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | console.log("Importing 3rd-party libraries") |  |  | console.log("Importing 3rd-party libraries"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | debug("Importing express"); |  |  | debug("Importing express"); | 
			
		
	
		
		
			
				
					|  |  | const express = require("express"); |  |  | const express = require("express"); | 
			
		
	
		
		
			
				
					|  |  | debug("Importing socket.io"); |  |  | debug("Importing socket.io"); | 
			
		
	
	
		
		
			
				
					|  | @ -70,7 +70,7 @@ if (! fs.existsSync(Database.dataDir)) { | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | console.log(`Data Dir: ${Database.dataDir}`); |  |  | console.log(`Data Dir: ${Database.dataDir}`); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  | console.log("Creating express and socket.io instance") |  |  | console.log("Creating express and socket.io instance"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | const app = express(); |  |  | const app = express(); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | let server; |  |  | let server; | 
			
		
	
	
		
		
			
				
					|  | @ -157,6 +157,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     app.use("/", express.static("dist")); |  |  |     app.use("/", express.static("dist")); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     // ./data/upload
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     app.use("/upload", express.static(Database.uploadDir)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     app.get("/.well-known/change-password", async (_, response) => { |  |  |     app.get("/.well-known/change-password", async (_, response) => { | 
			
		
	
		
		
			
				
					|  |  |         response.redirect("https://github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI"); |  |  |         response.redirect("https://github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI"); | 
			
		
	
		
		
			
				
					|  |  |     }); |  |  |     }); | 
			
		
	
	
		
		
			
				
					|  | @ -167,22 +170,26 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Universal Route Handler, must be at the end of all express route.
 |  |  |     // Universal Route Handler, must be at the end of all express route.
 | 
			
		
	
		
		
			
				
					|  |  |     app.get("*", async (_request, response) => { |  |  |     app.get("*", async (_request, response) => { | 
			
		
	
		
		
			
				
					
					|  |  |         response.send(indexHTML); |  |  |         if (_request.originalUrl.startsWith("/upload/")) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             response.status(404).send("File not found."); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             response.send(indexHTML); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |     }); |  |  |     }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     console.log("Adding socket handler") |  |  |     console.log("Adding socket handler"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |     io.on("connection", async (socket) => { |  |  |     io.on("connection", async (socket) => { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.emit("info", { |  |  |         socket.emit("info", { | 
			
		
	
		
		
			
				
					|  |  |             version: checkVersion.version, |  |  |             version: checkVersion.version, | 
			
		
	
		
		
			
				
					|  |  |             latestVersion: checkVersion.latestVersion, |  |  |             latestVersion: checkVersion.latestVersion, | 
			
		
	
		
		
			
				
					
					|  |  |         }) |  |  |         }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         totalClient++; |  |  |         totalClient++; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         if (needSetup) { |  |  |         if (needSetup) { | 
			
		
	
		
		
			
				
					
					|  |  |             console.log("Redirect to setup page") |  |  |             console.log("Redirect to setup page"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             socket.emit("setup") |  |  |             socket.emit("setup"); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("disconnect", () => { |  |  |         socket.on("disconnect", () => { | 
			
		
	
	
		
		
			
				
					|  | @ -198,44 +205,44 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					|  |  |                 let decoded = jwt.verify(token, jwtSecret); |  |  |                 let decoded = jwt.verify(token, jwtSecret); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log("Username from JWT: " + decoded.username) |  |  |                 console.log("Username from JWT: " + decoded.username); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let user = await R.findOne("user", " username = ? AND active = 1 ", [ |  |  |                 let user = await R.findOne("user", " username = ? AND active = 1 ", [ | 
			
		
	
		
		
			
				
					|  |  |                     decoded.username, |  |  |                     decoded.username, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (user) { |  |  |                 if (user) { | 
			
		
	
		
		
			
				
					
					|  |  |                     debug("afterLogin") |  |  |                     debug("afterLogin"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                     afterLogin(socket, user) |  |  |                     afterLogin(socket, user); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                     debug("afterLogin ok") |  |  |                     debug("afterLogin ok"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: true, |  |  |                         ok: true, | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } else { |  |  |                 } else { | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: false, |  |  |                         ok: false, | 
			
		
	
		
		
			
				
					|  |  |                         msg: "The user is inactive or deleted.", |  |  |                         msg: "The user is inactive or deleted.", | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |             } catch (error) { |  |  |             } catch (error) { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Invalid token.", |  |  |                     msg: "Invalid token.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("login", async (data, callback) => { |  |  |         socket.on("login", async (data, callback) => { | 
			
		
	
		
		
			
				
					
					|  |  |             console.log("Login") |  |  |             console.log("Login"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             let user = await login(data.username, data.password) |  |  |             let user = await login(data.username, data.password); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             if (user) { |  |  |             if (user) { | 
			
		
	
		
		
			
				
					
					|  |  |                 afterLogin(socket, user) |  |  |                 afterLogin(socket, user); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (user.twofaStatus == 0) { |  |  |                 if (user.twofaStatus == 0) { | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
	
		
		
			
				
					|  | @ -243,13 +250,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                         token: jwt.sign({ |  |  |                         token: jwt.sign({ | 
			
		
	
		
		
			
				
					|  |  |                             username: data.username, |  |  |                             username: data.username, | 
			
		
	
		
		
			
				
					|  |  |                         }, jwtSecret), |  |  |                         }, jwtSecret), | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (user.twofaStatus == 1 && !data.token) { |  |  |                 if (user.twofaStatus == 1 && !data.token) { | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         tokenRequired: true, |  |  |                         tokenRequired: true, | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (data.token) { |  |  |                 if (data.token) { | 
			
		
	
	
		
		
			
				
					|  | @ -261,39 +268,39 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                             token: jwt.sign({ |  |  |                             token: jwt.sign({ | 
			
		
	
		
		
			
				
					|  |  |                                 username: data.username, |  |  |                                 username: data.username, | 
			
		
	
		
		
			
				
					|  |  |                             }, jwtSecret), |  |  |                             }, jwtSecret), | 
			
		
	
		
		
			
				
					
					|  |  |                         }) |  |  |                         }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                     } else { |  |  |                     } else { | 
			
		
	
		
		
			
				
					|  |  |                         callback({ |  |  |                         callback({ | 
			
		
	
		
		
			
				
					|  |  |                             ok: false, |  |  |                             ok: false, | 
			
		
	
		
		
			
				
					|  |  |                             msg: "Invalid Token!", |  |  |                             msg: "Invalid Token!", | 
			
		
	
		
		
			
				
					
					|  |  |                         }) |  |  |                         }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                     } |  |  |                     } | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |             } else { |  |  |             } else { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Incorrect username or password.", |  |  |                     msg: "Incorrect username or password.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("logout", async (callback) => { |  |  |         socket.on("logout", async (callback) => { | 
			
		
	
		
		
			
				
					
					|  |  |             socket.leave(socket.userID) |  |  |             socket.leave(socket.userID); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             socket.userID = null; |  |  |             socket.userID = null; | 
			
		
	
		
		
			
				
					|  |  |             callback(); |  |  |             callback(); | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("prepare2FA", async (callback) => { |  |  |         socket.on("prepare2FA", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let user = await R.findOne("user", " id = ? AND active = 1 ", [ |  |  |                 let user = await R.findOne("user", " id = ? AND active = 1 ", [ | 
			
		
	
		
		
			
				
					|  |  |                     socket.userID, |  |  |                     socket.userID, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (user.twofa_status == 0) { |  |  |                 if (user.twofa_status == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |                     let newSecret = await genSecret() |  |  |                     let newSecret = await genSecret(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                     let encodedSecret = base32.encode(newSecret); |  |  |                     let encodedSecret = base32.encode(newSecret); | 
			
		
	
		
		
			
				
					|  |  |                     let uri = `otpauth://totp/Uptime%20Kuma:${user.username}?secret=${encodedSecret}`; |  |  |                     let uri = `otpauth://totp/Uptime%20Kuma:${user.username}?secret=${encodedSecret}`; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -305,24 +312,24 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: true, |  |  |                         ok: true, | 
			
		
	
		
		
			
				
					|  |  |                         uri: uri, |  |  |                         uri: uri, | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } else { |  |  |                 } else { | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: false, |  |  |                         ok: false, | 
			
		
	
		
		
			
				
					|  |  |                         msg: "2FA is already enabled.", |  |  |                         msg: "2FA is already enabled.", | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |             } catch (error) { |  |  |             } catch (error) { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Error while trying to prepare 2FA.", |  |  |                     msg: "Error while trying to prepare 2FA.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("save2FA", async (callback) => { |  |  |         socket.on("save2FA", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("UPDATE `user` SET twofa_status = 1 WHERE id = ? ", [ |  |  |                 await R.exec("UPDATE `user` SET twofa_status = 1 WHERE id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |                     socket.userID, |  |  |                     socket.userID, | 
			
		
	
	
		
		
			
				
					|  | @ -331,18 +338,18 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "2FA Enabled.", |  |  |                     msg: "2FA Enabled.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } catch (error) { |  |  |             } catch (error) { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Error while trying to change 2FA.", |  |  |                     msg: "Error while trying to change 2FA.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("disable2FA", async (callback) => { |  |  |         socket.on("disable2FA", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("UPDATE `user` SET twofa_status = 0 WHERE id = ? ", [ |  |  |                 await R.exec("UPDATE `user` SET twofa_status = 0 WHERE id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |                     socket.userID, |  |  |                     socket.userID, | 
			
		
	
	
		
		
			
				
					|  | @ -351,19 +358,19 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "2FA Disabled.", |  |  |                     msg: "2FA Disabled.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } catch (error) { |  |  |             } catch (error) { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Error while trying to change 2FA.", |  |  |                     msg: "Error while trying to change 2FA.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("verifyToken", async (token, callback) => { |  |  |         socket.on("verifyToken", async (token, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             let user = await R.findOne("user", " id = ? AND active = 1 ", [ |  |  |             let user = await R.findOne("user", " id = ? AND active = 1 ", [ | 
			
		
	
		
		
			
				
					|  |  |                 socket.userID, |  |  |                 socket.userID, | 
			
		
	
		
		
			
				
					
					|  |  |             ]) |  |  |             ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             let verify = notp.totp.verify(token, user.twofa_secret); |  |  |             let verify = notp.totp.verify(token, user.twofa_secret); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -371,40 +378,40 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
		
		
			
				
					|  |  |                     valid: true, |  |  |                     valid: true, | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } else { |  |  |             } else { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Invalid Token.", |  |  |                     msg: "Invalid Token.", | 
			
		
	
		
		
			
				
					|  |  |                     valid: false, |  |  |                     valid: false, | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("twoFAStatus", async (callback) => { |  |  |         socket.on("twoFAStatus", async (callback) => { | 
			
		
	
		
		
			
				
					
					|  |  |             checkLogin(socket) |  |  |             checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					|  |  |                 let user = await R.findOne("user", " id = ? AND active = 1 ", [ |  |  |                 let user = await R.findOne("user", " id = ? AND active = 1 ", [ | 
			
		
	
		
		
			
				
					|  |  |                     socket.userID, |  |  |                     socket.userID, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (user.twofa_status == 1) { |  |  |                 if (user.twofa_status == 1) { | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: true, |  |  |                         ok: true, | 
			
		
	
		
		
			
				
					|  |  |                         status: true, |  |  |                         status: true, | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } else { |  |  |                 } else { | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: true, |  |  |                         ok: true, | 
			
		
	
		
		
			
				
					|  |  |                         status: false, |  |  |                         status: false, | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |             } catch (error) { |  |  |             } catch (error) { | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: "Error while trying to get 2FA status.", |  |  |                     msg: "Error while trying to get 2FA status.", | 
			
		
	
		
		
			
				
					
					|  |  |                 }) |  |  |                 }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |         }); |  |  |         }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -415,13 +422,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |         socket.on("setup", async (username, password, callback) => { |  |  |         socket.on("setup", async (username, password, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					|  |  |                 if ((await R.count("user")) !== 0) { |  |  |                 if ((await R.count("user")) !== 0) { | 
			
		
	
		
		
			
				
					
					|  |  |                     throw new Error("Uptime Kuma has been setup. If you want to setup again, please delete the database.") |  |  |                     throw new Error("Uptime Kuma has been setup. If you want to setup again, please delete the database."); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 let user = R.dispense("user") |  |  |                 let user = R.dispense("user"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 user.username = username; |  |  |                 user.username = username; | 
			
		
	
		
		
			
				
					
					|  |  |                 user.password = passwordHash.generate(password) |  |  |                 user.password = passwordHash.generate(password); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await R.store(user) |  |  |                 await R.store(user); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 needSetup = false; |  |  |                 needSetup = false; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -445,8 +452,8 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |         // Add a new monitor
 |  |  |         // Add a new monitor
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("add", async (monitor, callback) => { |  |  |         socket.on("add", async (monitor, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 let bean = R.dispense("monitor") |  |  |                 let bean = R.dispense("monitor"); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let notificationIDList = monitor.notificationIDList; |  |  |                 let notificationIDList = monitor.notificationIDList; | 
			
		
	
		
		
			
				
					|  |  |                 delete monitor.notificationIDList; |  |  |                 delete monitor.notificationIDList; | 
			
		
	
	
		
		
			
				
					|  | @ -454,11 +461,11 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); |  |  |                 monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); | 
			
		
	
		
		
			
				
					|  |  |                 delete monitor.accepted_statuscodes; |  |  |                 delete monitor.accepted_statuscodes; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 bean.import(monitor) |  |  |                 bean.import(monitor); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.user_id = socket.userID |  |  |                 bean.user_id = socket.userID; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await R.store(bean) |  |  |                 await R.store(bean); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 await updateMonitorNotification(bean.id, notificationIDList) |  |  |                 await updateMonitorNotification(bean.id, notificationIDList); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await startMonitor(socket.userID, bean.id); |  |  |                 await startMonitor(socket.userID, bean.id); | 
			
		
	
		
		
			
				
					|  |  |                 await sendMonitorList(socket); |  |  |                 await sendMonitorList(socket); | 
			
		
	
	
		
		
			
				
					|  | @ -480,18 +487,18 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |         // Edit a monitor
 |  |  |         // Edit a monitor
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("editMonitor", async (monitor, callback) => { |  |  |         socket.on("editMonitor", async (monitor, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 let bean = await R.findOne("monitor", " id = ? ", [ monitor.id ]) |  |  |                 let bean = await R.findOne("monitor", " id = ? ", [ monitor.id ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (bean.user_id !== socket.userID) { |  |  |                 if (bean.user_id !== socket.userID) { | 
			
		
	
		
		
			
				
					
					|  |  |                     throw new Error("Permission denied.") |  |  |                     throw new Error("Permission denied."); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 bean.name = monitor.name |  |  |                 bean.name = monitor.name; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.type = monitor.type |  |  |                 bean.type = monitor.type; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.url = monitor.url |  |  |                 bean.url = monitor.url; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.interval = monitor.interval |  |  |                 bean.interval = monitor.interval; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                 bean.retryInterval = monitor.retryInterval; |  |  |                 bean.retryInterval = monitor.retryInterval; | 
			
		
	
		
		
			
				
					|  |  |                 bean.hostname = monitor.hostname; |  |  |                 bean.hostname = monitor.hostname; | 
			
		
	
		
		
			
				
					|  |  |                 bean.maxretries = monitor.maxretries; |  |  |                 bean.maxretries = monitor.maxretries; | 
			
		
	
	
		
		
			
				
					|  | @ -504,12 +511,12 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 bean.dns_resolve_type = monitor.dns_resolve_type; |  |  |                 bean.dns_resolve_type = monitor.dns_resolve_type; | 
			
		
	
		
		
			
				
					|  |  |                 bean.dns_resolve_server = monitor.dns_resolve_server; |  |  |                 bean.dns_resolve_server = monitor.dns_resolve_server; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 await R.store(bean) |  |  |                 await R.store(bean); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 await updateMonitorNotification(bean.id, monitor.notificationIDList) |  |  |                 await updateMonitorNotification(bean.id, monitor.notificationIDList); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (bean.active) { |  |  |                 if (bean.active) { | 
			
		
	
		
		
			
				
					
					|  |  |                     await restartMonitor(socket.userID, bean.id) |  |  |                     await restartMonitor(socket.userID, bean.id); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await sendMonitorList(socket); |  |  |                 await sendMonitorList(socket); | 
			
		
	
	
		
		
			
				
					|  | @ -521,7 +528,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 }); |  |  |                 }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             } catch (e) { |  |  |             } catch (e) { | 
			
		
	
		
		
			
				
					
					|  |  |                 console.error(e) |  |  |                 console.error(e); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: e.message, |  |  |                     msg: e.message, | 
			
		
	
	
		
		
			
				
					|  | @ -531,13 +538,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("getMonitorList", async (callback) => { |  |  |         socket.on("getMonitorList", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 await sendMonitorList(socket); |  |  |                 await sendMonitorList(socket); | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
		
		
			
				
					|  |  |                 }); |  |  |                 }); | 
			
		
	
		
		
			
				
					|  |  |             } catch (e) { |  |  |             } catch (e) { | 
			
		
	
		
		
			
				
					
					|  |  |                 console.error(e) |  |  |                 console.error(e); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
		
		
			
				
					|  |  |                     msg: e.message, |  |  |                     msg: e.message, | 
			
		
	
	
		
		
			
				
					|  | @ -547,14 +554,14 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("getMonitor", async (monitorID, callback) => { |  |  |         socket.on("getMonitor", async (monitorID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Get Monitor: ${monitorID} User ID: ${socket.userID}`) |  |  |                 console.log(`Get Monitor: ${monitorID} User ID: ${socket.userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let bean = await R.findOne("monitor", " id = ? AND user_id = ? ", [ |  |  |                 let bean = await R.findOne("monitor", " id = ? AND user_id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |                     monitorID, |  |  |                     monitorID, | 
			
		
	
		
		
			
				
					|  |  |                     socket.userID, |  |  |                     socket.userID, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -572,7 +579,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |         // Start or Resume the monitor
 |  |  |         // Start or Resume the monitor
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("resumeMonitor", async (monitorID, callback) => { |  |  |         socket.on("resumeMonitor", async (monitorID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 await startMonitor(socket.userID, monitorID); |  |  |                 await startMonitor(socket.userID, monitorID); | 
			
		
	
		
		
			
				
					|  |  |                 await sendMonitorList(socket); |  |  |                 await sendMonitorList(socket); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -591,8 +598,8 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("pauseMonitor", async (monitorID, callback) => { |  |  |         socket.on("pauseMonitor", async (monitorID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await pauseMonitor(socket.userID, monitorID) |  |  |                 await pauseMonitor(socket.userID, monitorID); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                 await sendMonitorList(socket); |  |  |                 await sendMonitorList(socket); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
	
		
		
			
				
					|  | @ -610,13 +617,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("deleteMonitor", async (monitorID, callback) => { |  |  |         socket.on("deleteMonitor", async (monitorID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Delete Monitor: ${monitorID} User ID: ${socket.userID}`) |  |  |                 console.log(`Delete Monitor: ${monitorID} User ID: ${socket.userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (monitorID in monitorList) { |  |  |                 if (monitorID in monitorList) { | 
			
		
	
		
		
			
				
					|  |  |                     monitorList[monitorID].stop(); |  |  |                     monitorList[monitorID].stop(); | 
			
		
	
		
		
			
				
					
					|  |  |                     delete monitorList[monitorID] |  |  |                     delete monitorList[monitorID]; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [ |  |  |                 await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [ | 
			
		
	
	
		
		
			
				
					|  | @ -641,9 +648,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("getTags", async (callback) => { |  |  |         socket.on("getTags", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 const list = await R.findAll("tag") |  |  |                 const list = await R.findAll("tag"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -660,12 +667,12 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("addTag", async (tag, callback) => { |  |  |         socket.on("addTag", async (tag, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 let bean = R.dispense("tag") |  |  |                 let bean = R.dispense("tag"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.name = tag.name |  |  |                 bean.name = tag.name; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.color = tag.color |  |  |                 bean.color = tag.color; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await R.store(bean) |  |  |                 await R.store(bean); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -682,12 +689,12 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("editTag", async (tag, callback) => { |  |  |         socket.on("editTag", async (tag, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 let bean = await R.findOne("monitor", " id = ? ", [ tag.id ]) |  |  |                 let bean = await R.findOne("monitor", " id = ? ", [ tag.id ]); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.name = tag.name |  |  |                 bean.name = tag.name; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 bean.color = tag.color |  |  |                 bean.color = tag.color; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await R.store(bean) |  |  |                 await R.store(bean); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -704,9 +711,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("deleteTag", async (tagID, callback) => { |  |  |         socket.on("deleteTag", async (tagID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 await R.exec("DELETE FROM tag WHERE id = ? ", [ tagID ]) |  |  |                 await R.exec("DELETE FROM tag WHERE id = ? ", [ tagID ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -723,13 +730,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("addMonitorTag", async (tagID, monitorID, value, callback) => { |  |  |         socket.on("addMonitorTag", async (tagID, monitorID, value, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("INSERT INTO monitor_tag (tag_id, monitor_id, value) VALUES (?, ?, ?)", [ |  |  |                 await R.exec("INSERT INTO monitor_tag (tag_id, monitor_id, value) VALUES (?, ?, ?)", [ | 
			
		
	
		
		
			
				
					|  |  |                     tagID, |  |  |                     tagID, | 
			
		
	
		
		
			
				
					|  |  |                     monitorID, |  |  |                     monitorID, | 
			
		
	
		
		
			
				
					|  |  |                     value, |  |  |                     value, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -746,13 +753,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("editMonitorTag", async (tagID, monitorID, value, callback) => { |  |  |         socket.on("editMonitorTag", async (tagID, monitorID, value, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("UPDATE monitor_tag SET value = ? WHERE tag_id = ? AND monitor_id = ?", [ |  |  |                 await R.exec("UPDATE monitor_tag SET value = ? WHERE tag_id = ? AND monitor_id = ?", [ | 
			
		
	
		
		
			
				
					|  |  |                     value, |  |  |                     value, | 
			
		
	
		
		
			
				
					|  |  |                     tagID, |  |  |                     tagID, | 
			
		
	
		
		
			
				
					|  |  |                     monitorID, |  |  |                     monitorID, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -769,13 +776,13 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("deleteMonitorTag", async (tagID, monitorID, value, callback) => { |  |  |         socket.on("deleteMonitorTag", async (tagID, monitorID, value, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("DELETE FROM monitor_tag WHERE tag_id = ? AND monitor_id = ? AND value = ?", [ |  |  |                 await R.exec("DELETE FROM monitor_tag WHERE tag_id = ? AND monitor_id = ? AND value = ?", [ | 
			
		
	
		
		
			
				
					|  |  |                     tagID, |  |  |                     tagID, | 
			
		
	
		
		
			
				
					|  |  |                     monitorID, |  |  |                     monitorID, | 
			
		
	
		
		
			
				
					|  |  |                     value, |  |  |                     value, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 // Cleanup unused Tags
 |  |  |                 // Cleanup unused Tags
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("delete from tag where ( select count(*) from monitor_tag mt where tag.id = mt.tag_id ) = 0"); |  |  |                 await R.exec("delete from tag where ( select count(*) from monitor_tag mt where tag.id = mt.tag_id ) = 0"); | 
			
		
	
	
		
		
			
				
					|  | @ -795,15 +802,15 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("changePassword", async (password, callback) => { |  |  |         socket.on("changePassword", async (password, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (! password.currentPassword) { |  |  |                 if (! password.currentPassword) { | 
			
		
	
		
		
			
				
					
					|  |  |                     throw new Error("Invalid new password") |  |  |                     throw new Error("Invalid new password"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let user = await R.findOne("user", " id = ? AND active = 1 ", [ |  |  |                 let user = await R.findOne("user", " id = ? AND active = 1 ", [ | 
			
		
	
		
		
			
				
					|  |  |                     socket.userID, |  |  |                     socket.userID, | 
			
		
	
		
		
			
				
					
					|  |  |                 ]) |  |  |                 ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (user && passwordHash.verify(password.currentPassword, user.password)) { |  |  |                 if (user && passwordHash.verify(password.currentPassword, user.password)) { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -812,9 +819,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                     callback({ |  |  |                     callback({ | 
			
		
	
		
		
			
				
					|  |  |                         ok: true, |  |  |                         ok: true, | 
			
		
	
		
		
			
				
					|  |  |                         msg: "Password has been updated successfully.", |  |  |                         msg: "Password has been updated successfully.", | 
			
		
	
		
		
			
				
					
					|  |  |                     }) |  |  |                     }); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } else { |  |  |                 } else { | 
			
		
	
		
		
			
				
					
					|  |  |                     throw new Error("Incorrect current password") |  |  |                     throw new Error("Incorrect current password"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             } catch (e) { |  |  |             } catch (e) { | 
			
		
	
	
		
		
			
				
					|  | @ -827,7 +834,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("getSettings", async (callback) => { |  |  |         socket.on("getSettings", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -844,7 +851,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("setSettings", async (data, callback) => { |  |  |         socket.on("setSettings", async (data, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await setSettings("general", data); |  |  |                 await setSettings("general", data); | 
			
		
	
		
		
			
				
					|  |  |                 exports.entryPage = data.entryPage; |  |  |                 exports.entryPage = data.entryPage; | 
			
		
	
	
		
		
			
				
					|  | @ -865,10 +872,10 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |         // Add or Edit
 |  |  |         // Add or Edit
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("addNotification", async (notification, notificationID, callback) => { |  |  |         socket.on("addNotification", async (notification, notificationID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 let notificationBean = await Notification.save(notification, notificationID, socket.userID) |  |  |                 let notificationBean = await Notification.save(notification, notificationID, socket.userID); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await sendNotificationList(socket) |  |  |                 await sendNotificationList(socket); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -886,10 +893,10 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("deleteNotification", async (notificationID, callback) => { |  |  |         socket.on("deleteNotification", async (notificationID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 await Notification.delete(notificationID, socket.userID) |  |  |                 await Notification.delete(notificationID, socket.userID); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 await sendNotificationList(socket) |  |  |                 await sendNotificationList(socket); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -906,9 +913,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("testNotification", async (notification, callback) => { |  |  |         socket.on("testNotification", async (notification, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 let msg = await Notification.send(notification, notification.name + " Testing") |  |  |                 let msg = await Notification.send(notification, notification.name + " Testing"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: true, |  |  |                     ok: true, | 
			
		
	
	
		
		
			
				
					|  | @ -916,7 +923,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                 }); |  |  |                 }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             } catch (e) { |  |  |             } catch (e) { | 
			
		
	
		
		
			
				
					
					|  |  |                 console.error(e) |  |  |                 console.error(e); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 callback({ |  |  |                 callback({ | 
			
		
	
		
		
			
				
					|  |  |                     ok: false, |  |  |                     ok: false, | 
			
		
	
	
		
		
			
				
					|  | @ -927,7 +934,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("checkApprise", async (callback) => { |  |  |         socket.on("checkApprise", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 callback(Notification.checkApprise()); |  |  |                 callback(Notification.checkApprise()); | 
			
		
	
		
		
			
				
					|  |  |             } catch (e) { |  |  |             } catch (e) { | 
			
		
	
		
		
			
				
					|  |  |                 callback(false); |  |  |                 callback(false); | 
			
		
	
	
		
		
			
				
					|  | @ -936,19 +943,19 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("uploadBackup", async (uploadedJSON, importHandle, callback) => { |  |  |         socket.on("uploadBackup", async (uploadedJSON, importHandle, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let backupData = JSON.parse(uploadedJSON); |  |  |                 let backupData = JSON.parse(uploadedJSON); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`) |  |  |                 console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let notificationListData = backupData.notificationList; |  |  |                 let notificationListData = backupData.notificationList; | 
			
		
	
		
		
			
				
					|  |  |                 let monitorListData = backupData.monitorList; |  |  |                 let monitorListData = backupData.monitorList; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (importHandle == "overwrite") { |  |  |                 if (importHandle == "overwrite") { | 
			
		
	
		
		
			
				
					|  |  |                     for (let id in monitorList) { |  |  |                     for (let id in monitorList) { | 
			
		
	
		
		
			
				
					
					|  |  |                         let monitor = monitorList[id] |  |  |                         let monitor = monitorList[id]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                         await monitor.stop() |  |  |                         await monitor.stop(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                     } |  |  |                     } | 
			
		
	
		
		
			
				
					|  |  |                     await R.exec("DELETE FROM heartbeat"); |  |  |                     await R.exec("DELETE FROM heartbeat"); | 
			
		
	
		
		
			
				
					|  |  |                     await R.exec("DELETE FROM monitor_notification"); |  |  |                     await R.exec("DELETE FROM monitor_notification"); | 
			
		
	
	
		
		
			
				
					|  | @ -965,7 +972,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                         if ((importHandle == "skip" && notificationNameListString.includes(notificationListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { |  |  |                         if ((importHandle == "skip" && notificationNameListString.includes(notificationListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                             let notification = JSON.parse(notificationListData[i].config); |  |  |                             let notification = JSON.parse(notificationListData[i].config); | 
			
		
	
		
		
			
				
					
					|  |  |                             await Notification.save(notification, null, socket.userID) |  |  |                             await Notification.save(notification, null, socket.userID); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                         } |  |  |                         } | 
			
		
	
		
		
			
				
					|  |  |                     } |  |  |                     } | 
			
		
	
	
		
		
			
				
					|  | @ -994,9 +1001,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                                 dns_resolve_type: monitorListData[i].dns_resolve_type, |  |  |                                 dns_resolve_type: monitorListData[i].dns_resolve_type, | 
			
		
	
		
		
			
				
					|  |  |                                 dns_resolve_server: monitorListData[i].dns_resolve_server, |  |  |                                 dns_resolve_server: monitorListData[i].dns_resolve_server, | 
			
		
	
		
		
			
				
					|  |  |                                 notificationIDList: {}, |  |  |                                 notificationIDList: {}, | 
			
		
	
		
		
			
				
					
					|  |  |                             } |  |  |                             }; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                             let bean = R.dispense("monitor") |  |  |                             let bean = R.dispense("monitor"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                             let notificationIDList = monitor.notificationIDList; |  |  |                             let notificationIDList = monitor.notificationIDList; | 
			
		
	
		
		
			
				
					|  |  |                             delete monitor.notificationIDList; |  |  |                             delete monitor.notificationIDList; | 
			
		
	
	
		
		
			
				
					|  | @ -1004,11 +1011,11 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                             monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); |  |  |                             monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); | 
			
		
	
		
		
			
				
					|  |  |                             delete monitor.accepted_statuscodes; |  |  |                             delete monitor.accepted_statuscodes; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                             bean.import(monitor) |  |  |                             bean.import(monitor); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                             bean.user_id = socket.userID |  |  |                             bean.user_id = socket.userID; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                             await R.store(bean) |  |  |                             await R.store(bean); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                             await updateMonitorNotification(bean.id, notificationIDList) |  |  |                             await updateMonitorNotification(bean.id, notificationIDList); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                             if (monitorListData[i].active == 1) { |  |  |                             if (monitorListData[i].active == 1) { | 
			
		
	
		
		
			
				
					|  |  |                                 await startMonitor(socket.userID, bean.id); |  |  |                                 await startMonitor(socket.userID, bean.id); | 
			
		
	
	
		
		
			
				
					|  | @ -1019,7 +1026,7 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                         } |  |  |                         } | 
			
		
	
		
		
			
				
					|  |  |                     } |  |  |                     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                     await sendNotificationList(socket) |  |  |                     await sendNotificationList(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                     await sendMonitorList(socket); |  |  |                     await sendMonitorList(socket); | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -1038,9 +1045,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("clearEvents", async (monitorID, callback) => { |  |  |         socket.on("clearEvents", async (monitorID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`) |  |  |                 console.log(`Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("UPDATE heartbeat SET msg = ?, important = ? WHERE monitor_id = ? ", [ |  |  |                 await R.exec("UPDATE heartbeat SET msg = ?, important = ? WHERE monitor_id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |                     "", |  |  |                     "", | 
			
		
	
	
		
		
			
				
					|  | @ -1064,9 +1071,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("clearHeartbeats", async (monitorID, callback) => { |  |  |         socket.on("clearHeartbeats", async (monitorID, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`) |  |  |                 console.log(`Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("DELETE FROM heartbeat WHERE monitor_id = ?", [ |  |  |                 await R.exec("DELETE FROM heartbeat WHERE monitor_id = ?", [ | 
			
		
	
		
		
			
				
					|  |  |                     monitorID |  |  |                     monitorID | 
			
		
	
	
		
		
			
				
					|  | @ -1088,9 +1095,9 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("clearStatistics", async (callback) => { |  |  |         socket.on("clearStatistics", async (callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket) |  |  |                 checkLogin(socket); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Clear Statistics User ID: ${socket.userID}`) |  |  |                 console.log(`Clear Statistics User ID: ${socket.userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 await R.exec("DELETE FROM heartbeat"); |  |  |                 await R.exec("DELETE FROM heartbeat"); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -1115,18 +1122,18 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |         // Better do anything after added all socket handlers here
 |  |  |         // Better do anything after added all socket handlers here
 | 
			
		
	
		
		
			
				
					|  |  |         // ***************************
 |  |  |         // ***************************
 | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |         debug("check auto login") |  |  |         debug("check auto login"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         if (await setting("disableAuth")) { |  |  |         if (await setting("disableAuth")) { | 
			
		
	
		
		
			
				
					
					|  |  |             console.log("Disabled Auth: auto login to admin") |  |  |             console.log("Disabled Auth: auto login to admin"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             afterLogin(socket, await R.findOne("user")) |  |  |             afterLogin(socket, await R.findOne("user")); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             socket.emit("autoLogin") |  |  |             socket.emit("autoLogin"); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |         } else { |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |             debug("need auth") |  |  |             debug("need auth"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     }); |  |  |     }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     console.log("Init the server") |  |  |     console.log("Init the server"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     server.once("error", async (err) => { |  |  |     server.once("error", async (err) => { | 
			
		
	
		
		
			
				
					|  |  |         console.error("Cannot listen: " + err.message); |  |  |         console.error("Cannot listen: " + err.message); | 
			
		
	
	
		
		
			
				
					|  | @ -1148,14 +1155,14 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | async function updateMonitorNotification(monitorID, notificationIDList) { |  |  | async function updateMonitorNotification(monitorID, notificationIDList) { | 
			
		
	
		
		
			
				
					|  |  |     await R.exec("DELETE FROM monitor_notification WHERE monitor_id = ? ", [ |  |  |     await R.exec("DELETE FROM monitor_notification WHERE monitor_id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |         monitorID, |  |  |         monitorID, | 
			
		
	
		
		
			
				
					
					|  |  |     ]) |  |  |     ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     for (let notificationID in notificationIDList) { |  |  |     for (let notificationID in notificationIDList) { | 
			
		
	
		
		
			
				
					|  |  |         if (notificationIDList[notificationID]) { |  |  |         if (notificationIDList[notificationID]) { | 
			
		
	
		
		
			
				
					|  |  |             let relation = R.dispense("monitor_notification"); |  |  |             let relation = R.dispense("monitor_notification"); | 
			
		
	
		
		
			
				
					|  |  |             relation.monitor_id = monitorID; |  |  |             relation.monitor_id = monitorID; | 
			
		
	
		
		
			
				
					|  |  |             relation.notification_id = notificationID; |  |  |             relation.notification_id = notificationID; | 
			
		
	
		
		
			
				
					
					|  |  |             await R.store(relation) |  |  |             await R.store(relation); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
	
		
		
			
				
					|  | @ -1164,7 +1171,7 @@ async function checkOwner(userID, monitorID) { | 
			
		
	
		
		
			
				
					|  |  |     let row = await R.getRow("SELECT id FROM monitor WHERE id = ? AND user_id = ? ", [ |  |  |     let row = await R.getRow("SELECT id FROM monitor WHERE id = ? AND user_id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |         monitorID, |  |  |         monitorID, | 
			
		
	
		
		
			
				
					|  |  |         userID, |  |  |         userID, | 
			
		
	
		
		
			
				
					
					|  |  |     ]) |  |  |     ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     if (! row) { |  |  |     if (! row) { | 
			
		
	
		
		
			
				
					|  |  |         throw new Error("You do not own this monitor."); |  |  |         throw new Error("You do not own this monitor."); | 
			
		
	
	
		
		
			
				
					|  | @ -1173,16 +1180,16 @@ async function checkOwner(userID, monitorID) { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | async function sendMonitorList(socket) { |  |  | async function sendMonitorList(socket) { | 
			
		
	
		
		
			
				
					|  |  |     let list = await getMonitorJSONList(socket.userID); |  |  |     let list = await getMonitorJSONList(socket.userID); | 
			
		
	
		
		
			
				
					
					|  |  |     io.to(socket.userID).emit("monitorList", list) |  |  |     io.to(socket.userID).emit("monitorList", list); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |     return list; |  |  |     return list; | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | async function afterLogin(socket, user) { |  |  | async function afterLogin(socket, user) { | 
			
		
	
		
		
			
				
					|  |  |     socket.userID = user.id; |  |  |     socket.userID = user.id; | 
			
		
	
		
		
			
				
					
					|  |  |     socket.join(user.id) |  |  |     socket.join(user.id); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     let monitorList = await sendMonitorList(socket) |  |  |     let monitorList = await sendMonitorList(socket); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     sendNotificationList(socket) |  |  |     sendNotificationList(socket); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     await sleep(500); |  |  |     await sleep(500); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -1195,7 +1202,7 @@ async function afterLogin(socket, user) { | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     for (let monitorID in monitorList) { |  |  |     for (let monitorID in monitorList) { | 
			
		
	
		
		
			
				
					
					|  |  |         await Monitor.sendStats(io, monitorID, user.id) |  |  |         await Monitor.sendStats(io, monitorID, user.id); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -1204,7 +1211,7 @@ async function getMonitorJSONList(userID) { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     let monitorList = await R.find("monitor", " user_id = ? ORDER BY weight DESC, name", [ |  |  |     let monitorList = await R.find("monitor", " user_id = ? ORDER BY weight DESC, name", [ | 
			
		
	
		
		
			
				
					|  |  |         userID, |  |  |         userID, | 
			
		
	
		
		
			
				
					
					|  |  |     ]) |  |  |     ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     for (let monitor of monitorList) { |  |  |     for (let monitor of monitorList) { | 
			
		
	
		
		
			
				
					|  |  |         result[monitor.id] = await monitor.toJSON(); |  |  |         result[monitor.id] = await monitor.toJSON(); | 
			
		
	
	
		
		
			
				
					|  | @ -1215,16 +1222,16 @@ async function getMonitorJSONList(userID) { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | async function initDatabase() { |  |  | async function initDatabase() { | 
			
		
	
		
		
			
				
					|  |  |     if (! fs.existsSync(Database.path)) { |  |  |     if (! fs.existsSync(Database.path)) { | 
			
		
	
		
		
			
				
					
					|  |  |         console.log("Copying Database") |  |  |         console.log("Copying Database"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         fs.copyFileSync(Database.templatePath, Database.path); |  |  |         fs.copyFileSync(Database.templatePath, Database.path); | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     console.log("Connecting to Database") |  |  |     console.log("Connecting to Database"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |     await Database.connect(); |  |  |     await Database.connect(); | 
			
		
	
		
		
			
				
					
					|  |  |     console.log("Connected") |  |  |     console.log("Connected"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // Patch the database
 |  |  |     // Patch the database
 | 
			
		
	
		
		
			
				
					
					|  |  |     await Database.patch() |  |  |     await Database.patch(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     let jwtSecretBean = await R.findOne("setting", " `key` = ? ", [ |  |  |     let jwtSecretBean = await R.findOne("setting", " `key` = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |         "jwtSecret", |  |  |         "jwtSecret", | 
			
		
	
	
		
		
			
				
					|  | @ -1240,7 +1247,7 @@ async function initDatabase() { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     // If there is no record in user table, it is a new Uptime Kuma instance, need to setup
 |  |  |     // If there is no record in user table, it is a new Uptime Kuma instance, need to setup
 | 
			
		
	
		
		
			
				
					|  |  |     if ((await R.count("user")) === 0) { |  |  |     if ((await R.count("user")) === 0) { | 
			
		
	
		
		
			
				
					
					|  |  |         console.log("No user, need setup") |  |  |         console.log("No user, need setup"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         needSetup = true; |  |  |         needSetup = true; | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -1248,9 +1255,9 @@ async function initDatabase() { | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | async function startMonitor(userID, monitorID) { |  |  | async function startMonitor(userID, monitorID) { | 
			
		
	
		
		
			
				
					
					|  |  |     await checkOwner(userID, monitorID) |  |  |     await checkOwner(userID, monitorID); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     console.log(`Resume Monitor: ${monitorID} User ID: ${userID}`) |  |  |     console.log(`Resume Monitor: ${monitorID} User ID: ${userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [ |  |  |     await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |         monitorID, |  |  |         monitorID, | 
			
		
	
	
		
		
			
				
					|  | @ -1259,24 +1266,24 @@ async function startMonitor(userID, monitorID) { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     let monitor = await R.findOne("monitor", " id = ? ", [ |  |  |     let monitor = await R.findOne("monitor", " id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |         monitorID, |  |  |         monitorID, | 
			
		
	
		
		
			
				
					
					|  |  |     ]) |  |  |     ]); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     if (monitor.id in monitorList) { |  |  |     if (monitor.id in monitorList) { | 
			
		
	
		
		
			
				
					|  |  |         monitorList[monitor.id].stop(); |  |  |         monitorList[monitor.id].stop(); | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     monitorList[monitor.id] = monitor; |  |  |     monitorList[monitor.id] = monitor; | 
			
		
	
		
		
			
				
					
					|  |  |     monitor.start(io) |  |  |     monitor.start(io); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | async function restartMonitor(userID, monitorID) { |  |  | async function restartMonitor(userID, monitorID) { | 
			
		
	
		
		
			
				
					
					|  |  |     return await startMonitor(userID, monitorID) |  |  |     return await startMonitor(userID, monitorID); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | async function pauseMonitor(userID, monitorID) { |  |  | async function pauseMonitor(userID, monitorID) { | 
			
		
	
		
		
			
				
					
					|  |  |     await checkOwner(userID, monitorID) |  |  |     await checkOwner(userID, monitorID); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     console.log(`Pause Monitor: ${monitorID} User ID: ${userID}`) |  |  |     console.log(`Pause Monitor: ${monitorID} User ID: ${userID}`); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [ |  |  |     await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [ | 
			
		
	
		
		
			
				
					|  |  |         monitorID, |  |  |         monitorID, | 
			
		
	
	
		
		
			
				
					|  | @ -1292,7 +1299,7 @@ async function pauseMonitor(userID, monitorID) { | 
			
		
	
		
		
			
				
					|  |  |  * Resume active monitors |  |  |  * Resume active monitors | 
			
		
	
		
		
			
				
					|  |  |  */ |  |  |  */ | 
			
		
	
		
		
			
				
					|  |  | async function startMonitors() { |  |  | async function startMonitors() { | 
			
		
	
		
		
			
				
					
					|  |  |     let list = await R.find("monitor", " active = 1 ") |  |  |     let list = await R.find("monitor", " active = 1 "); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     for (let monitor of list) { |  |  |     for (let monitor of list) { | 
			
		
	
		
		
			
				
					|  |  |         monitorList[monitor.id] = monitor; |  |  |         monitorList[monitor.id] = monitor; | 
			
		
	
	
		
		
			
				
					|  | @ -1309,10 +1316,10 @@ async function shutdownFunction(signal) { | 
			
		
	
		
		
			
				
					|  |  |     console.log("Shutdown requested"); |  |  |     console.log("Shutdown requested"); | 
			
		
	
		
		
			
				
					|  |  |     console.log("Called signal: " + signal); |  |  |     console.log("Called signal: " + signal); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     console.log("Stopping all monitors") |  |  |     console.log("Stopping all monitors"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |     for (let id in monitorList) { |  |  |     for (let id in monitorList) { | 
			
		
	
		
		
			
				
					
					|  |  |         let monitor = monitorList[id] |  |  |         let monitor = monitorList[id]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |         monitor.stop() |  |  |         monitor.stop(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |     await sleep(2000); |  |  |     await sleep(2000); | 
			
		
	
		
		
			
				
					|  |  |     await Database.close(); |  |  |     await Database.close(); | 
			
		
	
	
		
		
			
				
					|  | 
 |