Added import options
This commit is contained in:
		
							parent
							
								
									6caae725f9
								
							
						
					
					
						commit
						7fee4a7ea7
					
				
					 5 changed files with 111 additions and 46 deletions
				
			
		
							
								
								
									
										104
									
								
								server/server.js
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								server/server.js
									
									
									
									
									
								
							|  | @ -594,7 +594,7 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); | |||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         socket.on("uploadBackup", async (uploadedJSON, callback) => { | ||||
|         socket.on("uploadBackup", async (uploadedJSON, importHandle, callback) => { | ||||
|             try { | ||||
|                 checkLogin(socket) | ||||
| 
 | ||||
|  | @ -602,54 +602,80 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); | |||
| 
 | ||||
|                 console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`) | ||||
| 
 | ||||
|                 let notificationList = backupData.notificationList; | ||||
|                 let monitorList = backupData.monitorList; | ||||
|                 let notificationListData = backupData.notificationList; | ||||
|                 let monitorListData = backupData.monitorList; | ||||
| 
 | ||||
|                 if (notificationList.length >= 1) { | ||||
|                     for (let i = 0; i < notificationList.length; i++) { | ||||
|                         let notification = JSON.parse(notificationList[i].config); | ||||
|                         await Notification.save(notification, null, socket.userID) | ||||
|                 if (importHandle == "overwrite") { | ||||
|                     for (let id in monitorList) { | ||||
|                         let monitor = monitorList[id] | ||||
|                         await monitor.stop() | ||||
|                     } | ||||
|                     await R.exec("DELETE FROM heartbeat"); | ||||
|                     await R.exec("DELETE FROM monitor_notification"); | ||||
|                     await R.exec("DELETE FROM monitor_tls_info"); | ||||
|                     await R.exec("DELETE FROM notification"); | ||||
|                     await R.exec("DELETE FROM monitor"); | ||||
|                 } | ||||
| 
 | ||||
|                 if (notificationListData.length >= 1) { | ||||
|                     let notificationNameList = await R.getAll("SELECT name FROM notification"); | ||||
|                     let notificationNameListString = JSON.stringify(notificationNameList); | ||||
| 
 | ||||
|                     for (let i = 0; i < notificationListData.length; i++) { | ||||
|                         if ((importHandle == "skip" && notificationNameListString.includes(notificationListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { | ||||
| 
 | ||||
|                             let notification = JSON.parse(notificationListData[i].config); | ||||
|                             await Notification.save(notification, null, socket.userID) | ||||
| 
 | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (monitorList.length >= 1) { | ||||
|                     for (let i = 0; i < monitorList.length; i++) { | ||||
|                         let monitor = { | ||||
|                             name: monitorList[i].name, | ||||
|                             type: monitorList[i].type, | ||||
|                             url: monitorList[i].url, | ||||
|                             interval: monitorList[i].interval, | ||||
|                             hostname: monitorList[i].hostname, | ||||
|                             maxretries: monitorList[i].maxretries, | ||||
|                             port: monitorList[i].port, | ||||
|                             keyword: monitorList[i].keyword, | ||||
|                             ignoreTls: monitorList[i].ignoreTls, | ||||
|                             upsideDown: monitorList[i].upsideDown, | ||||
|                             maxredirects: monitorList[i].maxredirects, | ||||
|                             accepted_statuscodes: monitorList[i].accepted_statuscodes, | ||||
|                             dns_resolve_type: monitorList[i].dns_resolve_type, | ||||
|                             dns_resolve_server: monitorList[i].dns_resolve_server, | ||||
|                             notificationIDList: {}, | ||||
|                         } | ||||
|                 if (monitorListData.length >= 1) { | ||||
|                     let monitorNameList = await R.getAll("SELECT name FROM monitor"); | ||||
|                     let monitorNameListString = JSON.stringify(monitorNameList); | ||||
| 
 | ||||
|                         let bean = R.dispense("monitor") | ||||
|                     for (let i = 0; i < monitorListData.length; i++) { | ||||
|                         if ((importHandle == "skip" && monitorNameListString.includes(monitorListData[i].name) == false) || importHandle == "keep" || importHandle == "overwrite") { | ||||
| 
 | ||||
|                         let notificationIDList = monitor.notificationIDList; | ||||
|                         delete monitor.notificationIDList; | ||||
|                             let monitor = { | ||||
|                                 name: monitorListData[i].name, | ||||
|                                 type: monitorListData[i].type, | ||||
|                                 url: monitorListData[i].url, | ||||
|                                 interval: monitorListData[i].interval, | ||||
|                                 hostname: monitorListData[i].hostname, | ||||
|                                 maxretries: monitorListData[i].maxretries, | ||||
|                                 port: monitorListData[i].port, | ||||
|                                 keyword: monitorListData[i].keyword, | ||||
|                                 ignoreTls: monitorListData[i].ignoreTls, | ||||
|                                 upsideDown: monitorListData[i].upsideDown, | ||||
|                                 maxredirects: monitorListData[i].maxredirects, | ||||
|                                 accepted_statuscodes: monitorListData[i].accepted_statuscodes, | ||||
|                                 dns_resolve_type: monitorListData[i].dns_resolve_type, | ||||
|                                 dns_resolve_server: monitorListData[i].dns_resolve_server, | ||||
|                                 notificationIDList: {}, | ||||
|                             } | ||||
| 
 | ||||
|                         monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); | ||||
|                         delete monitor.accepted_statuscodes; | ||||
|                             let bean = R.dispense("monitor") | ||||
| 
 | ||||
|                         bean.import(monitor) | ||||
|                         bean.user_id = socket.userID | ||||
|                         await R.store(bean) | ||||
|                             let notificationIDList = monitor.notificationIDList; | ||||
|                             delete monitor.notificationIDList; | ||||
| 
 | ||||
|                         await updateMonitorNotification(bean.id, notificationIDList) | ||||
|                             monitor.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); | ||||
|                             delete monitor.accepted_statuscodes; | ||||
| 
 | ||||
|                             bean.import(monitor) | ||||
|                             bean.user_id = socket.userID | ||||
|                             await R.store(bean) | ||||
| 
 | ||||
|                             await updateMonitorNotification(bean.id, notificationIDList) | ||||
| 
 | ||||
|                             if (monitorListData[i].active == 1) { | ||||
|                                 await startMonitor(socket.userID, bean.id); | ||||
|                             } else { | ||||
|                                 await pauseMonitor(socket.userID, bean.id); | ||||
|                             } | ||||
| 
 | ||||
|                         if (monitorList[i].active == 1) { | ||||
|                             await startMonitor(socket.userID, bean.id); | ||||
|                         } else { | ||||
|                             await pauseMonitor(socket.userID, bean.id); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -128,5 +128,11 @@ export default { | |||
|     backupDescription3: "Sensible Daten wie Benachrichtigungstoken sind in der Exportdatei enthalten, bitte bewahre sie sorgfältig auf.", | ||||
|     alertNoFile: "Bitte wähle eine Datei zum importieren aus.", | ||||
|     alertWrongFileType: "Bitte wähle eine JSON Datei aus.", | ||||
|     "Clear all statistics": "Lösche alle Statistiken" | ||||
|     "Clear all statistics": "Lösche alle Statistiken", | ||||
|     importHandleDescription: "Wähle 'Vorhandene überspringen' aus, wenn jeder Monitor oder Benachrichtigung mit demselben Namen übersprungen werden soll. 'Überschreiben' löscht jeden vorhandenen Monitor sowie Benachrichtigungen.", | ||||
|     "Skip existing": "Vorhandene überspringen", | ||||
|     "Overwrite": "Überschreiben", | ||||
|     "Import Options": "Import Optionen", | ||||
|     confirmImportMsg: "Möchtest du das Backup wirklich importieren? Bitte stelle sicher, dass die richtige Import Option ausgewählt ist.", | ||||
|     "Keep both": "Beide behalten", | ||||
| } | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ export default { | |||
|     clearEventsMsg: "Are you sure want to delete all events for this monitor?", | ||||
|     clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", | ||||
|     confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", | ||||
|     importHandleDescription: "Choose 'Skip Existing' if you want to skip every monitor or notification with the same name. 'Overwrite' will delete every existing monitor and notification.", | ||||
|     confirmImportMsg: "Are you sure to import the backup? Please make sure you've selected the right import option.", | ||||
|     Settings: "Settings", | ||||
|     Dashboard: "Dashboard", | ||||
|     "New Update": "New Update", | ||||
|  | @ -128,5 +130,9 @@ export default { | |||
|     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||
|     alertNoFile: "Please select a file to import.", | ||||
|     alertWrongFileType: "Please select a JSON file.", | ||||
|     "Clear all statistics": "Clear all Statistics" | ||||
|     "Clear all statistics": "Clear all Statistics", | ||||
|     "Skip existing": "Skip existing", | ||||
|     "Overwrite": "Overwrite", | ||||
|     "Import Options": "Import Options", | ||||
|     "Keep both": "Keep both", | ||||
| } | ||||
|  |  | |||
|  | @ -256,8 +256,8 @@ export default { | |||
|             this.importantHeartbeatList = {} | ||||
|         }, | ||||
| 
 | ||||
|         uploadBackup(uploadedJSON, callback) { | ||||
|             socket.emit("uploadBackup", uploadedJSON, callback) | ||||
|         uploadBackup(uploadedJSON, importHandle, callback) { | ||||
|             socket.emit("uploadBackup", uploadedJSON, importHandle, callback) | ||||
|         }, | ||||
| 
 | ||||
|         clearEvents(monitorID, callback) { | ||||
|  |  | |||
|  | @ -127,14 +127,33 @@ | |||
|                                 ({{ $t("backupDescription2") }}) <br /> | ||||
|                             </p> | ||||
| 
 | ||||
|                             <div class="input-group mb-3"> | ||||
|                             <div class="input-group mb-2"> | ||||
|                                 <button class="btn btn-outline-primary" @click="downloadBackup">{{ $t("Export") }}</button> | ||||
|                                 <button type="button" class="btn btn-outline-primary" :disabled="processing" @click="importBackup"> | ||||
|                                 <button type="button" class="btn btn-outline-primary" :disabled="processing" @click="confirmImport"> | ||||
|                                     <div v-if="processing" class="spinner-border spinner-border-sm me-1"></div> | ||||
|                                     {{ $t("Import") }} | ||||
|                                 </button> | ||||
|                                 <input id="importBackup" type="file" class="form-control" accept="application/json"> | ||||
|                             </div> | ||||
| 
 | ||||
|                             <label class="form-label">{{ $t("Import Options") }}:</label> | ||||
|                             <br> | ||||
|                             <div class="form-check form-check-inline"> | ||||
|                                 <input v-model="importHandle" class="form-check-input" type="radio" name="radioImportHandle" id="radioKeep" value="keep"> | ||||
|                                 <label class="form-check-label" for="radioKeep">{{ $t("Keep both") }}</label> | ||||
|                             </div> | ||||
|                             <div class="form-check form-check-inline"> | ||||
|                                 <input v-model="importHandle" class="form-check-input" type="radio" name="radioImportHandle" id="radioSkip" value="skip"> | ||||
|                                 <label class="form-check-label" for="radioSkip">{{ $t("Skip existing") }}</label> | ||||
|                             </div> | ||||
|                             <div class="form-check form-check-inline"> | ||||
|                                 <input v-model="importHandle" class="form-check-input" type="radio" name="radioImportHandle" id="radioOverwrite" value="overwrite"> | ||||
|                                 <label class="form-check-label" for="radioOverwrite">{{ $t("Overwrite") }}</label> | ||||
|                             </div> | ||||
|                             <div class="form-text mb-2"> | ||||
|                                 {{ $t("importHandleDescription") }} | ||||
|                             </div> | ||||
| 
 | ||||
|                             <div v-if="importAlert" class="alert alert-danger mt-3" style="padding: 6px 16px;"> | ||||
|                                 {{ importAlert }} | ||||
|                             </div> | ||||
|  | @ -259,6 +278,9 @@ | |||
|             <Confirm ref="confirmClearStatistics" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="clearStatistics"> | ||||
|                 {{ $t("confirmClearStatisticsMsg") }} | ||||
|             </Confirm> | ||||
|             <Confirm ref="confirmImport" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="importBackup"> | ||||
|                 {{ $t("confirmImportMsg") }} | ||||
|             </Confirm> | ||||
|         </div> | ||||
|     </transition> | ||||
| </template> | ||||
|  | @ -297,6 +319,7 @@ export default { | |||
|             }, | ||||
|             loaded: false, | ||||
|             importAlert: null, | ||||
|             importHandle: "skip", | ||||
|             processing: false, | ||||
|         } | ||||
|     }, | ||||
|  | @ -363,6 +386,10 @@ export default { | |||
|             this.$refs.confirmClearStatistics.show(); | ||||
|         }, | ||||
| 
 | ||||
|         confirmImport() { | ||||
|             this.$refs.confirmImport.show(); | ||||
|         }, | ||||
| 
 | ||||
|         disableAuth() { | ||||
|             this.settings.disableAuth = true; | ||||
|             this.saveSettings(); | ||||
|  | @ -408,7 +435,7 @@ export default { | |||
|             fileReader.readAsText(uploadItem.item(0)); | ||||
| 
 | ||||
|             fileReader.onload = item => { | ||||
|                 this.$root.uploadBackup(item.target.result, (res) => { | ||||
|                 this.$root.uploadBackup(item.target.result, this.importHandle, (res) => { | ||||
|                     this.processing = false; | ||||
| 
 | ||||
|                     if (res.ok) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue