From dcc91d6c7258707caf1df65eb07d3b21845dfc9e Mon Sep 17 00:00:00 2001
From: Louis Lam <louislam@users.noreply.github.com>
Date: Wed, 8 Dec 2021 14:59:59 +0800
Subject: [PATCH] Fix #922

---
 server/model/monitor.js      | 12 ++++++++++++
 server/routers/api-router.js | 12 ++++--------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/server/model/monitor.js b/server/model/monitor.js
index ab0c1d40..6aa614b7 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -296,6 +296,9 @@ class Monitor extends BeanModel {
                     debug("heartbeatCount" + heartbeatCount + " " + time);
 
                     if (heartbeatCount <= 0) {
+                        // Fix #922, since previous heartbeat could be inserted by api, it should get from database
+                        previousBeat = await Monitor.getPreviousHeartbeat(this.id);
+
                         throw new Error("No heartbeat in the time window");
                     } else {
                         // No need to insert successful heartbeat for push type, so end here
@@ -751,6 +754,15 @@ class Monitor extends BeanModel {
             debug("No notification, no need to send cert notification");
         }
     }
+
+    static async getPreviousHeartbeat(monitorID) {
+        return await R.getRow(`
+            SELECT status, time FROM heartbeat
+            WHERE id = (select MAX(id) from heartbeat where monitor_id = ?)
+        `, [
+            monitorID
+        ]);
+    }
 }
 
 module.exports = Monitor;
diff --git a/server/routers/api-router.js b/server/routers/api-router.js
index 79e82837..70d94673 100644
--- a/server/routers/api-router.js
+++ b/server/routers/api-router.js
@@ -31,12 +31,7 @@ router.get("/api/push/:pushToken", async (request, response) => {
             throw new Error("Monitor not found or not active.");
         }
 
-        const previousHeartbeat = await R.getRow(`
-            SELECT status, time FROM heartbeat
-            WHERE id = (select MAX(id) from heartbeat where monitor_id = ?)
-        `, [
-            monitor.id
-        ]);
+        const previousHeartbeat = await Monitor.getPreviousHeartbeat(monitor.id);
 
         let status = UP;
         if (monitor.isUpsideDown()) {
@@ -157,8 +152,9 @@ router.get("/api/status-page/monitor-list", cache("5 minutes"), async (_request,
                             JOIN tag
                             ON monitor_tag.tag_id = tag.id
                             WHERE monitor_tag.monitor_id = ?`, [monitor.id]
-                        );
-                    return {...monitor, tags: tags}
+                    );
+                    return { ...monitor,
+                        tags: tags };
                 }));
             }