From 403202d4d424c2fb6c8d3441a11478e82ae0b65e Mon Sep 17 00:00:00 2001 From: Ponkhy Date: Thu, 9 Sep 2021 21:10:31 +0200 Subject: [PATCH 01/21] Added simple TOTP Two Factor Authentication --- db/patch12.sql | 10 ++ package.json | 4 + server/server.js | 168 +++++++++++++++++++++++++++++-- server/util-server.js | 10 ++ src/components/Login.vue | 25 ++++- src/components/TwoFADialog.vue | 178 +++++++++++++++++++++++++++++++++ src/languages/de-DE.js | 13 +++ src/languages/en.js | 15 ++- src/mixins/socket.js | 26 ++++- src/pages/Settings.vue | 11 ++ src/pages/Setup.vue | 2 +- 11 files changed, 447 insertions(+), 15 deletions(-) create mode 100644 db/patch12.sql create mode 100644 src/components/TwoFADialog.vue diff --git a/db/patch12.sql b/db/patch12.sql new file mode 100644 index 000000000..754ffdf7b --- /dev/null +++ b/db/patch12.sql @@ -0,0 +1,10 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +ALTER TABLE user + ADD twofa_secret VARCHAR(64); + +ALTER TABLE user + ADD twofa_status BOOLEAN default 0; + +COMMIT; diff --git a/package.json b/package.json index c04be03f4..e43e00944 100644 --- a/package.json +++ b/package.json @@ -56,20 +56,24 @@ "http-graceful-shutdown": "^3.1.4", "jsonwebtoken": "^8.5.1", "nodemailer": "^6.6.3", + "notp": "^2.0.3", "password-hash": "^1.2.2", "prom-client": "^13.2.0", "prometheus-api-metrics": "^3.2.0", + "qrcode": "^1.4.4", "redbean-node": "0.1.2", "socket.io": "^4.2.0", "socket.io-client": "^4.2.0", "sqlite3": "github:mapbox/node-sqlite3#593c9d", "tcp-ping": "^0.1.1", + "thirty-two": "^1.0.2", "v-pagination-3": "^0.1.6", "vue": "^3.2.8", "vue-chart-3": "^0.5.7", "vue-confirm-dialog": "^1.0.2", "vue-i18n": "^9.1.7", "vue-multiselect": "^3.0.0-alpha.2", + "vue-qrcode": "^1.0.0", "vue-router": "^4.0.11", "vue-toastification": "^2.0.0-rc.1" }, diff --git a/server/server.js b/server/server.js index 2949c4be7..9319fa914 100644 --- a/server/server.js +++ b/server/server.js @@ -22,11 +22,15 @@ const gracefulShutdown = require("http-graceful-shutdown"); debug("Importing prometheus-api-metrics"); const prometheusAPIMetrics = require("prometheus-api-metrics"); +debug("2FA Modules"); +const notp = require("notp"); +const base32 = require("thirty-two"); + console.log("Importing this project modules"); debug("Importing Monitor"); const Monitor = require("./model/monitor"); debug("Importing Settings"); -const { getSettings, setSettings, setting, initJWTSecret } = require("./util-server"); +const { getSettings, setSettings, setting, initJWTSecret, genSecret } = require("./util-server"); debug("Importing Notification"); const { Notification } = require("./notification"); @@ -219,12 +223,38 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); if (user) { afterLogin(socket, user) - callback({ - ok: true, - token: jwt.sign({ - username: data.username, - }, jwtSecret), - }) + if (user.twofaStatus == 0) { + callback({ + ok: true, + token: jwt.sign({ + username: data.username, + }, jwtSecret), + }) + } + + if (user.twofaStatus == 1 && !data.token) { + callback({ + tokenRequired: true, + }) + } + + if (data.token) { + let verify = notp.totp.verify(data.token, user.twofa_secret); + + if (verify && verify.delta == 0) { + callback({ + ok: true, + token: jwt.sign({ + username: data.username, + }, jwtSecret), + }) + } else { + callback({ + ok: false, + msg: "Token Invalid!", + }) + } + } } else { callback({ ok: false, @@ -240,6 +270,130 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); callback(); }); + socket.on("prepare2FA", async (callback) => { + try { + checkLogin(socket) + + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]) + + if (user.twofa_status == 0) { + let newSecret = await genSecret() + let encodedSecret = base32.encode(newSecret); + let uri = `otpauth://totp/UptimeKuma:${user.username}?secret=${encodedSecret}`; + + await R.exec("UPDATE `user` SET twofa_secret = ? WHERE id = ? ", [ + newSecret, + socket.userID, + ]); + + callback({ + ok: true, + uri: uri, + }) + } else { + callback({ + ok: false, + msg: "2FA is already enabled.", + }) + } + } catch (error) { + callback({ + ok: false, + msg: "Error while trying to prepare 2FA.", + }) + } + }); + + socket.on("save2FA", async (callback) => { + try { + checkLogin(socket) + + await R.exec("UPDATE `user` SET twofa_status = 1 WHERE id = ? ", [ + socket.userID, + ]); + + callback({ + ok: true, + msg: "2FA Enabled.", + }) + } catch (error) { + callback({ + ok: false, + msg: "Error while trying to change 2FA.", + }) + } + }); + + socket.on("disable2FA", async (callback) => { + try { + checkLogin(socket) + + await R.exec("UPDATE `user` SET twofa_status = 0 WHERE id = ? ", [ + socket.userID, + ]); + + callback({ + ok: true, + msg: "2FA Disabled.", + }) + } catch (error) { + callback({ + ok: false, + msg: "Error while trying to change 2FA.", + }) + } + }); + + socket.on("verifyToken", async (token, callback) => { + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]) + + let verify = notp.totp.verify(token, user.twofa_secret); + + if (verify && verify.delta == 0) { + callback({ + ok: true, + valid: true, + }) + } else { + callback({ + ok: false, + msg: "Token Invalid.", + valid: false, + }) + } + }); + + socket.on("twoFAStatus", async (callback) => { + checkLogin(socket) + + try { + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]) + + if (user.twofa_status == 1) { + callback({ + ok: true, + status: true, + }) + } else { + callback({ + ok: true, + status: false, + }) + } + } catch (error) { + callback({ + ok: false, + msg: "Error while trying to get 2FA status.", + }) + } + }); + socket.on("needSetup", async (callback) => { callback(needSetup); }); diff --git a/server/util-server.js b/server/util-server.js index a2fef0656..079bd82f3 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -271,3 +271,13 @@ exports.getTotalClientInRoom = (io, roomName) => { return 0; } } + +exports.genSecret = () => { + let secret = ""; + let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + let charsLength = chars.length; + for ( let i = 0; i < 64; i++ ) { + secret += chars.charAt(Math.floor(Math.random() * charsLength)); + } + return secret; +} diff --git a/src/components/Login.vue b/src/components/Login.vue index bd51759c7..ca36fdb9f 100644 --- a/src/components/Login.vue +++ b/src/components/Login.vue @@ -4,16 +4,23 @@

