From a36f24d827f2dd37c247cee6a124495bbd0e3d19 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Sun, 9 Oct 2022 20:59:58 +0800 Subject: [PATCH] Add configurable server timezone --- package-lock.json | 4 ++-- package.json | 2 +- server/server.js | 24 ++++++++++++++++++------ server/uptime-kuma-server.js | 25 +++++++++++++++++++++++++ src/components/settings/General.vue | 20 ++++++++++++++++++-- src/util.js | 2 +- src/util.ts | 2 +- 7 files changed, 66 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2fdcb272b..fb50f2753 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "uptime-kuma", - "version": "1.18.3", + "version": "1.18.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "uptime-kuma", - "version": "1.18.3", + "version": "1.18.4", "license": "MIT", "dependencies": { "@louislam/sqlite3": "~15.0.6", diff --git a/package.json b/package.json index a77ea3d72..c3f7a8865 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "@vitejs/plugin-legacy": "~2.1.0", "@vitejs/plugin-vue": "~3.1.0", "@vue/compiler-sfc": "~3.2.36", - "@vuepic/vue-datepicker": "^3.4.8", + "@vuepic/vue-datepicker": "~3.4.8", "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", "bootstrap": "5.1.3", diff --git a/server/server.js b/server/server.js index 1ad99899f..f80d5d575 100644 --- a/server/server.js +++ b/server/server.js @@ -5,6 +5,11 @@ */ console.log("Welcome to Uptime Kuma"); +// As the log function need to use dayjs, it should be very top +const dayjs = require("dayjs"); +dayjs.extend(require("dayjs/plugin/utc")); +dayjs.extend(require("dayjs/plugin/timezone")); + // Check Node.js Version const nodeVersion = parseInt(process.versions.node.split(".")[0]); const requiredVersion = 14; @@ -34,10 +39,6 @@ const fs = require("fs"); log.info("server", "Importing 3rd-party libraries"); -const dayjs = require("dayjs"); -dayjs.extend(require("dayjs/plugin/utc")); -dayjs.extend(require("dayjs/plugin/timezone")); - log.debug("server", "Importing express"); const express = require("express"); const expressStaticGzip = require("express-static-gzip"); @@ -160,6 +161,7 @@ let needSetup = false; (async () => { Database.init(args); await initDatabase(testMode); + await server.initAfterDatabaseReady(); exports.entryPage = await setting("entryPage"); await StatusPage.loadDomainMappingList(); @@ -1061,10 +1063,15 @@ let needSetup = false; socket.on("getSettings", async (callback) => { try { checkLogin(socket); + const data = await getSettings("general"); + + if (!data.serverTimezone) { + data.serverTimezone = await server.getTimezone(); + } callback({ ok: true, - data: await getSettings("general"), + data: data, }); } catch (e) { @@ -1092,9 +1099,14 @@ let needSetup = false; await setSettings("general", data); exports.entryPage = data.entryPage; + // Also need to apply timezone globally + if (data.serverTimezone) { + await server.setTimezone(data.serverTimezone); + } + callback({ ok: true, - msg: "Saved" + msg: "Saved " + dayjs() }); sendInfo(socket); diff --git a/server/uptime-kuma-server.js b/server/uptime-kuma-server.js index 7de53fe68..155831592 100644 --- a/server/uptime-kuma-server.js +++ b/server/uptime-kuma-server.js @@ -9,6 +9,7 @@ const Database = require("./database"); const util = require("util"); const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent"); const { Settings } = require("./settings"); +const dayjs = require("dayjs"); /** * `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue. @@ -84,6 +85,13 @@ class UptimeKumaServer { this.io = new Server(this.httpServer); } + async initAfterDatabaseReady() { + process.env.TZ = await this.getTimezone(); + dayjs.tz.setDefault(process.env.TZ); + log.debug("DEBUG", "Timezone: " + process.env.TZ); + log.debug("DEBUG", "Current Time: " + dayjs.tz().format()); + } + async sendMonitorList(socket) { let list = await this.getMonitorJSONList(socket.userID); this.io.to(socket.userID).emit("monitorList", list); @@ -184,6 +192,23 @@ class UptimeKumaServer { return clientIP.replace(/^.*:/, ""); } } + + async getTimezone() { + let timezone = await Settings.get("serverTimezone"); + if (timezone) { + return timezone; + } else if (process.env.TZ) { + return process.env.TZ; + } else { + return dayjs.tz.guess(); + } + } + + async setTimezone(timezone) { + await Settings.set("serverTimezone", timezone, "general"); + process.env.TZ = timezone; + dayjs.tz.setDefault(timezone); + } } module.exports = { diff --git a/src/components/settings/General.vue b/src/components/settings/General.vue index 242ad8537..57c8e0cac 100644 --- a/src/components/settings/General.vue +++ b/src/components/settings/General.vue @@ -1,10 +1,10 @@