[status page] store config

This commit is contained in:
LouisLam 2021-09-20 16:22:18 +08:00
parent 7ee98d989c
commit 0b572df3d0
3 changed files with 51 additions and 35 deletions

View file

@ -1,5 +1,5 @@
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const { checkLogin } = require("../util-server"); const { checkLogin, setSettings } = require("../util-server");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const { debug } = require("../../src/util"); const { debug } = require("../../src/util");
@ -67,12 +67,19 @@ module.exports.statusPageSocketHandler = (socket) => {
}); });
// Save Status Page // Save Status Page
socket.on("saveStatusPage", async (publicGroupList, callback) => { socket.on("saveStatusPage", async (config, imgDataUrl, publicGroupList, callback) => {
try { try {
checkLogin(socket); checkLogin(socket);
await R.transaction(async (trx) => { await R.transaction(async (trx) => {
// Save Config
//TODO
await setSettings("statusPage", config);
// Save Icon
// Save Public Group List
const groupIDList = []; const groupIDList = [];
let groupOrder = 1; let groupOrder = 1;
@ -120,6 +127,7 @@ module.exports.statusPageSocketHandler = (socket) => {
}); });
}); });
} catch (error) { } catch (error) {
console.log(error);
callback({ callback({
ok: false, ok: false,

View file

@ -5,7 +5,6 @@ const { debug } = require("../src/util");
const passwordHash = require("./password-hash"); const passwordHash = require("./password-hash");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const { Resolver } = require("dns"); const { Resolver } = require("dns");
const { allowAllOrigin } = require("./util-server");
/** /**
* Init or reset JWT secret * Init or reset JWT secret
@ -24,7 +23,7 @@ exports.initJWTSecret = async () => {
jwtSecretBean.value = passwordHash.generate(dayjs() + ""); jwtSecretBean.value = passwordHash.generate(dayjs() + "");
await R.store(jwtSecretBean); await R.store(jwtSecretBean);
return jwtSecretBean; return jwtSecretBean;
} };
exports.tcping = function (hostname, port) { exports.tcping = function (hostname, port) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -45,7 +44,7 @@ exports.tcping = function (hostname, port) {
resolve(Math.round(data.max)); resolve(Math.round(data.max));
}); });
}); });
} };
exports.ping = async (hostname) => { exports.ping = async (hostname) => {
try { try {
@ -58,7 +57,7 @@ exports.ping = async (hostname) => {
throw e; throw e;
} }
} }
} };
exports.pingAsync = function (hostname, ipv6 = false) { exports.pingAsync = function (hostname, ipv6 = false) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -70,13 +69,13 @@ exports.pingAsync = function (hostname, ipv6 = false) {
if (err) { if (err) {
reject(err); reject(err);
} else if (ms === null) { } else if (ms === null) {
reject(new Error(stdout)) reject(new Error(stdout));
} else { } else {
resolve(Math.round(ms)) resolve(Math.round(ms));
} }
}); });
}); });
} };
exports.dnsResolve = function (hostname, resolver_server, rrtype) { exports.dnsResolve = function (hostname, resolver_server, rrtype) {
const resolver = new Resolver(); const resolver = new Resolver();
@ -99,8 +98,8 @@ exports.dnsResolve = function (hostname, resolver_server, rrtype) {
} }
}); });
} }
}) });
} };
exports.setting = async function (key) { exports.setting = async function (key) {
let value = await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [ let value = await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [
@ -109,29 +108,29 @@ exports.setting = async function (key) {
try { try {
const v = JSON.parse(value); const v = JSON.parse(value);
debug(`Get Setting: ${key}: ${v}`) debug(`Get Setting: ${key}: ${v}`);
return v; return v;
} catch (e) { } catch (e) {
return value; return value;
} }
} };
exports.setSetting = async function (key, value) { exports.setSetting = async function (key, value) {
let bean = await R.findOne("setting", " `key` = ? ", [ let bean = await R.findOne("setting", " `key` = ? ", [
key, key,
]) ]);
if (!bean) { if (!bean) {
bean = R.dispense("setting") bean = R.dispense("setting");
bean.key = key; bean.key = key;
} }
bean.value = JSON.stringify(value); bean.value = JSON.stringify(value);
await R.store(bean) await R.store(bean);
} };
exports.getSettings = async function (type) { exports.getSettings = async function (type) {
let list = await R.getAll("SELECT `key`, `value` FROM setting WHERE `type` = ? ", [ let list = await R.getAll("SELECT `key`, `value` FROM setting WHERE `type` = ? ", [
type, type,
]) ]);
let result = {}; let result = {};
@ -144,7 +143,7 @@ exports.getSettings = async function (type) {
} }
return result; return result;
} };
exports.setSettings = async function (type, data) { exports.setSettings = async function (type, data) {
let keyList = Object.keys(data); let keyList = Object.keys(data);
@ -164,12 +163,12 @@ exports.setSettings = async function (type, data) {
if (bean.type === type) { if (bean.type === type) {
bean.value = JSON.stringify(data[key]); bean.value = JSON.stringify(data[key]);
promiseList.push(R.store(bean)) promiseList.push(R.store(bean));
} }
} }
await Promise.all(promiseList); await Promise.all(promiseList);
} };
// ssl-checker by @dyaa // ssl-checker by @dyaa
// param: res - response object from axios // param: res - response object from axios
@ -219,7 +218,7 @@ exports.checkCertificate = function (res) {
issuer, issuer,
fingerprint, fingerprint,
}; };
} };
// Check if the provided status code is within the accepted ranges // Check if the provided status code is within the accepted ranges
// Param: status - the status code to check // Param: status - the status code to check
@ -248,7 +247,7 @@ exports.checkStatusCode = function (status, accepted_codes) {
} }
return false; return false;
} };
exports.getTotalClientInRoom = (io, roomName) => { exports.getTotalClientInRoom = (io, roomName) => {
@ -271,7 +270,7 @@ exports.getTotalClientInRoom = (io, roomName) => {
} else { } else {
return 0; return 0;
} }
} };
exports.genSecret = () => { exports.genSecret = () => {
let secret = ""; let secret = "";
@ -281,21 +280,21 @@ exports.genSecret = () => {
secret += chars.charAt(Math.floor(Math.random() * charsLength)); secret += chars.charAt(Math.floor(Math.random() * charsLength));
} }
return secret; return secret;
} };
exports.allowDevAllOrigin = (res) => { exports.allowDevAllOrigin = (res) => {
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
exports.allowAllOrigin(res); exports.allowAllOrigin(res);
} }
} };
exports.allowAllOrigin = (res) => { exports.allowAllOrigin = (res) => {
res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
} };
exports.checkLogin = (socket) => { exports.checkLogin = (socket) => {
if (! socket.userID) { if (! socket.userID) {
throw new Error("You are not logged in."); throw new Error("You are not logged in.");
} }
} };

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="container mt-3"> <div v-if="loadedTheme" class="container mt-3">
<!-- Logo & Title --> <!-- Logo & Title -->
<h1> <h1>
<!-- Logo --> <!-- Logo -->
@ -143,15 +143,19 @@
All Systems Operational All Systems Operational
</div> </div>
<div v-if="partialDown"> <div v-else-if="partialDown">
<font-awesome-icon icon="exclamation-circle" class="warning" /> <font-awesome-icon icon="exclamation-circle" class="warning" />
Partially Degraded Service Partially Degraded Service
</div> </div>
<div v-if="allDown"> <div v-else-if="allDown">
<font-awesome-icon icon="times-circle" class="danger" /> <font-awesome-icon icon="times-circle" class="danger" />
Degraded Service Degraded Service
</div> </div>
<div v-else>
<font-awesome-icon icon="question-circle" style="color: #efefef" />
</div>
</template> </template>
</div> </div>
@ -190,7 +194,6 @@
</template> </template>
<script> <script>
import VueMultiselect from "vue-multiselect";
import axios from "axios"; import axios from "axios";
import PublicGroupList from "../components/PublicGroupList.vue"; import PublicGroupList from "../components/PublicGroupList.vue";
import ImageCropUpload from "vue-image-crop-upload"; import ImageCropUpload from "vue-image-crop-upload";
@ -206,7 +209,6 @@ let feedInterval;
export default { export default {
components: { components: {
PublicGroupList, PublicGroupList,
VueMultiselect,
ImageCropUpload ImageCropUpload
}, },
@ -234,6 +236,7 @@ export default {
previousIncident: null, previousIncident: null,
showImageCropUpload: false, showImageCropUpload: false,
imgDataUrl: "/icon.svg", imgDataUrl: "/icon.svg",
loadedTheme: false,
}; };
}, },
computed: { computed: {
@ -284,6 +287,11 @@ export default {
}, },
overallStatus() { overallStatus() {
if (Object.keys(this.$root.publicLastHeartbeatList).length === 0) {
return -1;
}
let status = STATUS_PAGE_ALL_UP; let status = STATUS_PAGE_ALL_UP;
let hasUp = false; let hasUp = false;
@ -346,6 +354,7 @@ export default {
// Set Theme // Set Theme
"config.statusPageTheme"() { "config.statusPageTheme"() {
this.$root.statusPageTheme = this.config.statusPageTheme; this.$root.statusPageTheme = this.config.statusPageTheme;
this.loadedTheme = true;
} }
}, },
@ -366,6 +375,7 @@ export default {
async mounted() { async mounted() {
axios.get("/api/status-page/config").then((res) => { axios.get("/api/status-page/config").then((res) => {
this.config = res.data; this.config = res.data;
}); });
axios.get("/api/status-page/incident").then((res) => { axios.get("/api/status-page/incident").then((res) => {
@ -401,10 +411,9 @@ export default {
}, },
save() { save() {
this.$root.getSocket().emit("saveStatusPage", this.$root.publicGroupList, (res) => { this.$root.getSocket().emit("saveStatusPage", this.config, this.imgDataUrl, this.$root.publicGroupList, (res) => {
if (res.ok) { if (res.ok) {
this.enableEditMode = false; this.enableEditMode = false;
console.log(res);
this.$root.publicGroupList = res.publicGroupList; this.$root.publicGroupList = res.publicGroupList;
} else { } else {
toast.error(res.msg); toast.error(res.msg);