diff --git a/server/server.js b/server/server.js index d24cc0371..d6665a0c6 100644 --- a/server/server.js +++ b/server/server.js @@ -927,7 +927,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) @@ -935,54 +935,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/da-DK.js b/src/languages/da-DK.js index fa9ceac7c..86e1c0c9d 100644 --- a/src/languages/da-DK.js +++ b/src/languages/da-DK.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For hver ny overvåger aktiveres denne underretning som standard. Du kan stadig deaktivere underretningen separat for hver skærm.", "Default enabled": "Standard aktiveret", "Also apply to existing monitors": "Anvend også på eksisterende overvågere", - "Import/Export Backup": " Importér/Eksportér sikkerhedskopi", Export: "Eksport", Import: "Import", backupDescription: "Du kan sikkerhedskopiere alle Overvågere og alle underretninger til en JSON-fil.", diff --git a/src/languages/de-DE.js b/src/languages/de-DE.js index 243c2157d..008dbbc5f 100644 --- a/src/languages/de-DE.js +++ b/src/languages/de-DE.js @@ -113,6 +113,8 @@ export default { "Create your admin account": "Erstelle dein Admin Konto", "Repeat Password": "Wiederhole das Passwort", "Resource Record Type": "Resource Record Type", + "Export": "Export", + "Import": "Import", "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", @@ -128,6 +130,13 @@ 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", + 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", + "Options": "Optionen", + confirmImportMsg: "Möchtest du das Backup wirklich importieren? Bitte stelle sicher, dass die richtige Import Option ausgewählt ist.", + "Keep both": "Beide behalten", twoFAVerifyLabel: "Bitte trage deinen Token ein um zu verifizieren das 2FA funktioniert", "Verify Token": "Token verifizieren", "Setup 2FA": "2FA Einrichten", diff --git a/src/languages/en.js b/src/languages/en.js index a378ddcb3..9d88c46e1 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.", twoFAVerifyLabel: "Please type in your token to verify that 2FA is working", tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.", confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?", @@ -115,7 +117,8 @@ export default { "Last Result": "Last Result", "Create your admin account": "Create your admin account", "Repeat Password": "Repeat Password", - "Import/Export Backup": "Import/Export Backup", + "Import Backup": "Import Backup", + "Export Backup": "Export Backup", Export: "Export", Import: "Import", respTime: "Resp. Time (ms)", @@ -132,6 +135,11 @@ 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", + "Skip existing": "Skip existing", + "Overwrite": "Overwrite", + "Options": "Options", + "Keep both": "Keep both", "Verify Token": "Verify Token", "Setup 2FA": "Setup 2FA", "Enable 2FA": "Enable 2FA", diff --git a/src/languages/es-ES.js b/src/languages/es-ES.js index ca3e4d757..cf6951a44 100644 --- a/src/languages/es-ES.js +++ b/src/languages/es-ES.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/et-EE.js b/src/languages/et-EE.js index 551e0c675..14bedd178 100644 --- a/src/languages/et-EE.js +++ b/src/languages/et-EE.js @@ -113,7 +113,6 @@ export default { clearEventsMsg: "Kas soovid seire kõik sündmused kustutada?", clearHeartbeatsMsg: "Kas soovid seire kõik tuksed kustutada?", confirmClearStatisticsMsg: "Kas soovid KÕIK statistika kustutada?", - "Import/Export Backup": "Impordi/Ekspordi varukoopia", Export: "Eksport", Import: "Import", "Default enabled": "Kasuta vaikimisi", diff --git a/src/languages/fr-FR.js b/src/languages/fr-FR.js index 6d61beb00..ab03f68c7 100644 --- a/src/languages/fr-FR.js +++ b/src/languages/fr-FR.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/it-IT.js b/src/languages/it-IT.js index 89c33fd6a..6362f0143 100644 --- a/src/languages/it-IT.js +++ b/src/languages/it-IT.js @@ -127,6 +127,7 @@ export default { Events: "Eventi", Heartbeats: "Controlli", "Auto Get": "Auto Get", + "Also apply to existing monitors": "Also apply to existing monitors", backupDescription: "È possibile fare il backup di tutti i monitoraggi e di tutte le notifiche in un file JSON.", backupDescription2: "P.S.: lo storico e i dati relativi agli eventi non saranno inclusi.", backupDescription3: "Dati sensibili come i token di autenticazione saranno inclusi nel backup, tenere quindi in un luogo sicuro.", diff --git a/src/languages/ja.js b/src/languages/ja.js index eff5279f2..358df33c5 100644 --- a/src/languages/ja.js +++ b/src/languages/ja.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/ko-KR.js b/src/languages/ko-KR.js index e730d7148..349c3ae77 100644 --- a/src/languages/ko-KR.js +++ b/src/languages/ko-KR.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/nl-NL.js b/src/languages/nl-NL.js index 540d03c87..00dc41501 100644 --- a/src/languages/nl-NL.js +++ b/src/languages/nl-NL.js @@ -140,6 +140,7 @@ export default { "Two Factor Authentication": "Two Factor Authenticatie", Active: "Actief", Inactive: "Inactief", + "Also apply to existing monitors": "Also apply to existing monitors", Token: "Token", "Show URI": "Toon URI", "Clear all statistics": "Wis alle statistieken", diff --git a/src/languages/pl.js b/src/languages/pl.js index a63005aa3..e76c2f30c 100644 --- a/src/languages/pl.js +++ b/src/languages/pl.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/ru-RU.js b/src/languages/ru-RU.js index b1e2b1ef4..b25b5b122 100644 --- a/src/languages/ru-RU.js +++ b/src/languages/ru-RU.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/sr-latn.js b/src/languages/sr-latn.js index b0e5489f1..38a6fe736 100644 --- a/src/languages/sr-latn.js +++ b/src/languages/sr-latn.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/sr.js b/src/languages/sr.js index e6e3ba4c2..c163dcb64 100644 --- a/src/languages/sr.js +++ b/src/languages/sr.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/sv-SE.js b/src/languages/sv-SE.js index 38f27dac3..559dbb824 100644 --- a/src/languages/sv-SE.js +++ b/src/languages/sv-SE.js @@ -120,7 +120,6 @@ export default { enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", "Default enabled": "Default enabled", "Also apply to existing monitors": "Also apply to existing monitors", - "Import/Export Backup": "Import/Export Backup", Export: "Export", Import: "Import", backupDescription: "You can backup all monitors and all notifications into a JSON file.", diff --git a/src/languages/zh-CN.js b/src/languages/zh-CN.js index a19901685..f3e55fc8c 100644 --- a/src/languages/zh-CN.js +++ b/src/languages/zh-CN.js @@ -119,6 +119,7 @@ export default { "Auto Get": "自动获取", enableDefaultNotificationDescription: "新的监控项将默认启用,你也可以在每个监控项中分别设置", "Default enabled": "默认开启", + "Also apply to existing monitors": "应用到所有监控项", "Import/Export Backup": "导入/导出备份", Export: "导出", Import: "导入", diff --git a/src/languages/zh-HK.js b/src/languages/zh-HK.js index 187e1a12b..50959ca87 100644 --- a/src/languages/zh-HK.js +++ b/src/languages/zh-HK.js @@ -119,6 +119,7 @@ export default { "Auto Get": "自動獲取", enableDefaultNotificationDescription: "新增監測器時這個通知會預設啟用,當然每個監測器亦可分別控制開關。", "Default enabled": "預設通知", + "Also apply to existing monitors": "同時取用至目前所有監測器", "Import/Export Backup": "匯入/匯出 備份", Export: "匯出", Import: "匯入", diff --git a/src/mixins/socket.js b/src/mixins/socket.js index da6361486..ca69dee04 100644 --- a/src/mixins/socket.js +++ b/src/mixins/socket.js @@ -284,8 +284,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 0e809f736..0d8862292 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -127,27 +127,54 @@ -

{{ $t("Import/Export Backup") }}

+

{{ $t("Export Backup") }}

{{ $t("backupDescription") }}
({{ $t("backupDescription2") }})

-
- - - -
-
- {{ importAlert }} +
+

{{ $t("backupDescription3") }}

+

{{ $t("Import Backup") }}

+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ {{ $t("importHandleDescription") }} +
+ +
+ +
+ +
+ +
+ +
+ {{ importAlert }} +
+

{{ $t("Advanced") }}

@@ -273,6 +300,9 @@ {{ $t("confirmClearStatisticsMsg") }} + + {{ $t("confirmImportMsg") }} +
@@ -313,6 +343,7 @@ export default { }, loaded: false, importAlert: null, + importHandle: "skip", processing: false, } }, @@ -379,6 +410,10 @@ export default { this.$refs.confirmClearStatistics.show(); }, + confirmImport() { + this.$refs.confirmImport.show(); + }, + disableAuth() { this.settings.disableAuth = true; this.saveSettings(); @@ -424,7 +459,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) {