|  | @ -26,6 +26,8 @@ debug("Importing http-graceful-shutdown"); | 
			
		
	
		
		
			
				
					|  |  | const gracefulShutdown = require("http-graceful-shutdown"); |  |  | const gracefulShutdown = require("http-graceful-shutdown"); | 
			
		
	
		
		
			
				
					|  |  | debug("Importing prometheus-api-metrics"); |  |  | debug("Importing prometheus-api-metrics"); | 
			
		
	
		
		
			
				
					|  |  | const prometheusAPIMetrics = require("prometheus-api-metrics"); |  |  | const prometheusAPIMetrics = require("prometheus-api-metrics"); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | debug("Importing compare-versions"); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const compareVersions = require("compare-versions"); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | debug("Importing 2FA Modules"); |  |  | debug("Importing 2FA Modules"); | 
			
		
	
		
		
			
				
					|  |  | const notp = require("notp"); |  |  | const notp = require("notp"); | 
			
		
	
	
		
		
			
				
					|  | @ -943,16 +945,20 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         socket.on("uploadBackup", async (uploadedJSON, importHandle, callback) => { |  |  |         socket.on("uploadBackup", async (uploadedJSON, importHandle, callback) => { | 
			
		
	
		
		
			
				
					|  |  |             try { |  |  |             try { | 
			
		
	
		
		
			
				
					
					|  |  |                 checkLogin(socket); |  |  |                 checkLogin(socket) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let backupData = JSON.parse(uploadedJSON); |  |  |                 let backupData = JSON.parse(uploadedJSON); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`); |  |  |                 console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 let notificationListData = backupData.notificationList; |  |  |                 let notificationListData = backupData.notificationList; | 
			
		
	
		
		
			
				
					|  |  |                 let monitorListData = backupData.monitorList; |  |  |                 let monitorListData = backupData.monitorList; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 let version17x = compareVersions.compare(backupData.version, '1.7.0', '>=') | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 // If the import option is "overwrite" it'll clear most of the tables, except "settings" and "user"
 | 
			
		
	
		
		
			
				
					|  |  |                 if (importHandle == "overwrite") { |  |  |                 if (importHandle == "overwrite") { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     // Stops every monitor first, so it doesn't execute any heartbeat while importing
 | 
			
		
	
		
		
			
				
					|  |  |                     for (let id in monitorList) { |  |  |                     for (let id in monitorList) { | 
			
		
	
		
		
			
				
					|  |  |                         let monitor = monitorList[id]; |  |  |                         let monitor = monitorList[id]; | 
			
		
	
		
		
			
				
					|  |  |                         await monitor.stop(); |  |  |                         await monitor.stop(); | 
			
		
	
	
		
		
			
				
					|  | @ -961,14 +967,19 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                     await R.exec("DELETE FROM monitor_notification"); |  |  |                     await R.exec("DELETE FROM monitor_notification"); | 
			
		
	
		
		
			
				
					|  |  |                     await R.exec("DELETE FROM monitor_tls_info"); |  |  |                     await R.exec("DELETE FROM monitor_tls_info"); | 
			
		
	
		
		
			
				
					|  |  |                     await R.exec("DELETE FROM notification"); |  |  |                     await R.exec("DELETE FROM notification"); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     await R.exec("DELETE FROM monitor_tag"); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     await R.exec("DELETE FROM tag"); | 
			
		
	
		
		
			
				
					|  |  |                     await R.exec("DELETE FROM monitor"); |  |  |                     await R.exec("DELETE FROM monitor"); | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 // Only starts importing if the backup file contains at least one notification
 | 
			
		
	
		
		
			
				
					|  |  |                 if (notificationListData.length >= 1) { |  |  |                 if (notificationListData.length >= 1) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     // Get every existing notification name and puts them in one simple string
 | 
			
		
	
		
		
			
				
					|  |  |                     let notificationNameList = await R.getAll("SELECT name FROM notification"); |  |  |                     let notificationNameList = await R.getAll("SELECT name FROM notification"); | 
			
		
	
		
		
			
				
					|  |  |                     let notificationNameListString = JSON.stringify(notificationNameList); |  |  |                     let notificationNameListString = JSON.stringify(notificationNameList); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                     for (let i = 0; i < notificationListData.length; i++) { |  |  |                     for (let i = 0; i < notificationListData.length; i++) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         // Only starts importing the notification if the import option is "overwrite", "keep" or "skip" but the notification doesn't exists
 | 
			
		
	
		
		
			
				
					|  |  |                         if ((importHandle == "skip" && notificationNameListString.includes(notificationListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { |  |  |                         if ((importHandle == "skip" && notificationNameListString.includes(notificationListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                             let notification = JSON.parse(notificationListData[i].config); |  |  |                             let notification = JSON.parse(notificationListData[i].config); | 
			
		
	
	
		
		
			
				
					|  | @ -978,18 +989,39 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                     } |  |  |                     } | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 // Only starts importing if the backup file contains at least one monitor
 | 
			
		
	
		
		
			
				
					|  |  |                 if (monitorListData.length >= 1) { |  |  |                 if (monitorListData.length >= 1) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     // Get every existing monitor name and puts them in one simple string
 | 
			
		
	
		
		
			
				
					|  |  |                     let monitorNameList = await R.getAll("SELECT name FROM monitor"); |  |  |                     let monitorNameList = await R.getAll("SELECT name FROM monitor"); | 
			
		
	
		
		
			
				
					|  |  |                     let monitorNameListString = JSON.stringify(monitorNameList); |  |  |                     let monitorNameListString = JSON.stringify(monitorNameList); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                     for (let i = 0; i < monitorListData.length; i++) { |  |  |                     for (let i = 0; i < monitorListData.length; i++) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         // Only starts importing the monitor if the import option is "overwrite", "keep" or "skip" but the notification doesn't exists
 | 
			
		
	
		
		
			
				
					|  |  |                         if ((importHandle == "skip" && monitorNameListString.includes(monitorListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { |  |  |                         if ((importHandle == "skip" && monitorNameListString.includes(monitorListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             // Define in here every new variable for monitors which where implemented after the first version of the Import/Export function (1.6.0)
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             // --- Start ---
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             // Define default values
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             let retryInterval = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             /* | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             Only replace the default value with the backup file data for the specific version, where it appears the first time | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             More information about that where "let version" will be defined | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             if (version17x) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 retryInterval = monitorListData[i].retryInterval; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             // --- End ---
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                             let monitor = { |  |  |                             let monitor = { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 // Define the new variable from earlier here
 | 
			
		
	
		
		
			
				
					|  |  |                                 name: monitorListData[i].name, |  |  |                                 name: monitorListData[i].name, | 
			
		
	
		
		
			
				
					|  |  |                                 type: monitorListData[i].type, |  |  |                                 type: monitorListData[i].type, | 
			
		
	
		
		
			
				
					|  |  |                                 url: monitorListData[i].url, |  |  |                                 url: monitorListData[i].url, | 
			
		
	
		
		
			
				
					|  |  |                                 interval: monitorListData[i].interval, |  |  |                                 interval: monitorListData[i].interval, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 retryInterval: retryInterval, | 
			
		
	
		
		
			
				
					|  |  |                                 hostname: monitorListData[i].hostname, |  |  |                                 hostname: monitorListData[i].hostname, | 
			
		
	
		
		
			
				
					|  |  |                                 maxretries: monitorListData[i].maxretries, |  |  |                                 maxretries: monitorListData[i].maxretries, | 
			
		
	
		
		
			
				
					|  |  |                                 port: monitorListData[i].port, |  |  |                                 port: monitorListData[i].port, | 
			
		
	
	
		
		
			
				
					|  | @ -1015,8 +1047,43 @@ exports.entryPage = "dashboard"; | 
			
		
	
		
		
			
				
					|  |  |                             bean.user_id = socket.userID; |  |  |                             bean.user_id = socket.userID; | 
			
		
	
		
		
			
				
					|  |  |                             await R.store(bean); |  |  |                             await R.store(bean); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                             await updateMonitorNotification(bean.id, notificationIDList); |  |  |                             // Only for backup files with the version 1.7.0 or higher, since there was the tag feature implemented
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                             if (version17x) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 // Only import if the specific monitor has tags assigned
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 if (monitorListData[i].tags.length >= 1) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     for (let o = 0; o < monitorListData[i].tags.length; o++) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         // Check if tag already exists and get data ->
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         let tag = await R.findOne("tag", " name = ?", [ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             monitorListData[i].tags[o].name, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         ]) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         // Set tagId to vaule from database
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         let tagId = tag.id | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         // -> If it doesn't, create new tag from backup file
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         if (! tag) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             let beanTag = R.dispense("tag") | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             beanTag.name = monitorListData[i].tags[o].name | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             beanTag.color = monitorListData[i].tags[o].color | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             await R.store(beanTag) | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             tagId = beanTag.id | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         // Assign the new created tag to the monitor
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         await R.exec("INSERT INTO monitor_tag (tag_id, monitor_id, value) VALUES (?, ?, ?)", [ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             tagId, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             bean.id, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             monitorListData[i].tags[o].value, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         ]) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             await updateMonitorNotification(bean.id, notificationIDList) | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             // If monitor was active start it immediately, otherwise pause it
 | 
			
		
	
		
		
			
				
					|  |  |                             if (monitorListData[i].active == 1) { |  |  |                             if (monitorListData[i].active == 1) { | 
			
		
	
		
		
			
				
					|  |  |                                 await startMonitor(socket.userID, bean.id); |  |  |                                 await startMonitor(socket.userID, bean.id); | 
			
		
	
		
		
			
				
					|  |  |                             } else { |  |  |                             } else { | 
			
		
	
	
		
		
			
				
					|  | 
 |