From d490285a447c4401e9986f6dbed3995454042fb5 Mon Sep 17 00:00:00 2001 From: yumeiyin <155420652+yumeiyin@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:08:53 +0800 Subject: [PATCH 1/3] chore: fix some minor issues in comments (#5984) Signed-off-by: yumeiyin --- server/model/monitor.js | 2 +- server/notification-providers/promosms.js | 2 +- server/socket-handlers/api-key-socket-handler.js | 2 +- server/uptime-calculator.js | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index 3be8267c9..0ddfa924c 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -1314,7 +1314,7 @@ class Monitor extends BeanModel { /** * Send a notification about a monitor * @param {boolean} isFirstBeat Is this beat the first of this monitor? - * @param {Monitor} monitor The monitor to send a notificaton about + * @param {Monitor} monitor The monitor to send a notification about * @param {Bean} bean Status information about monitor * @returns {void} */ diff --git a/server/notification-providers/promosms.js b/server/notification-providers/promosms.js index 05334e902..36b7ecb33 100644 --- a/server/notification-providers/promosms.js +++ b/server/notification-providers/promosms.js @@ -15,7 +15,7 @@ class PromoSMS extends NotificationProvider { notification.promosmsAllowLongSMS = false; } - //TODO: Add option for enabling special characters. It will decrese message max length from 160 to 70 chars. + //TODO: Add option for enabling special characters. It will decrease message max length from 160 to 70 chars. //Lets remove non ascii char let cleanMsg = msg.replace(/[^\x00-\x7F]/g, ""); diff --git a/server/socket-handlers/api-key-socket-handler.js b/server/socket-handlers/api-key-socket-handler.js index d88151294..d49ac086b 100644 --- a/server/socket-handlers/api-key-socket-handler.js +++ b/server/socket-handlers/api-key-socket-handler.js @@ -27,7 +27,7 @@ module.exports.apiKeySocketHandler = (socket) => { log.debug("apikeys", "Added API Key"); log.debug("apikeys", key); - // Append key ID and prefix to start of key seperated by _, used to get + // Append key ID and prefix to start of key separated by _, used to get // correct hash when validating key. let formattedKey = "uk" + bean.id + "_" + clearKey; await sendAPIKeyList(socket); diff --git a/server/uptime-calculator.js b/server/uptime-calculator.js index 71d1d458c..48f7d80ae 100644 --- a/server/uptime-calculator.js +++ b/server/uptime-calculator.js @@ -582,7 +582,7 @@ class UptimeCalculator { let totalPing = 0; let endTimestamp; - // Get the eariest timestamp of the required period based on the type + // Get the earliest timestamp of the required period based on the type switch (type) { case "day": endTimestamp = key - 86400 * (num - 1); @@ -710,7 +710,7 @@ class UptimeCalculator { let endTimestamp; - // Get the eariest timestamp of the required period based on the type + // Get the earliest timestamp of the required period based on the type switch (type) { case "day": endTimestamp = key - 86400 * (num - 1); From 7c88a38df3815130263721394afb58e8fd32524e Mon Sep 17 00:00:00 2001 From: Ionys <9364594+Ionys320@users.noreply.github.com> Date: Wed, 16 Jul 2025 17:28:29 +0200 Subject: [PATCH 2/3] Fixing recurring maintenance start (again) (#5914) Co-authored-by: Frank Elsinga --- ...5-06-13-0000-maintenance-add-last-start.js | 34 ++++++++++++++++++ server/model/maintenance.js | 36 +++++++++++++++---- 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 db/knex_migrations/2025-06-13-0000-maintenance-add-last-start.js diff --git a/db/knex_migrations/2025-06-13-0000-maintenance-add-last-start.js b/db/knex_migrations/2025-06-13-0000-maintenance-add-last-start.js new file mode 100644 index 000000000..3cb28d968 --- /dev/null +++ b/db/knex_migrations/2025-06-13-0000-maintenance-add-last-start.js @@ -0,0 +1,34 @@ +// Add column last_start_date to maintenance table +exports.up = async function (knex) { + await knex.schema + .alterTable("maintenance", function (table) { + table.datetime("last_start_date"); + }); + + // Perform migration for recurring-interval strategy + const recurringMaintenances = await knex("maintenance").where({ + strategy: "recurring-interval", + cron: "* * * * *" + }).select("id", "start_time"); + + // eslint-disable-next-line camelcase + const maintenanceUpdates = recurringMaintenances.map(async ({ start_time, id }) => { + // eslint-disable-next-line camelcase + const [ hourStr, minuteStr ] = start_time.split(":"); + const hour = parseInt(hourStr, 10); + const minute = parseInt(minuteStr, 10); + + const cron = `${minute} ${hour} * * *`; + + await knex("maintenance") + .where({ id }) + .update({ cron }); + }); + await Promise.all(maintenanceUpdates); +}; + +exports.down = function (knex) { + return knex.schema.alterTable("maintenance", function (table) { + table.dropColumn("last_start_date"); + }); +}; diff --git a/server/model/maintenance.js b/server/model/maintenance.js index 0a70063ff..aa1fa0c14 100644 --- a/server/model/maintenance.js +++ b/server/model/maintenance.js @@ -202,7 +202,7 @@ class Maintenance extends BeanModel { * @returns {void} */ static validateCron(cron) { - let job = new Cron(cron, () => {}); + let job = new Cron(cron, () => { }); job.stop(); } @@ -239,6 +239,8 @@ class Maintenance extends BeanModel { apicache.clear(); }); } else if (this.cron != null) { + let current = dayjs(); + // Here should be cron or recurring try { this.beanMeta.status = "scheduled"; @@ -258,6 +260,10 @@ class Maintenance extends BeanModel { this.beanMeta.status = "scheduled"; UptimeKumaServer.getInstance().sendMaintenanceListByUserID(this.user_id); }, duration); + + // Set last start date to current time + this.last_start_date = current.toISOString(); + R.store(this); }; // Create Cron @@ -268,9 +274,25 @@ class Maintenance extends BeanModel { const startDateTime = startDate.hour(hour).minute(minute); this.beanMeta.job = new Cron(this.cron, { timezone: await this.getTimezone(), - interval: this.interval_day * 24 * 60 * 60, startAt: startDateTime.toISOString(), - }, startEvent); + }, () => { + if (!this.lastStartDate || this.interval_day === 1) { + return startEvent(); + } + + // If last start date is set, it means the maintenance has been started before + let lastStartDate = dayjs(this.lastStartDate) + .subtract(1.1, "hour"); // Subtract 1.1 hour to avoid issues with timezone differences + + // Check if the interval is enough + if (current.diff(lastStartDate, "day") < this.interval_day) { + log.debug("maintenance", "Maintenance id: " + this.id + " is still in the window, skipping start event"); + return; + } + + log.debug("maintenance", "Maintenance id: " + this.id + " is not in the window, starting event"); + return startEvent(); + }); } else { this.beanMeta.job = new Cron(this.cron, { timezone: await this.getTimezone(), @@ -279,7 +301,6 @@ class Maintenance extends BeanModel { // Continue if the maintenance is still in the window let runningTimeslot = this.getRunningTimeslot(); - let current = dayjs(); if (runningTimeslot) { let duration = dayjs(runningTimeslot.endDate).diff(current, "second") * 1000; @@ -423,8 +444,11 @@ class Maintenance extends BeanModel { } else if (!this.strategy.startsWith("recurring-")) { this.cron = ""; } else if (this.strategy === "recurring-interval") { - // For intervals, the pattern is calculated in the run function as the interval-option is set - this.cron = "* * * * *"; + // For intervals, the pattern is used to check if the execution should be started + let array = this.start_time.split(":"); + let hour = parseInt(array[0]); + let minute = parseInt(array[1]); + this.cron = `${minute} ${hour} * * *`; this.duration = this.calcDuration(); log.debug("maintenance", "Cron: " + this.cron); log.debug("maintenance", "Duration: " + this.duration); From 2fd4e1cc72a7522df87310efdd2ff75c613f5159 Mon Sep 17 00:00:00 2001 From: "Otto Richter (fnetX)" Date: Thu, 17 Jul 2025 08:47:51 +0200 Subject: [PATCH 3/3] Matrix token command hint should send JSON (#5990) Co-authored-by: Otto Richter --- src/components/notifications/Matrix.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/notifications/Matrix.vue b/src/components/notifications/Matrix.vue index 60d43cf17..49c51f9e4 100644 --- a/src/components/notifications/Matrix.vue +++ b/src/components/notifications/Matrix.vue @@ -18,7 +18,7 @@ {{ $t("matrixDesc1") }}

- curl -XPOST -d '{"type": "m.login.password", "identifier": {"user": "botusername", "type": "m.id.user"}, "password": "passwordforuser"}' "https://home.server/_matrix/client/v3/login". + curl -XPOST --json '{"type": "m.login.password", "identifier": {"user": "botusername", "type": "m.id.user"}, "password": "passwordforuser"}' "https://home.server/_matrix/client/v3/login".