From a2f1d61d3196d21ca8218a07f192d55825f0aa9b Mon Sep 17 00:00:00 2001 From: "F.D.Castel" Date: Thu, 14 Oct 2021 03:37:45 -0300 Subject: [PATCH 1/3] Initial support for https://github.com/louislam/uptime-kuma/issues/686. --- server/routers/api-router.js | 43 ++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/server/routers/api-router.js b/server/routers/api-router.js index fbe8136..c5a1333 100644 --- a/server/routers/api-router.js +++ b/server/routers/api-router.js @@ -17,13 +17,15 @@ router.get("/api/entry-page", async (_, response) => { }); router.get("/api/push/:pushToken", async (request, response) => { + const trx = await R.begin(); try { - let pushToken = request.params.pushToken; - let msg = request.query.msg || "OK"; - let ping = request.query.ping || null; - let monitor = await R.findOne("monitor", " push_token = ? AND active = 1 ", [ + let {msg, ping, ...requestTags} = request.query; + msg = msg || "OK"; + ping = ping || null; + + let monitor = await trx.findOne("monitor", " push_token = ? AND active = 1 ", [ pushToken ]); @@ -31,13 +33,36 @@ router.get("/api/push/:pushToken", async (request, response) => { throw new Error("Monitor not found or not active."); } - const previousHeartbeat = await R.getRow(` + const previousHeartbeat = await trx.getRow(` SELECT status, time FROM heartbeat WHERE id = (select MAX(id) from heartbeat where monitor_id = ?) `, [ monitor.id ]); + const tagKeys = Object.keys(requestTags) + if (tagKeys.length > 0) { + // Request has additional tags. Fetch all tags for this monitor. + const dbTags = await trx.getAll("SELECT tag.id, tag.name FROM tag JOIN monitor_tag ON monitor_tag.tag_id = tag.id AND monitor_tag.monitor_id = ?", [monitor.id]); + + // Update monitor_tag, ignoring non-existing request tags. + dbTags + .filter(tag => tagKeys.includes(tag.name)) + .forEach(async tag => { + const tagValue = requestTags[tag.name]; + + await trx.exec("UPDATE monitor_tag SET value = ? WHERE tag_id = ? AND monitor_id = ?", [ + tagValue, + tag.id, + monitor.id, + ]); + + // FixMe: Not working. What to emit here? + io.to(monitor.user_id).emit("addMonitorTag", tag.id, monitor.id, tagValue); + }); + } + + // FixMe: Bean returned by trx.dispense() has no .toJSON() method (!?). let status = UP; if (monitor.isUpsideDown()) { status = flipStatus(status); @@ -47,7 +72,7 @@ router.get("/api/push/:pushToken", async (request, response) => { let previousStatus = status; let duration = 0; - let bean = R.dispense("heartbeat"); + let bean = R.dispense("heartbeat"); // Should be trx.dispense(); bean.time = R.isoDateTime(dayjs.utc()); if (previousHeartbeat) { @@ -66,11 +91,13 @@ router.get("/api/push/:pushToken", async (request, response) => { bean.ping = ping; bean.duration = duration; - await R.store(bean); + await trx.store(bean); io.to(monitor.user_id).emit("heartbeat", bean.toJSON()); Monitor.sendStats(io, monitor.id, monitor.user_id); + await trx.commit(); + response.json({ ok: true, }); @@ -80,6 +107,8 @@ router.get("/api/push/:pushToken", async (request, response) => { } } catch (e) { + await trx.rollback(); + response.json({ ok: false, msg: e.message -- 2.43.0 From baa746c662b88614598c32012b3797c34a3448f4 Mon Sep 17 00:00:00 2001 From: "F.D.Castel" Date: Thu, 14 Oct 2021 19:11:51 -0300 Subject: [PATCH 2/3] For multiple tags with same name, updates the oldest one. (#704) --- server/routers/api-router.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/server/routers/api-router.js b/server/routers/api-router.js index c5a1333..492529f 100644 --- a/server/routers/api-router.js +++ b/server/routers/api-router.js @@ -43,35 +43,36 @@ router.get("/api/push/:pushToken", async (request, response) => { const tagKeys = Object.keys(requestTags) if (tagKeys.length > 0) { // Request has additional tags. Fetch all tags for this monitor. - const dbTags = await trx.getAll("SELECT tag.id, tag.name FROM tag JOIN monitor_tag ON monitor_tag.tag_id = tag.id AND monitor_tag.monitor_id = ?", [monitor.id]); + // For multiple tags with same name, get the oldest one. + const monitorTags = await trx.getAll("SELECT tag.name, MIN(monitor_tag.id) id FROM monitor_tag JOIN tag ON tag.id = monitor_tag.tag_id AND monitor_tag.monitor_id = ? GROUP BY tag.name ORDER BY 1", [monitor.id]); // Update monitor_tag, ignoring non-existing request tags. - dbTags - .filter(tag => tagKeys.includes(tag.name)) - .forEach(async tag => { - const tagValue = requestTags[tag.name]; + monitorTags + .filter(mt => tagKeys.includes(mt.name)) + .forEach(async mt => { + const tagValue = requestTags[mt.name]; - await trx.exec("UPDATE monitor_tag SET value = ? WHERE tag_id = ? AND monitor_id = ?", [ + await trx.exec("UPDATE monitor_tag SET value = ? WHERE id = ?", [ tagValue, - tag.id, - monitor.id, + mt.id ]); // FixMe: Not working. What to emit here? - io.to(monitor.user_id).emit("addMonitorTag", tag.id, monitor.id, tagValue); + io.to(monitor.user_id).emit("addMonitorTag", mt.id, monitor.id, tagValue); }); } - // FixMe: Bean returned by trx.dispense() has no .toJSON() method (!?). let status = UP; - if (monitor.isUpsideDown()) { - status = flipStatus(status); - } + // FixMe: monitor.isUpsideDown is not a function (?) + //if (monitor.isUpsideDown()) { + // status = flipStatus(status); + //} let isFirstBeat = true; let previousStatus = status; let duration = 0; + // FixMe: Bean returned by trx.dispense() has no .toJSON() method (!?). let bean = R.dispense("heartbeat"); // Should be trx.dispense(); bean.time = R.isoDateTime(dayjs.utc()); -- 2.43.0 From 5d9e98fbbc03c8d203bbd300a7950578501cd4a1 Mon Sep 17 00:00:00 2001 From: "F.D.Castel" Date: Fri, 22 Oct 2021 08:23:15 -0300 Subject: [PATCH 3/3] Remove transaction support. --- server/routers/api-router.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/server/routers/api-router.js b/server/routers/api-router.js index 492529f..0cb5caa 100644 --- a/server/routers/api-router.js +++ b/server/routers/api-router.js @@ -17,7 +17,6 @@ router.get("/api/entry-page", async (_, response) => { }); router.get("/api/push/:pushToken", async (request, response) => { - const trx = await R.begin(); try { let pushToken = request.params.pushToken; @@ -25,7 +24,7 @@ router.get("/api/push/:pushToken", async (request, response) => { msg = msg || "OK"; ping = ping || null; - let monitor = await trx.findOne("monitor", " push_token = ? AND active = 1 ", [ + let monitor = await R.findOne("monitor", " push_token = ? AND active = 1 ", [ pushToken ]); @@ -33,7 +32,7 @@ router.get("/api/push/:pushToken", async (request, response) => { throw new Error("Monitor not found or not active."); } - const previousHeartbeat = await trx.getRow(` + const previousHeartbeat = await R.getRow(` SELECT status, time FROM heartbeat WHERE id = (select MAX(id) from heartbeat where monitor_id = ?) `, [ @@ -44,7 +43,7 @@ router.get("/api/push/:pushToken", async (request, response) => { if (tagKeys.length > 0) { // Request has additional tags. Fetch all tags for this monitor. // For multiple tags with same name, get the oldest one. - const monitorTags = await trx.getAll("SELECT tag.name, MIN(monitor_tag.id) id FROM monitor_tag JOIN tag ON tag.id = monitor_tag.tag_id AND monitor_tag.monitor_id = ? GROUP BY tag.name ORDER BY 1", [monitor.id]); + const monitorTags = await R.getAll("SELECT tag.name, MIN(monitor_tag.id) id FROM monitor_tag JOIN tag ON tag.id = monitor_tag.tag_id AND monitor_tag.monitor_id = ? GROUP BY tag.name ORDER BY 1", [monitor.id]); // Update monitor_tag, ignoring non-existing request tags. monitorTags @@ -52,7 +51,7 @@ router.get("/api/push/:pushToken", async (request, response) => { .forEach(async mt => { const tagValue = requestTags[mt.name]; - await trx.exec("UPDATE monitor_tag SET value = ? WHERE id = ?", [ + await R.exec("UPDATE monitor_tag SET value = ? WHERE id = ?", [ tagValue, mt.id ]); @@ -63,17 +62,15 @@ router.get("/api/push/:pushToken", async (request, response) => { } let status = UP; - // FixMe: monitor.isUpsideDown is not a function (?) - //if (monitor.isUpsideDown()) { - // status = flipStatus(status); - //} + if (monitor.isUpsideDown()) { + status = flipStatus(status); + } let isFirstBeat = true; let previousStatus = status; let duration = 0; - // FixMe: Bean returned by trx.dispense() has no .toJSON() method (!?). - let bean = R.dispense("heartbeat"); // Should be trx.dispense(); + let bean = R.dispense("heartbeat"); bean.time = R.isoDateTime(dayjs.utc()); if (previousHeartbeat) { -- 2.43.0