-
+
-
+
+
+
+ + +
+
+
@@ -42,16 +49,24 @@ export default { processing: false, username: "", password: "", - + token: "", res: null, + tokenRequired: false, } }, methods: { submit() { this.processing = true; - this.$root.login(this.username, this.password, (res) => { + + this.$root.login(this.username, this.password, this.token, (res) => { this.processing = false; - this.res = res; + console.log(res) + + if (res.tokenRequired) { + this.tokenRequired = true; + } else { + this.res = res; + } }) }, }, diff --git a/src/components/TwoFADialog.vue b/src/components/TwoFADialog.vue new file mode 100644 index 000000000..371462b9e --- /dev/null +++ b/src/components/TwoFADialog.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/src/languages/de-DE.js b/src/languages/de-DE.js index cfadf1709..b6bc676c4 100644 --- a/src/languages/de-DE.js +++ b/src/languages/de-DE.js @@ -128,4 +128,17 @@ 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.", + twoFAVerifyLabel: "Bitte trage deinen Token ein um zu verifizieren das 2FA funktioniert", + "Verify Token": "Token verifizieren", + "Setup 2FA": "2FA Einrichten", + "Enable 2FA": "2FA Aktivieren", + "Disable 2FA": "2FA deaktivieren", + "2FA Settings": "2FA Einstellungen", + confirmEnableTwoFAMsg: "Bist du sicher das du 2FA aktivieren möchtest?", + confirmDisableTwoFAMsg: "Bist du sicher das du 2FA deaktivieren möchtest?", + tokenValidSettingsMsg: "Token gültig! Du kannst jetzt die 2FA Einstellungen speichern.", + "Two Factor Authentication": "Zwei Faktor Authentifizierung", + Active: "Aktiv", + Inactive: "Inaktiv", + Token: "Token", } diff --git a/src/languages/en.js b/src/languages/en.js index 1272bf3ed..c7facb2ae 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -20,6 +20,10 @@ 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?", + twoFAVerifyLabel: "Please type in your token to verify that 2FA is working", + tokenValidSettingsMsg: "Token valid! You can now save the 2FA settings.", + confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", Settings: "Settings", Dashboard: "Dashboard", "New Update": "New Update", @@ -127,5 +131,14 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", } diff --git a/src/mixins/socket.js b/src/mixins/socket.js index 22cc25bfd..0cffbdc56 100644 --- a/src/mixins/socket.js +++ b/src/mixins/socket.js @@ -201,11 +201,15 @@ export default { } }, - login(username, password, callback) { + login(username, password, token, callback) { socket.emit("login", { username, password, + token, }, (res) => { + if (res.tokenRequired) { + callback(res) + } if (res.ok) { this.storage().token = res.token; @@ -240,6 +244,26 @@ export default { this.clearData() }, + prepare2FA(callback) { + socket.emit("prepare2FA", callback) + }, + + save2FA(secret, callback) { + socket.emit("save2FA", callback) + }, + + disable2FA(callback) { + socket.emit("disable2FA", callback) + }, + + verifyToken(token, callback) { + socket.emit("verifyToken", token, callback) + }, + + twoFAStatus(callback) { + socket.emit("twoFAStatus", callback) + }, + add(monitor, callback) { socket.emit("add", monitor, callback) }, diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue index 17c2630aa..33992a439 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -120,6 +120,14 @@ +

+ {{ $t("Two Factor Authentication") }} +

+ +
+ +
+

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

@@ -186,6 +194,7 @@ +

@@ -446,10 +446,6 @@ export default { color: #fff; } -.me-1 { - margin-bottom: .25rem; -} - .dark { .list-group-item { background-color: $dark-bg2; From 8205f90f3d9fb81b76e392ee13011952122d4760 Mon Sep 17 00:00:00 2001 From: LouisLam Date: Mon, 13 Sep 2021 00:45:43 +0800 Subject: [PATCH 20/21] update language files --- src/languages/da-DK.js | 18 +++++++++++++++++- src/languages/es-ES.js | 18 +++++++++++++++++- src/languages/et-EE.js | 18 +++++++++++++++++- src/languages/fr-FR.js | 18 +++++++++++++++++- src/languages/it-IT.js | 18 +++++++++++++++++- src/languages/ja.js | 18 +++++++++++++++++- src/languages/ko-KR.js | 18 +++++++++++++++++- src/languages/nl-NL.js | 18 +++++++++++++++++- src/languages/pl.js | 18 +++++++++++++++++- src/languages/ru-RU.js | 18 +++++++++++++++++- src/languages/sr-latn.js | 18 +++++++++++++++++- src/languages/sr.js | 18 +++++++++++++++++- src/languages/sv-SE.js | 18 +++++++++++++++++- src/languages/zh-CN.js | 19 +++++++++++++++++-- src/languages/zh-HK.js | 19 +++++++++++++++++-- 15 files changed, 255 insertions(+), 17 deletions(-) diff --git a/src/languages/da-DK.js b/src/languages/da-DK.js index 6e8069aa1..c43e3181a 100644 --- a/src/languages/da-DK.js +++ b/src/languages/da-DK.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: Historik og hændelsesdata er ikke inkluderet.", backupDescription3: "Følsom data, f.eks. underretnings-tokener, er inkluderet i eksportfilen. Gem den sikkert.", alertNoFile: "Vælg en fil der skal importeres.", - alertWrongFileType: "Vælg venligst en JSON-fil." + alertWrongFileType: "Vælg venligst en JSON-fil.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/es-ES.js b/src/languages/es-ES.js index b52c1654f..7b24bcd04 100644 --- a/src/languages/es-ES.js +++ b/src/languages/es-ES.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/et-EE.js b/src/languages/et-EE.js index fca24a33d..c196da13f 100644 --- a/src/languages/et-EE.js +++ b/src/languages/et-EE.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: Varukoopia EI sisalda seirete ajalugu ja sündmustikku.", backupDescription3: "Varukoopiad sisaldavad teavitusmeetodite pääsuvõtmeid.", alertNoFile: "Palun lisa fail, mida importida.", - alertWrongFileType: "Palun lisa JSON-formaadis fail." + alertWrongFileType: "Palun lisa JSON-formaadis fail.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/fr-FR.js b/src/languages/fr-FR.js index 4821b818c..137148623 100644 --- a/src/languages/fr-FR.js +++ b/src/languages/fr-FR.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/it-IT.js b/src/languages/it-IT.js index 1d337810c..5c171bec6 100644 --- a/src/languages/it-IT.js +++ b/src/languages/it-IT.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/ja.js b/src/languages/ja.js index 6d0693d5a..2e1b5f33e 100644 --- a/src/languages/ja.js +++ b/src/languages/ja.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/ko-KR.js b/src/languages/ko-KR.js index 68479ade1..2f9a002dd 100644 --- a/src/languages/ko-KR.js +++ b/src/languages/ko-KR.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/nl-NL.js b/src/languages/nl-NL.js index 48e3b3a29..80b69fd9d 100644 --- a/src/languages/nl-NL.js +++ b/src/languages/nl-NL.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/pl.js b/src/languages/pl.js index 3029b3497..1b5ffd139 100644 --- a/src/languages/pl.js +++ b/src/languages/pl.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/ru-RU.js b/src/languages/ru-RU.js index 7f5eae760..11ad56874 100644 --- a/src/languages/ru-RU.js +++ b/src/languages/ru-RU.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/sr-latn.js b/src/languages/sr-latn.js index 3dd73d2cc..251be1556 100644 --- a/src/languages/sr-latn.js +++ b/src/languages/sr-latn.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/sr.js b/src/languages/sr.js index 6931d272e..d213732f9 100644 --- a/src/languages/sr.js +++ b/src/languages/sr.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/sv-SE.js b/src/languages/sv-SE.js index f8749e289..4ab1a7394 100644 --- a/src/languages/sv-SE.js +++ b/src/languages/sv-SE.js @@ -127,5 +127,21 @@ export default { backupDescription2: "PS: History and event data is not included.", 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." + alertWrongFileType: "Please select a JSON file.", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "Apply on all existing monitors", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/zh-CN.js b/src/languages/zh-CN.js index 1d15c3d95..488beaa38 100644 --- a/src/languages/zh-CN.js +++ b/src/languages/zh-CN.js @@ -119,7 +119,6 @@ export default { "Auto Get": "自动获取", enableDefaultNotificationDescription: "新的监控项将默认启用,你也可以在每个监控项中分别设置", "Default enabled": "默认开启", - "Also apply to existing monitors": "应用到所有监控项", "Import/Export Backup": "导入/导出备份", Export: "导出", Import: "导入", @@ -127,5 +126,21 @@ export default { backupDescription2: "注意: 不包括历史状态和事件数据", backupDescription3: "导出的文件中可能包含敏感信息,如消息通知的 Token 信息,请小心存放!", alertNoFile: "请选择一个文件导入", - alertWrongFileType: "请选择一个 JSON 格式的文件" + alertWrongFileType: "请选择一个 JSON 格式的文件", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "应用到所有监控项", + "Verify Token": "Verify Token", + "Setup 2FA": "Setup 2FA", + "Enable 2FA": "Enable 2FA", + "Disable 2FA": "Disable 2FA", + "2FA Settings": "2FA Settings", + "Two Factor Authentication": "Two Factor Authentication", + Active: "Active", + Inactive: "Inactive", + Token: "Token", + "Show URI": "Show URI", + "Clear all statistics": "Clear all Statistics" } diff --git a/src/languages/zh-HK.js b/src/languages/zh-HK.js index 314b6e696..686f59701 100644 --- a/src/languages/zh-HK.js +++ b/src/languages/zh-HK.js @@ -119,7 +119,6 @@ export default { "Auto Get": "自動獲取", enableDefaultNotificationDescription: "新增監測器時這個通知會預設啟用,當然每個監測器亦可分別控制開關。", "Default enabled": "預設通知", - "Also apply to existing monitors": "同時取用至目前所有監測器", "Import/Export Backup": "匯入/匯出 備份", Export: "匯出", Import: "匯入", @@ -127,5 +126,21 @@ export default { backupDescription2: "註:此備份不包括歷史記錄。", backupDescription3: "此備份可能包含了一些敏感資料如通知裡的 Token,請小心保存備份。", alertNoFile: "請選擇一個檔案", - alertWrongFileType: "請選擇 JSON 檔案" + alertWrongFileType: "請選擇 JSON 檔案", + 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?", + confirmDisableTwoFAMsg: "Are you sure you want to disable 2FA?", + "Apply on all existing monitors": "套用至目前所有監測器", + "Verify Token": "驗証 Token", + "Setup 2FA": "設定 2FA", + "Enable 2FA": "開啟 2FA", + "Disable 2FA": "關閉 2FA", + "2FA Settings": "2FA 設定", + "Two Factor Authentication": "雙重認證", + Active: "生效", + Inactive: "未生效", + Token: "Token", + "Show URI": "顯示 URI", + "Clear all statistics": "清除所有歷史記錄" } From 7df9698e5d84d1458c9e2e0f3f58c48e15551d01 Mon Sep 17 00:00:00 2001 From: LouisLam Date: Mon, 13 Sep 2021 00:58:45 +0800 Subject: [PATCH 21/21] eslint: comma-dangle for language files --- .eslintrc.js | 8 ++++++++ src/languages/da-DK.js | 2 +- src/languages/de-DE.js | 6 +++--- src/languages/en.js | 2 +- src/languages/es-ES.js | 2 +- src/languages/et-EE.js | 2 +- src/languages/fr-FR.js | 2 +- src/languages/it-IT.js | 2 +- src/languages/ja.js | 2 +- src/languages/ko-KR.js | 2 +- src/languages/nl-NL.js | 2 +- src/languages/pl.js | 2 +- src/languages/ru-RU.js | 2 +- src/languages/sr-latn.js | 2 +- src/languages/sr.js | 2 +- src/languages/sv-SE.js | 2 +- src/languages/zh-CN.js | 2 +- src/languages/zh-HK.js | 2 +- src/pages/EditMonitor.vue | 1 + 19 files changed, 28 insertions(+), 19 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 6704a85b2..398d64c84 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -82,4 +82,12 @@ module.exports = { "one-var": ["error", "never"], "max-statements-per-line": ["error", { "max": 1 }] }, + "overrides": [ + { + "files": [ "src/languages/*.js" ], + "rules": { + "comma-dangle": ["error", "always-multiline"], + } + } + ] } diff --git a/src/languages/da-DK.js b/src/languages/da-DK.js index c43e3181a..fa9ceac7c 100644 --- a/src/languages/da-DK.js +++ b/src/languages/da-DK.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/de-DE.js b/src/languages/de-DE.js index cff49cb0c..223d23b92 100644 --- a/src/languages/de-DE.js +++ b/src/languages/de-DE.js @@ -114,8 +114,8 @@ export default { "Repeat Password": "Wiederhole das Passwort", "Resource Record Type": "Resource Record Type", "Import/Export Backup": "Import/Export Backup", - "Export": "Export", - "Import": "Import", + Export: "Export", + Import: "Import", respTime: "Antw. Zeit (ms)", notAvailableShort: "N/A", "Default enabled": "Standardmäßig aktiviert", @@ -142,5 +142,5 @@ export default { Inactive: "Inaktiv", Token: "Token", "Show URI": "URI Anzeigen", - "Clear all statistics": "Lösche alle Statistiken" + "Clear all statistics": "Lösche alle Statistiken", } diff --git a/src/languages/en.js b/src/languages/en.js index 9b692b517..9b3e5422a 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -142,5 +142,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/es-ES.js b/src/languages/es-ES.js index 7b24bcd04..ca3e4d757 100644 --- a/src/languages/es-ES.js +++ b/src/languages/es-ES.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/et-EE.js b/src/languages/et-EE.js index c196da13f..551e0c675 100644 --- a/src/languages/et-EE.js +++ b/src/languages/et-EE.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/fr-FR.js b/src/languages/fr-FR.js index 137148623..6d61beb00 100644 --- a/src/languages/fr-FR.js +++ b/src/languages/fr-FR.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/it-IT.js b/src/languages/it-IT.js index 5c171bec6..a2e1d5b5f 100644 --- a/src/languages/it-IT.js +++ b/src/languages/it-IT.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/ja.js b/src/languages/ja.js index 2e1b5f33e..eff5279f2 100644 --- a/src/languages/ja.js +++ b/src/languages/ja.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/ko-KR.js b/src/languages/ko-KR.js index 2f9a002dd..e730d7148 100644 --- a/src/languages/ko-KR.js +++ b/src/languages/ko-KR.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/nl-NL.js b/src/languages/nl-NL.js index 80b69fd9d..8e61125f4 100644 --- a/src/languages/nl-NL.js +++ b/src/languages/nl-NL.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/pl.js b/src/languages/pl.js index 1b5ffd139..a63005aa3 100644 --- a/src/languages/pl.js +++ b/src/languages/pl.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/ru-RU.js b/src/languages/ru-RU.js index 11ad56874..b1e2b1ef4 100644 --- a/src/languages/ru-RU.js +++ b/src/languages/ru-RU.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/sr-latn.js b/src/languages/sr-latn.js index 251be1556..b0e5489f1 100644 --- a/src/languages/sr-latn.js +++ b/src/languages/sr-latn.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/sr.js b/src/languages/sr.js index d213732f9..e6e3ba4c2 100644 --- a/src/languages/sr.js +++ b/src/languages/sr.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/sv-SE.js b/src/languages/sv-SE.js index 4ab1a7394..38f27dac3 100644 --- a/src/languages/sv-SE.js +++ b/src/languages/sv-SE.js @@ -143,5 +143,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/zh-CN.js b/src/languages/zh-CN.js index 488beaa38..a19901685 100644 --- a/src/languages/zh-CN.js +++ b/src/languages/zh-CN.js @@ -142,5 +142,5 @@ export default { Inactive: "Inactive", Token: "Token", "Show URI": "Show URI", - "Clear all statistics": "Clear all Statistics" + "Clear all statistics": "Clear all Statistics", } diff --git a/src/languages/zh-HK.js b/src/languages/zh-HK.js index 686f59701..187e1a12b 100644 --- a/src/languages/zh-HK.js +++ b/src/languages/zh-HK.js @@ -142,5 +142,5 @@ export default { Inactive: "未生效", Token: "Token", "Show URI": "顯示 URI", - "Clear all statistics": "清除所有歷史記錄" + "Clear all statistics": "清除所有歷史記錄", } diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 420c4900e..f98bb7560 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -219,6 +219,7 @@ export default { dnsresolvetypeOptions: [], // Source: https://digitalfortress.tech/tips/top-15-commonly-used-regex/ + // eslint-disable-next-line ipRegexPattern: "((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))", } },