mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Feat: Add database storage for TLS info
This commit is contained in:
		
							
								
								
									
										9
									
								
								db/patch2.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								db/patch2.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					BEGIN TRANSACTION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CREATE TABLE monitor_tls_info (
 | 
				
			||||||
 | 
						id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
 | 
				
			||||||
 | 
						monitor_id INTEGER NOT NULL,
 | 
				
			||||||
 | 
						info_json TEXT
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COMMIT;
 | 
				
			||||||
@@ -8,7 +8,7 @@ class Database {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    static templatePath = "./db/kuma.db"
 | 
					    static templatePath = "./db/kuma.db"
 | 
				
			||||||
    static path =  './data/kuma.db';
 | 
					    static path =  './data/kuma.db';
 | 
				
			||||||
    static latestVersion = 1;
 | 
					    static latestVersion = 2;
 | 
				
			||||||
    static noReject = true;
 | 
					    static noReject = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static async patch() {
 | 
					    static async patch() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,8 +74,10 @@ class Monitor extends BeanModel {
 | 
				
			|||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    bean.msg = `${res.status} - ${res.statusText}`
 | 
					                    bean.msg = `${res.status} - ${res.statusText}`
 | 
				
			||||||
                    bean.ping = dayjs().valueOf() - startTime;
 | 
					                    bean.ping = dayjs().valueOf() - startTime;
 | 
				
			||||||
                    if (this.url.startsWith("https")) {
 | 
					
 | 
				
			||||||
                        Monitor.sendCertInfo(checkCertificate(res), io, this.id, this.user_id);
 | 
					                    // Check certificate if https is used
 | 
				
			||||||
 | 
					                    if (this.getUrl().protocol === "https:") {
 | 
				
			||||||
 | 
					                        await this.updateTlsInfo(checkCertificate(res));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (this.type === "http") {
 | 
					                    if (this.type === "http") {
 | 
				
			||||||
@@ -168,10 +170,35 @@ class Monitor extends BeanModel {
 | 
				
			|||||||
        clearInterval(this.heartbeatInterval)
 | 
					        clearInterval(this.heartbeatInterval)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Helper Method: 
 | 
				
			||||||
 | 
					    // returns URL object for further usage
 | 
				
			||||||
 | 
					    // returns null if url is invalid
 | 
				
			||||||
 | 
					    getUrl() {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            return new URL(this.url);
 | 
				
			||||||
 | 
					        } catch (_) {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Store TLS info to database
 | 
				
			||||||
 | 
					    async updateTlsInfo(checkCertificateResult) {
 | 
				
			||||||
 | 
					        let tls_info_bean = await R.findOne("monitor_tls_info", "monitor_id = ?", [
 | 
				
			||||||
 | 
					            this.id
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					        if (tls_info_bean == null) {
 | 
				
			||||||
 | 
					            tls_info_bean = R.dispense("monitor_tls_info");
 | 
				
			||||||
 | 
					            tls_info_bean.monitor_id = this.id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        tls_info_bean.info_json = JSON.stringify(checkCertificateResult);
 | 
				
			||||||
 | 
					        R.store(tls_info_bean);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static async sendStats(io, monitorID, userID) {
 | 
					    static async sendStats(io, monitorID, userID) {
 | 
				
			||||||
        Monitor.sendAvgPing(24, io, monitorID, userID);
 | 
					        Monitor.sendAvgPing(24, io, monitorID, userID);
 | 
				
			||||||
        Monitor.sendUptime(24, io, monitorID, userID);
 | 
					        Monitor.sendUptime(24, io, monitorID, userID);
 | 
				
			||||||
        Monitor.sendUptime(24 * 30, io, monitorID, userID);
 | 
					        Monitor.sendUptime(24 * 30, io, monitorID, userID);
 | 
				
			||||||
 | 
					        Monitor.sendCertInfo(io, monitorID, userID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -192,12 +219,13 @@ class Monitor extends BeanModel {
 | 
				
			|||||||
        io.to(userID).emit("avgPing", monitorID, avgPing);
 | 
					        io.to(userID).emit("avgPing", monitorID, avgPing);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    static async sendCertInfo(io, monitorID, userID) {
 | 
				
			||||||
     *
 | 
					         let tls_info = await R.findOne("monitor_tls_info", "monitor_id = ?", [
 | 
				
			||||||
     * @param checkCertificateResult : Object return result of checkCertificate
 | 
					            monitorID
 | 
				
			||||||
     */
 | 
					        ]);
 | 
				
			||||||
     static async sendCertInfo(checkCertificateResult, io, monitorID, userID) {
 | 
					        if (tls_info != null) {
 | 
				
			||||||
        io.to(userID).emit("certInfo", monitorID, checkCertificateResult);
 | 
					            io.to(userID).emit("certInfo", monitorID, tls_info.info_json);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,17 @@ export default {
 | 
				
			|||||||
            this.$router.push("/setup")
 | 
					            this.$router.push("/setup")
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        socket.on('monitorList', (data) => {
 | 
					        socket.on("monitorList", (data) => {
 | 
				
			||||||
 | 
					            // Add Helper function
 | 
				
			||||||
 | 
					            Object.entries(data).forEach(([monitorID, monitor]) => {
 | 
				
			||||||
 | 
					                monitor.getUrl = () => {
 | 
				
			||||||
 | 
					                    try {
 | 
				
			||||||
 | 
					                        return new URL(monitor.url);
 | 
				
			||||||
 | 
					                    } catch (_) {
 | 
				
			||||||
 | 
					                        return null;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
            this.monitorList = data;
 | 
					            this.monitorList = data;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -116,7 +126,7 @@ export default {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        socket.on('certInfo', (monitorID, data) => {
 | 
					        socket.on('certInfo', (monitorID, data) => {
 | 
				
			||||||
            this.certInfoList[monitorID] = data
 | 
					            this.certInfoList[monitorID] = JSON.parse(data)
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        socket.on('importantHeartbeatList', (monitorID, data) => {
 | 
					        socket.on('importantHeartbeatList', (monitorID, data) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,7 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="shadow-box big-padding text-center stats" v-if="monitor.type === 'http' && monitor.url.startsWith('https') && certInfo != null">
 | 
					    <div class="shadow-box big-padding text-center stats" v-if="monitor.type === 'http' && monitor.getUrl().protocol === 'https:' && certInfo != null">
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
            <div class="col">
 | 
					            <div class="col">
 | 
				
			||||||
                <h4>Certificate Info</h4>
 | 
					                <h4>Certificate Info</h4>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user