diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..cc0f11863 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,73 @@ +module.exports = { + env: { + browser: true, + commonjs: true, + es2017: true, + node: true, + }, + extends: [ + "eslint:recommended", + "plugin:vue/vue3-recommended", + ], + parserOptions: { + ecmaVersion: 2018, + sourceType: "module", + }, + rules: { + // override/add rules settings here, such as: + // 'vue/no-unused-vars': 'error' + indent: ["error", 4], + quotes: ["warn", "double"], + //semi: ['off', 'never'], + "vue/html-indent": ["warn", 4], // default: 2 + "vue/max-attributes-per-line": "off", + "no-multi-spaces": ["error", { + ignoreEOLComments: true, + }], + "curly": "error", + "object-curly-spacing": ["error", "always"], + "object-curly-newline": ["error", { + "ObjectExpression": { + "minProperties": 1, + }, + "ObjectPattern": { + "multiline": true, + "minProperties": 2, + }, + "ImportDeclaration": { + "multiline": true, + }, + "ExportDeclaration": { + "multiline": true, + //'minProperties': 2, + }, + }], + "object-property-newline": "error", + "comma-spacing": "error", + "brace-style": "error", + "no-var": "error", + "key-spacing": "warn", + "keyword-spacing": "warn", + "space-infix-ops": "warn", + "arrow-spacing": "warn", + "no-trailing-spaces": "warn", + "space-before-blocks": "warn", + //'no-console': 'warn', + "no-extra-boolean-cast": "off", + "no-multiple-empty-lines": ["warn", { + "max": 1, + "maxBOF": 0, + }], + "lines-between-class-members": ["warn", "always", { + exceptAfterSingleLine: true, + }], + "no-unneeded-ternary": "error", + "no-else-return": ["error", { + "allowElseIf": false, + }], + "array-bracket-newline": ["error", "consistent"], + "eol-last": ["error", "always"], + //'prefer-template': 'error', + "comma-dangle": ["warn", "always-multiline"], + }, +} diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 000000000..4d3d9d1f8 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-recommended", +} diff --git a/package.json b/package.json index b54c73ff9..7cfd9e408 100644 --- a/package.json +++ b/package.json @@ -52,11 +52,16 @@ "vue-toastification": "^2.0.0-rc.1" }, "devDependencies": { - "@vitejs/plugin-legacy": "^1.4.4", - "@vitejs/plugin-vue": "^1.2.5", + "@vitejs/plugin-legacy": "^1.5.0", + "@vitejs/plugin-vue": "^1.3.0", "@vue/compiler-sfc": "^3.1.5", "core-js": "^3.15.2", - "sass": "^1.35.2", - "vite": "^2.4.2" + "eslint": "^7.31.0", + "eslint-plugin-vue": "^7.14.0", + "sass": "^1.36.0", + "stylelint": "^13.13.1", + "stylelint-config-recommended": "^5.0.0", + "stylelint-config-standard": "^22.0.0", + "vite": "^2.4.4" } } diff --git a/server/auth.js b/server/auth.js index b4d13d68a..54182bdef 100644 --- a/server/auth.js +++ b/server/auth.js @@ -1,6 +1,6 @@ -const basicAuth = require('express-basic-auth') -const passwordHash = require('./password-hash'); -const {R} = require("redbean-node"); +const basicAuth = require("express-basic-auth") +const passwordHash = require("./password-hash"); +const { R } = require("redbean-node"); /** * @@ -10,7 +10,7 @@ const {R} = require("redbean-node"); */ exports.login = async function (username, password) { let user = await R.findOne("user", " username = ? AND active = 1 ", [ - username + username, ]) if (user && passwordHash.verify(password, user.password)) { @@ -18,13 +18,13 @@ exports.login = async function (username, password) { if (passwordHash.needRehash(user.password)) { await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [ passwordHash.generate(password), - user.id + user.id, ]); } return user; - } else { - return null; } + + return null; } function myAuthorizer(username, password, callback) { @@ -36,5 +36,5 @@ function myAuthorizer(username, password, callback) { exports.basicAuth = basicAuth({ authorizer: myAuthorizer, authorizeAsync: true, - challenge: true + challenge: true, }); diff --git a/server/model/heartbeat.js b/server/model/heartbeat.js index 01fb71ff9..546794140 100644 --- a/server/model/heartbeat.js +++ b/server/model/heartbeat.js @@ -1,15 +1,15 @@ const dayjs = require("dayjs"); -const utc = require('dayjs/plugin/utc') -var timezone = require('dayjs/plugin/timezone') +const utc = require("dayjs/plugin/utc") +let timezone = require("dayjs/plugin/timezone") dayjs.extend(utc) dayjs.extend(timezone) -const {BeanModel} = require("redbean-node/dist/bean-model"); - +const { BeanModel } = require("redbean-node/dist/bean-model"); /** * status: * 0 = DOWN * 1 = UP + * 2 = PENDING */ class Heartbeat extends BeanModel { diff --git a/server/model/monitor.js b/server/model/monitor.js index 27f3f9bab..b725f43c6 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -22,6 +22,7 @@ const customAgent = new https.Agent({ * status: * 0 = DOWN * 1 = UP + * 2 = PENDING */ class Monitor extends BeanModel { async toJSON() { @@ -197,7 +198,7 @@ class Monitor extends BeanModel { if (bean.status === UP) { console.info(`Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${this.interval} seconds | Type: ${this.type}`) } else if (bean.status === PENDING) { - console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Type: ${this.type}`) + console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Type: ${this.type}`) } else { console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Type: ${this.type}`) } diff --git a/server/notification.js b/server/notification.js index 9da8a0dc8..f25ca80a7 100644 --- a/server/notification.js +++ b/server/notification.js @@ -1,6 +1,6 @@ const axios = require("axios"); -const {R} = require("redbean-node"); -const FormData = require('form-data'); +const { R } = require("redbean-node"); +const FormData = require("form-data"); const nodemailer = require("nodemailer"); const child_process = require("child_process"); @@ -24,7 +24,7 @@ class Notification { params: { chat_id: notification.telegramChatID, text: msg, - } + }, }) return okMsg; @@ -41,7 +41,7 @@ class Notification { await axios.post(`${notification.gotifyserverurl}/message?token=${notification.gotifyapplicationToken}`, { "message": msg, "priority": notification.gotifyPriority || 8, - "title": "Uptime-Kuma" + "title": "Uptime-Kuma", }) return okMsg; @@ -62,10 +62,10 @@ class Notification { if (notification.webhookContentType === "form-data") { finalData = new FormData(); - finalData.append('data', JSON.stringify(data)); + finalData.append("data", JSON.stringify(data)); config = { - headers: finalData.getHeaders() + headers: finalData.getHeaders(), } } else { @@ -84,63 +84,68 @@ class Notification { } else if (notification.type === "discord") { try { - // If heartbeatJSON is null, assume we're testing. - if(heartbeatJSON == null) { + // If heartbeatJSON is null, assume we're testing. + if (heartbeatJSON == null) { + let data = { + username: "Uptime-Kuma", + content: msg, + } + await axios.post(notification.discordWebhookUrl, data) + return okMsg; + } + // If heartbeatJSON is not null, we go into the normal alerting loop. + if (heartbeatJSON["status"] == 0) { + var alertColor = "16711680"; + } else if (heartbeatJSON["status"] == 1) { + var alertColor = "65280"; + } let data = { - username: 'Uptime-Kuma', - content: msg + username: "Uptime-Kuma", + embeds: [{ + title: "Uptime-Kuma Alert", + color: alertColor, + fields: [ + { + name: "Time (UTC)", + value: heartbeatJSON["time"], + }, + { + name: "Message", + value: msg, + }, + ], + }], } await axios.post(notification.discordWebhookUrl, data) return okMsg; - } - // If heartbeatJSON is not null, we go into the normal alerting loop. - if(heartbeatJSON['status'] == 0) { - var alertColor = "16711680"; - } else if(heartbeatJSON['status'] == 1) { - var alertColor = "65280"; - } - let data = { - username: 'Uptime-Kuma', - embeds: [{ - title: "Uptime-Kuma Alert", - color: alertColor, - fields: [ - { - name: "Time (UTC)", - value: heartbeatJSON["time"] - }, - { - name: "Message", - value: msg - } - ] - }] - } - await axios.post(notification.discordWebhookUrl, data) - return okMsg; - } catch(error) { - throwGeneralAxiosError(error) + } catch (error) { + throwGeneralAxiosError(error) } } else if (notification.type === "signal") { - try { - let data = { - "message": msg, - "number": notification.signalNumber, - "recipients": notification.signalRecipients.replace(/\s/g, '').split(",") - }; - let config = {}; + try { + let data = { + "message": msg, + "number": notification.signalNumber, + "recipients": notification.signalRecipients.replace(/\s/g, "").split(","), + }; + let config = {}; - await axios.post(notification.signalURL, data, config) - return okMsg; - } catch (error) { - throwGeneralAxiosError(error) - } + await axios.post(notification.signalURL, data, config) + return okMsg; + } catch (error) { + throwGeneralAxiosError(error) + } } else if (notification.type === "slack") { try { if (heartbeatJSON == null) { - let data = {'text': "Uptime Kuma Slack testing successful.", 'channel': notification.slackchannel, 'username': notification.slackusername, 'icon_emoji': notification.slackiconemo} + let data = { + "text": "Uptime Kuma Slack testing successful.", + "channel": notification.slackchannel, + "username": notification.slackusername, + "icon_emoji": notification.slackiconemo, + } await axios.post(notification.slackwebhookURL, data) return okMsg; } @@ -148,44 +153,42 @@ class Notification { const time = heartbeatJSON["time"]; let data = { "text": "Uptime Kuma Alert", - "channel":notification.slackchannel, + "channel": notification.slackchannel, "username": notification.slackusername, "icon_emoji": notification.slackiconemo, "blocks": [{ - "type": "header", - "text": { - "type": "plain_text", - "text": "Uptime Kuma Alert" - } + "type": "header", + "text": { + "type": "plain_text", + "text": "Uptime Kuma Alert", + }, + }, + { + "type": "section", + "fields": [{ + "type": "mrkdwn", + "text": "*Message*\n" + msg, }, { - "type": "section", - "fields": [{ - "type": "mrkdwn", - "text": '*Message*\n'+msg + "type": "mrkdwn", + "text": "*Time (UTC)*\n" + time, + }], + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Visit Uptime Kuma", }, - { - "type": "mrkdwn", - "text": "*Time (UTC)*\n"+time - } - ] - }, - { - "type": "actions", - "elements": [ - { - "type": "button", - "text": { - "type": "plain_text", - "text": "Visit Uptime Kuma", - }, - "value": "Uptime-Kuma", - "url": notification.slackbutton || "https://github.com/louislam/uptime-kuma" - } - ] - } - ] - } + "value": "Uptime-Kuma", + "url": notification.slackbutton || "https://github.com/louislam/uptime-kuma", + }, + ], + }], + } await axios.post(notification.slackwebhookURL, data) return okMsg; } catch (error) { @@ -193,27 +196,35 @@ class Notification { } } else if (notification.type === "pushover") { - var pushoverlink = 'https://api.pushover.net/1/messages.json' + let pushoverlink = "https://api.pushover.net/1/messages.json" try { if (heartbeatJSON == null) { - let data = {'message': "Uptime Kuma Pushover testing successful.", - 'user': notification.pushoveruserkey, 'token': notification.pushoverapptoken, 'sound':notification.pushoversounds, - 'priority': notification.pushoverpriority, 'title':notification.pushovertitle, 'retry': "30", 'expire':"3600", 'html': 1} + let data = { + "message": "Uptime Kuma Pushover testing successful.", + "user": notification.pushoveruserkey, + "token": notification.pushoverapptoken, + "sound": notification.pushoversounds, + "priority": notification.pushoverpriority, + "title": notification.pushovertitle, + "retry": "30", + "expire": "3600", + "html": 1, + } await axios.post(pushoverlink, data) return okMsg; } let data = { - "message": "Uptime Kuma Alert\n\nMessage:"+msg+ '\nTime (UTC):' +heartbeatJSON["time"], - "user":notification.pushoveruserkey, + "message": "Uptime Kuma Alert\n\nMessage:" + msg + "\nTime (UTC):" + heartbeatJSON["time"], + "user": notification.pushoveruserkey, "token": notification.pushoverapptoken, "sound": notification.pushoversounds, "priority": notification.pushoverpriority, "title": notification.pushovertitle, "retry": "30", "expire": "3600", - "html": 1 - } + "html": 1, + } await axios.post(pushoverlink, data) return okMsg; } catch (error) { @@ -291,24 +302,23 @@ class Notification { static async apprise(notification, msg) { let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL]) - - let output = (s.stdout) ? s.stdout.toString() : 'ERROR: maybe apprise not found'; + let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found"; if (output) { if (! output.includes("ERROR")) { return "Sent Successfully"; - } else { - throw new Error(output) } + + throw new Error(output) } else { return "" } } static checkApprise() { - let commandExistsSync = require('command-exists').sync; - let exists = commandExistsSync('apprise'); + let commandExistsSync = require("command-exists").sync; + let exists = commandExistsSync("apprise"); return exists; } diff --git a/server/password-hash.js b/server/password-hash.js index 39bc0c20c..52e26b959 100644 --- a/server/password-hash.js +++ b/server/password-hash.js @@ -1,5 +1,5 @@ -const passwordHashOld = require('password-hash'); -const bcrypt = require('bcrypt'); +const passwordHashOld = require("password-hash"); +const bcrypt = require("bcrypt"); const saltRounds = 10; exports.generate = function (password) { @@ -9,9 +9,9 @@ exports.generate = function (password) { exports.verify = function (password, hash) { if (isSHA1(hash)) { return passwordHashOld.verify(password, hash) - } else { - return bcrypt.compareSync(password, hash); } + + return bcrypt.compareSync(password, hash); } function isSHA1(hash) { diff --git a/server/ping-lite.js b/server/ping-lite.js index e290d8876..0b9a7401a 100644 --- a/server/ping-lite.js +++ b/server/ping-lite.js @@ -1,9 +1,9 @@ // https://github.com/ben-bradley/ping-lite/blob/master/ping-lite.js // Fixed on Windows -var spawn = require('child_process').spawn, - events = require('events'), - fs = require('fs'), +let spawn = require("child_process").spawn, + events = require("events"), + fs = require("fs"), WIN = /^win/.test(process.platform), LIN = /^linux/.test(process.platform), MAC = /^darwin/.test(process.platform); @@ -11,8 +11,9 @@ var spawn = require('child_process').spawn, module.exports = Ping; function Ping(host, options) { - if (!host) - throw new Error('You must specify a host to ping!'); + if (!host) { + throw new Error("You must specify a host to ping!"); + } this._host = host; this._options = options = (options || {}); @@ -20,26 +21,24 @@ function Ping(host, options) { events.EventEmitter.call(this); if (WIN) { - this._bin = 'c:/windows/system32/ping.exe'; - this._args = (options.args) ? options.args : [ '-n', '1', '-w', '5000', host ]; + this._bin = "c:/windows/system32/ping.exe"; + this._args = (options.args) ? options.args : [ "-n", "1", "-w", "5000", host ]; this._regmatch = /[><=]([0-9.]+?)ms/; - } - else if (LIN) { - this._bin = '/bin/ping'; - this._args = (options.args) ? options.args : [ '-n', '-w', '2', '-c', '1', host ]; + } else if (LIN) { + this._bin = "/bin/ping"; + this._args = (options.args) ? options.args : [ "-n", "-w", "2", "-c", "1", host ]; this._regmatch = /=([0-9.]+?) ms/; // need to verify this - } - else if (MAC) { - this._bin = '/sbin/ping'; - this._args = (options.args) ? options.args : [ '-n', '-t', '2', '-c', '1', host ]; + } else if (MAC) { + this._bin = "/sbin/ping"; + this._args = (options.args) ? options.args : [ "-n", "-t", "2", "-c", "1", host ]; this._regmatch = /=([0-9.]+?) ms/; - } - else { - throw new Error('Could not detect your ping binary.'); + } else { + throw new Error("Could not detect your ping binary."); } - if (!fs.existsSync(this._bin)) - throw new Error('Could not detect '+this._bin+' on your system'); + if (!fs.existsSync(this._bin)) { + throw new Error("Could not detect " + this._bin + " on your system"); + } this._i = 0; @@ -51,48 +50,57 @@ Ping.prototype.__proto__ = events.EventEmitter.prototype; // SEND A PING // =========== Ping.prototype.send = function(callback) { - var self = this; + let self = this; callback = callback || function(err, ms) { - if (err) return self.emit('error', err); - else return self.emit('result', ms); + if (err) { + return self.emit("error", err); + } + return self.emit("result", ms); }; - var _ended, _exited, _errored; + let _ended, _exited, _errored; this._ping = spawn(this._bin, this._args); // spawn the binary - this._ping.on('error', function(err) { // handle binary errors + this._ping.on("error", function(err) { // handle binary errors _errored = true; callback(err); }); - this._ping.stdout.on('data', function(data) { // log stdout - this._stdout = (this._stdout || '') + data; + this._ping.stdout.on("data", function(data) { // log stdout + this._stdout = (this._stdout || "") + data; }); - this._ping.stdout.on('end', function() { + this._ping.stdout.on("end", function() { _ended = true; - if (_exited && !_errored) onEnd.call(self._ping); + if (_exited && !_errored) { + onEnd.call(self._ping); + } }); - this._ping.stderr.on('data', function(data) { // log stderr - this._stderr = (this._stderr || '') + data; + this._ping.stderr.on("data", function(data) { // log stderr + this._stderr = (this._stderr || "") + data; }); - this._ping.on('exit', function(code) { // handle complete + this._ping.on("exit", function(code) { // handle complete _exited = true; - if (_ended && !_errored) onEnd.call(self._ping); + if (_ended && !_errored) { + onEnd.call(self._ping); + } }); function onEnd() { - var stdout = this.stdout._stdout, + let stdout = this.stdout._stdout, stderr = this.stderr._stderr, ms; - if (stderr) + if (stderr) { return callback(new Error(stderr)); - else if (!stdout) - return callback(new Error('No stdout detected')); + } + + if (!stdout) { + return callback(new Error("No stdout detected")); + } ms = stdout.match(self._regmatch); // parse out the ##ms response ms = (ms && ms[1]) ? Number(ms[1]) : ms; @@ -104,7 +112,7 @@ Ping.prototype.send = function(callback) { // CALL Ping#send(callback) ON A TIMER // =================================== Ping.prototype.start = function(callback) { - var self = this; + let self = this; this._i = setInterval(function() { self.send(callback); }, (self._options.interval || 5000)); diff --git a/server/server.js b/server/server.js index b3837c920..661d9807d 100644 --- a/server/server.js +++ b/server/server.js @@ -1,24 +1,24 @@ console.log("Welcome to Uptime Kuma ") console.log("Importing libraries") -const express = require('express'); -const http = require('http'); +const express = require("express"); +const http = require("http"); const { Server } = require("socket.io"); const dayjs = require("dayjs"); -const {R} = require("redbean-node"); -const jwt = require('jsonwebtoken'); +const { R } = require("redbean-node"); +const jwt = require("jsonwebtoken"); const Monitor = require("./model/monitor"); const fs = require("fs"); -const {getSettings} = require("./util-server"); -const {Notification} = require("./notification") -const gracefulShutdown = require('http-graceful-shutdown'); +const { getSettings } = require("./util-server"); +const { Notification } = require("./notification") +const gracefulShutdown = require("http-graceful-shutdown"); const Database = require("./database"); -const {sleep} = require("./util"); -const args = require('args-parser')(process.argv); -const prometheusAPIMetrics = require('prometheus-api-metrics'); +const { sleep } = require("./util"); +const args = require("args-parser")(process.argv); +const prometheusAPIMetrics = require("prometheus-api-metrics"); const { basicAuth } = require("./auth"); -const {login} = require("./auth"); +const { login } = require("./auth"); const passwordHash = require('./password-hash'); -const version = require('../package.json').version; +const version = require("../package.json").version; const hostname = args.host || "0.0.0.0" const port = args.port || 3001 @@ -64,12 +64,12 @@ let needSetup = false; // Normal Router here - app.use('/', express.static("dist")); + app.use("/", express.static("dist")); // Basic Auth Router here // For testing - basicAuthRouter.get('/test-auth', (req, res) => { + basicAuthRouter.get("/test-auth", (req, res) => { res.end("OK") }); @@ -78,12 +78,12 @@ let needSetup = false; basicAuthRouter.use(prometheusAPIMetrics()) // Universal Route Handler, must be at the end - app.get('*', function(request, response, next) { - response.sendFile(process.cwd() + '/dist/index.html'); + app.get("*", function(request, response, next) { + response.sendFile(process.cwd() + "/dist/index.html"); }); console.log("Adding socket handler") - io.on('connection', async (socket) => { + io.on("connection", async (socket) => { socket.emit("info", { version, @@ -96,7 +96,7 @@ let needSetup = false; socket.emit("setup") } - socket.on('disconnect', () => { + socket.on("disconnect", () => { totalClient--; }); @@ -110,7 +110,7 @@ let needSetup = false; console.log("Username from JWT: " + decoded.username) let user = await R.findOne("user", " username = ? AND active = 1 ", [ - decoded.username + decoded.username, ]) if (user) { @@ -122,13 +122,13 @@ let needSetup = false; } else { callback({ ok: false, - msg: "The user is inactive or deleted." + msg: "The user is inactive or deleted.", }) } } catch (error) { callback({ ok: false, - msg: "Invalid token." + msg: "Invalid token.", }) } @@ -145,13 +145,13 @@ let needSetup = false; callback({ ok: true, token: jwt.sign({ - username: data.username - }, jwtSecret) + username: data.username, + }, jwtSecret), }) } else { callback({ ok: false, - msg: "Incorrect username or password." + msg: "Incorrect username or password.", }) } @@ -182,13 +182,13 @@ let needSetup = false; callback({ ok: true, - msg: "Added Successfully." + msg: "Added Successfully.", }); } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -215,13 +215,13 @@ let needSetup = false; callback({ ok: true, msg: "Added Successfully.", - monitorID: bean.id + monitorID: bean.id, }); } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -258,14 +258,14 @@ let needSetup = false; callback({ ok: true, msg: "Saved.", - monitorID: bean.id + monitorID: bean.id, }); } catch (e) { console.error(e) callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -289,7 +289,7 @@ let needSetup = false; } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -303,13 +303,13 @@ let needSetup = false; callback({ ok: true, - msg: "Resumed Successfully." + msg: "Resumed Successfully.", }); } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -322,14 +322,13 @@ let needSetup = false; callback({ ok: true, - msg: "Paused Successfully." + msg: "Paused Successfully.", }); - } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -347,12 +346,12 @@ let needSetup = false; await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [ monitorID, - socket.userID + socket.userID, ]); callback({ ok: true, - msg: "Deleted Successfully." + msg: "Deleted Successfully.", }); await sendMonitorList(socket); @@ -360,7 +359,7 @@ let needSetup = false; } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -374,19 +373,19 @@ let needSetup = false; } let user = await R.findOne("user", " id = ? AND active = 1 ", [ - socket.userID + socket.userID, ]) if (user && passwordHash.verify(password.currentPassword, user.password)) { await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [ passwordHash.generate(password.newPassword), - socket.userID + socket.userID, ]); callback({ ok: true, - msg: "Password has been updated successfully." + msg: "Password has been updated successfully.", }) } else { throw new Error("Incorrect current password") @@ -395,7 +394,7 @@ let needSetup = false; } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -404,7 +403,6 @@ let needSetup = false; try { checkLogin(socket) - callback({ ok: true, data: await getSettings(type), @@ -413,7 +411,7 @@ let needSetup = false; } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -434,7 +432,7 @@ let needSetup = false; } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -454,7 +452,7 @@ let needSetup = false; } catch (e) { callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -467,7 +465,7 @@ let needSetup = false; callback({ ok: true, - msg + msg, }); } catch (e) { @@ -475,7 +473,7 @@ let needSetup = false; callback({ ok: false, - msg: e.message + msg: e.message, }); } }); @@ -500,7 +498,7 @@ let needSetup = false; async function updateMonitorNotification(monitorID, notificationIDList) { R.exec("DELETE FROM monitor_notification WHERE monitor_id = ? ", [ - monitorID + monitorID, ]) for (let notificationID in notificationIDList) { @@ -533,7 +531,7 @@ async function sendMonitorList(socket) { async function sendNotificationList(socket) { let result = []; let list = await R.find("notification", " user_id = ? ", [ - socket.userID + socket.userID, ]); for (let bean of list) { @@ -563,7 +561,7 @@ async function getMonitorJSONList(userID) { let result = {}; let monitorList = await R.find("monitor", " user_id = ? ", [ - userID + userID, ]) for (let monitor of monitorList) { @@ -586,8 +584,8 @@ async function initDatabase() { } console.log("Connecting to Database") - R.setup('sqlite', { - filename: Database.path + R.setup("sqlite", { + filename: Database.path, }); console.log("Connected") @@ -599,7 +597,7 @@ async function initDatabase() { await R.autoloadModels("./server/model"); let jwtSecretBean = await R.findOne("setting", " `key` = ? ", [ - "jwtSecret" + "jwtSecret", ]); if (! jwtSecretBean) { @@ -630,11 +628,11 @@ async function startMonitor(userID, monitorID) { await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [ monitorID, - userID + userID, ]); let monitor = await R.findOne("monitor", " id = ? ", [ - monitorID + monitorID, ]) if (monitor.id in monitorList) { @@ -656,7 +654,7 @@ async function pauseMonitor(userID, monitorID) { await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [ monitorID, - userID + userID, ]); if (monitorID in monitorList) { @@ -685,13 +683,13 @@ async function sendHeartbeatList(socket, monitorID) { ORDER BY time DESC LIMIT 100 `, [ - monitorID + monitorID, ]) let result = []; for (let bean of list) { - result.unshift(bean.toJSON()) + result.unshift(bean.toJSON()) } socket.emit("heartbeatList", monitorID, result) @@ -704,23 +702,20 @@ async function sendImportantHeartbeatList(socket, monitorID) { ORDER BY time DESC LIMIT 500 `, [ - monitorID + monitorID, ]) socket.emit("importantHeartbeatList", monitorID, list) } - - const startGracefulShutdown = async () => { - console.log('Shutdown requested'); - + console.log("Shutdown requested"); await (new Promise((resolve) => { server.close(async function () { - console.log('Stopped Express.'); + console.log("Stopped Express."); process.exit(0) - setTimeout(async () =>{ + setTimeout(async () => { await R.close(); console.log("Stopped DB") @@ -730,11 +725,10 @@ const startGracefulShutdown = async () => { }); })); - } async function shutdownFunction(signal) { - console.log('Called signal: ' + signal); + console.log("Called signal: " + signal); console.log("Stopping all monitors") for (let id in monitorList) { @@ -746,14 +740,14 @@ async function shutdownFunction(signal) { } function finalFunction() { - console.log('Graceful Shutdown') + console.log("Graceful Shutdown") } gracefulShutdown(server, { - signals: 'SIGINT SIGTERM', + signals: "SIGINT SIGTERM", timeout: 30000, // timeout: 30 secs development: false, // not in dev mode forceExit: true, // triggers process.exit() at the end of shutdown process onShutdown: shutdownFunction, // shutdown function (async) - e.g. for cleanup DB, ... - finally: finalFunction // finally function (sync) - e.g. for logging + finally: finalFunction, // finally function (sync) - e.g. for logging }); diff --git a/server/util-server.js b/server/util-server.js index f03823d3a..43aa5ccfb 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -1,6 +1,6 @@ -const tcpp = require('tcp-ping'); +const tcpp = require("tcp-ping"); const Ping = require("./ping-lite"); -const {R} = require("redbean-node"); +const { R } = require("redbean-node"); exports.tcping = function (hostname, port) { return new Promise((resolve, reject) => { @@ -41,13 +41,13 @@ exports.ping = function (hostname) { exports.setting = async function (key) { return await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [ - key + key, ]) } exports.setSetting = async function (key, value) { let bean = await R.findOne("setting", " `key` = ? ", [ - key + key, ]) if (! bean) { bean = R.dispense("setting") @@ -59,7 +59,7 @@ exports.setSetting = async function (key, value) { exports.getSettings = async function (type) { let list = await R.getAll("SELECT * FROM setting WHERE `type` = ? ", [ - type + type, ]) let result = {}; @@ -71,7 +71,6 @@ exports.getSettings = async function (type) { return result; } - // ssl-checker by @dyaa // param: res - response object from axios // return an object containing the certificate information @@ -97,7 +96,9 @@ exports.checkCertificate = function (res) { } = res.request.res.socket.getPeerCertificate(false); if (!valid_from || !valid_to || !subjectaltname) { - throw { message: 'No TLS certificate in response' }; + throw { + message: "No TLS certificate in response", + }; } const valid = res.request.res.socket.authorized || false; @@ -118,4 +119,4 @@ exports.checkCertificate = function (res) { issuer, fingerprint, }; -} \ No newline at end of file +} diff --git a/server/util.js b/server/util.js index 081561bf9..6e90dc42b 100644 --- a/server/util.js +++ b/server/util.js @@ -23,4 +23,3 @@ exports.debug = (msg) => { console.log(msg) } } - diff --git a/src/App.vue b/src/App.vue index 1f05560e6..a16d42085 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,11 +3,5 @@ - - diff --git a/src/components/Confirm.vue b/src/components/Confirm.vue index 063ece257..36d3781a6 100644 --- a/src/components/Confirm.vue +++ b/src/components/Confirm.vue @@ -1,17 +1,23 @@ - - diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue index 33904b6a9..c63aea14b 100644 --- a/src/components/CountUp.vue +++ b/src/components/CountUp.vue @@ -5,24 +5,20 @@ - - diff --git a/src/components/Datetime.vue b/src/components/Datetime.vue index 3e5516597..84093afb1 100644 --- a/src/components/Datetime.vue +++ b/src/components/Datetime.vue @@ -5,8 +5,8 @@ - - diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index 03cdceca6..bfcb90850 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -1,28 +1,27 @@ diff --git a/src/components/Login.vue b/src/components/Login.vue index 017261ccd..4b08de066 100644 --- a/src/components/Login.vue +++ b/src/components/Login.vue @@ -2,31 +2,32 @@
- -

+

- +
- +
- +
- + -