From 885e66220631e52993b282eb4c75fb3927556066 Mon Sep 17 00:00:00 2001
From: Joseph <40335314+JRedOW@users.noreply.github.com>
Date: Sun, 16 Feb 2025 01:10:24 +0000
Subject: [PATCH 1/4] Refresh Certificate Expiry Times on Status Pages

---
 server/routers/status-page-router.js | 31 +++++++++++++++++++++++++++-
 src/components/PublicGroupList.vue   | 28 ++++++++++++++++---------
 src/pages/StatusPage.vue             |  5 +++--
 3 files changed, 51 insertions(+), 13 deletions(-)

diff --git a/server/routers/status-page-router.js b/server/routers/status-page-router.js
index 893f57564..70c448d2d 100644
--- a/server/routers/status-page-router.js
+++ b/server/routers/status-page-router.js
@@ -70,10 +70,12 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
     try {
         let heartbeatList = {};
         let uptimeList = {};
+        let certificateExpiryList = {};
 
         let slug = request.params.slug;
         slug = slug.toLowerCase();
         let statusPageID = await StatusPage.slugToID(slug);
+        let showCertificateExpiry = !!(await R.getCell("SELECT show_certificate_expiry FROM status_page WHERE id = ? ", [ statusPageID ]));
 
         let monitorIDList = await R.getCol(`
             SELECT monitor_group.monitor_id FROM monitor_group, \`group\`
@@ -99,11 +101,38 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
 
             const uptimeCalculator = await UptimeCalculator.getUptimeCalculator(monitorID);
             uptimeList[`${monitorID}_24`] = uptimeCalculator.get24Hour().uptime;
+
+            // Get Certificate Status (Copied from monitor.js getCertExpiry())
+            if (showCertificateExpiry) {
+                let tlsInfoBean = await R.findOne("monitor_tls_info", "monitor_id = ?", [
+                    monitorID,
+                ]);
+                let tlsInfo;
+                if (tlsInfoBean) {
+                    tlsInfo = JSON.parse(tlsInfoBean?.info_json);
+                    if (tlsInfo?.valid && tlsInfo?.certInfo?.daysRemaining) {
+                        certificateExpiryList[monitorID] = {
+                            certExpiryDaysRemaining: tlsInfo.certInfo.daysRemaining,
+                            validCert: true
+                        };
+                        certificateExpiryList[monitorID] = {
+                            certExpiryDaysRemaining: "10",
+                            validCert: true
+                        };
+                    } else {
+                        certificateExpiryList[monitorID] = {
+                            certExpiryDaysRemaining: "",
+                            validCert: false
+                        };
+                    }
+                }
+            }
         }
 
         response.json({
             heartbeatList,
-            uptimeList
+            uptimeList,
+            certificateExpiryList
         });
 
     } catch (error) {
diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index bacddbf13..a870eeaee 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -63,8 +63,15 @@
                                             </span>
                                         </div>
                                         <div class="extra-info">
-                                            <div v-if="showCertificateExpiry && monitor.element.certExpiryDaysRemaining">
-                                                <Tag :item="{name: $t('Cert Exp.'), value: formattedCertExpiryMessage(monitor), color: certExpiryColor(monitor)}" :size="'sm'" />
+                                            <div v-if="showCertificateExpiry && $root.certificateExpiryList[monitor.element.id].certExpiryDaysRemaining">
+                                                <Tag
+                                                    :item="{
+                                                        name: $t('Cert Exp.'),
+                                                        value: formattedCertExpiryMessage($root.certificateExpiryList[monitor.element.id]),
+                                                        color: certExpiryColor($root.certificateExpiryList[monitor.element.id])
+                                                    }"
+                                                    :size="'sm'"
+                                                />
                                             </div>
                                             <div v-if="showTags">
                                                 <Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" data-testid="monitor-tag" />
@@ -169,13 +176,14 @@ export default {
 
         /**
          * Returns formatted certificate expiry or Bad cert message
-         * @param {object} monitor Monitor to show expiry for
+         * @param {object} info Certificate information to show
          * @returns {string} Certificate expiry message
          */
-        formattedCertExpiryMessage(monitor) {
-            if (monitor?.element?.validCert && monitor?.element?.certExpiryDaysRemaining) {
-                return monitor.element.certExpiryDaysRemaining + " " + this.$tc("day", monitor.element.certExpiryDaysRemaining);
-            } else if (monitor?.element?.validCert === false) {
+        formattedCertExpiryMessage(info) {
+            console.log("TEST 123 FORMAT CERT");
+            if (info.validCert && info.certExpiryDaysRemaining) {
+                return info.certExpiryDaysRemaining + " " + this.$tc("day", info.certExpiryDaysRemaining);
+            } else if (info.validCert === false) {
                 return this.$t("noOrBadCertificate");
             } else {
                 return this.$t("Unknown") + " " + this.$tc("day", 2);
@@ -184,11 +192,11 @@ export default {
 
         /**
          * Returns certificate expiry color based on days remaining
-         * @param {object} monitor Monitor to show expiry for
+         * @param {object} info Certificate information to show
          * @returns {string} Color for certificate expiry
          */
-        certExpiryColor(monitor) {
-            if (monitor?.element?.validCert && monitor.element.certExpiryDaysRemaining > 7) {
+        certExpiryColor(info) {
+            if (info.validCert && info.certExpiryDaysRemaining > 7) {
                 return "#059669";
             }
             return "#DC2626";
diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue
index 116968282..4cacc5f32 100644
--- a/src/pages/StatusPage.vue
+++ b/src/pages/StatusPage.vue
@@ -765,17 +765,18 @@ export default {
         },
 
         /**
-         * Update the heartbeat list and update favicon if necessary
+         * Update the heartbeat list along with the favicon and certificate expiry if necessary
          * @returns {void}
          */
         updateHeartbeatList() {
             // If editMode, it will use the data from websocket.
             if (! this.editMode) {
                 axios.get("/api/status-page/heartbeat/" + this.slug).then((res) => {
-                    const { heartbeatList, uptimeList } = res.data;
+                    const { heartbeatList, uptimeList, certificateExpiryList } = res.data;
 
                     this.$root.heartbeatList = heartbeatList;
                     this.$root.uptimeList = uptimeList;
+                    this.$root.certificateExpiryList = certificateExpiryList;
 
                     const heartbeatIds = Object.keys(heartbeatList);
                     const downMonitors = heartbeatIds.reduce((downMonitorsAmount, currentId) => {

From 30da6e04f6276d2ad97d5e85cec8756271c2e12c Mon Sep 17 00:00:00 2001
From: Joseph <40335314+JRedOW@users.noreply.github.com>
Date: Sun, 16 Feb 2025 01:31:11 +0000
Subject: [PATCH 2/4] Remove Last Debug Elements

Oops
---
 server/routers/status-page-router.js | 4 ----
 src/components/PublicGroupList.vue   | 1 -
 2 files changed, 5 deletions(-)

diff --git a/server/routers/status-page-router.js b/server/routers/status-page-router.js
index 70c448d2d..060b6931c 100644
--- a/server/routers/status-page-router.js
+++ b/server/routers/status-page-router.js
@@ -115,10 +115,6 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
                             certExpiryDaysRemaining: tlsInfo.certInfo.daysRemaining,
                             validCert: true
                         };
-                        certificateExpiryList[monitorID] = {
-                            certExpiryDaysRemaining: "10",
-                            validCert: true
-                        };
                     } else {
                         certificateExpiryList[monitorID] = {
                             certExpiryDaysRemaining: "",
diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index a870eeaee..b122b18d9 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -180,7 +180,6 @@ export default {
          * @returns {string} Certificate expiry message
          */
         formattedCertExpiryMessage(info) {
-            console.log("TEST 123 FORMAT CERT");
             if (info.validCert && info.certExpiryDaysRemaining) {
                 return info.certExpiryDaysRemaining + " " + this.$tc("day", info.certExpiryDaysRemaining);
             } else if (info.validCert === false) {

From dc0d24e2f684be87956bc300929437d37dc64c71 Mon Sep 17 00:00:00 2001
From: Joseph <40335314+JRedOW@users.noreply.github.com>
Date: Sun, 16 Feb 2025 03:05:06 +0000
Subject: [PATCH 3/4] Fix Edge Case Issue

---
 src/components/PublicGroupList.vue | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index b122b18d9..017e80424 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -63,7 +63,11 @@
                                             </span>
                                         </div>
                                         <div class="extra-info">
-                                            <div v-if="showCertificateExpiry && $root.certificateExpiryList[monitor.element.id].certExpiryDaysRemaining">
+                                            <div
+                                                v-if="showCertificateExpiry &&
+                                                    $root.certificateExpiryList[monitor.element.id] &&
+                                                    $root.certificateExpiryList[monitor.element.id].certExpiryDaysRemaining"
+                                            >
                                                 <Tag
                                                     :item="{
                                                         name: $t('Cert Exp.'),

From e441b6d76b82ec22472f727fa814c766ac0981fc Mon Sep 17 00:00:00 2001
From: Joseph <40335314+JRedOW@users.noreply.github.com>
Date: Sat, 15 Feb 2025 22:56:11 -0500
Subject: [PATCH 4/4] Fix theoretical issue

---
 src/components/PublicGroupList.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index 017e80424..93ced63dc 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -65,7 +65,7 @@
                                         <div class="extra-info">
                                             <div
                                                 v-if="showCertificateExpiry &&
-                                                    $root.certificateExpiryList[monitor.element.id] &&
+                                                    $root.certificateExpiryList &&
                                                     $root.certificateExpiryList[monitor.element.id].certExpiryDaysRemaining"
                                             >
                                                 <Tag