diff --git a/server/server.js b/server/server.js
index 2949c4be7..e4ad586aa 100644
--- a/server/server.js
+++ b/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);
}
}
diff --git a/src/languages/de-DE.js b/src/languages/de-DE.js
index a8cf5a7c0..083d939a4 100644
--- a/src/languages/de-DE.js
+++ b/src/languages/de-DE.js
@@ -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",
}
diff --git a/src/languages/en.js b/src/languages/en.js
index 585736857..14bf20b2d 100644
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -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",
}
diff --git a/src/mixins/socket.js b/src/mixins/socket.js
index 9771db0d2..e0088a59f 100644
--- a/src/mixins/socket.js
+++ b/src/mixins/socket.js
@@ -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) {
diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue
index cd1a95bc2..9502f11ce 100644
--- a/src/pages/Settings.vue
+++ b/src/pages/Settings.vue
@@ -127,14 +127,33 @@
({{ $t("backupDescription2") }})