mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-01 03:49:24 +08:00 
			
		
		
		
	Merge branch 'master' into public-dashboard
# Conflicts: # server/database.js # server/server.js # server/util-server.js
This commit is contained in:
		| @@ -82,4 +82,12 @@ module.exports = { | |||||||
|         "one-var": ["error", "never"], |         "one-var": ["error", "never"], | ||||||
|         "max-statements-per-line": ["error", { "max": 1 }] |         "max-statements-per-line": ["error", { "max": 1 }] | ||||||
|     }, |     }, | ||||||
|  |     "overrides": [ | ||||||
|  |         { | ||||||
|  |             "files": [ "src/languages/*.js" ], | ||||||
|  |             "rules": { | ||||||
|  |                 "comma-dangle": ["error", "always-multiline"], | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     ] | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								db/patch-2fa.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								db/patch-2fa.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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 NOT NULL; | ||||||
|  |  | ||||||
|  | COMMIT; | ||||||
							
								
								
									
										823
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										823
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -10,6 +10,8 @@ | |||||||
|         "node": "14.*" |         "node": "14.*" | ||||||
|     }, |     }, | ||||||
|     "scripts": { |     "scripts": { | ||||||
|  |         "install-legacy-peer-deps": "npm install --legacy-peer-deps", | ||||||
|  |         "update-legacy-peer-deps": "npm update --legacy-peer-deps", | ||||||
|         "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", |         "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", | ||||||
|         "lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore", |         "lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore", | ||||||
|         "lint": "npm run lint:js && npm run lint:style", |         "lint": "npm run lint:js && npm run lint:style", | ||||||
| @@ -56,20 +58,24 @@ | |||||||
|         "http-graceful-shutdown": "^3.1.4", |         "http-graceful-shutdown": "^3.1.4", | ||||||
|         "jsonwebtoken": "^8.5.1", |         "jsonwebtoken": "^8.5.1", | ||||||
|         "nodemailer": "^6.6.3", |         "nodemailer": "^6.6.3", | ||||||
|  |         "notp": "^2.0.3", | ||||||
|         "password-hash": "^1.2.2", |         "password-hash": "^1.2.2", | ||||||
|         "prom-client": "^13.2.0", |         "prom-client": "^13.2.0", | ||||||
|         "prometheus-api-metrics": "^3.2.0", |         "prometheus-api-metrics": "^3.2.0", | ||||||
|  |         "qrcode": "^1.4.4", | ||||||
|         "redbean-node": "0.1.2", |         "redbean-node": "0.1.2", | ||||||
|         "socket.io": "^4.2.0", |         "socket.io": "^4.2.0", | ||||||
|         "socket.io-client": "^4.2.0", |         "socket.io-client": "^4.2.0", | ||||||
|         "sqlite3": "github:mapbox/node-sqlite3#593c9d", |         "sqlite3": "github:mapbox/node-sqlite3#593c9d", | ||||||
|         "tcp-ping": "^0.1.1", |         "tcp-ping": "^0.1.1", | ||||||
|  |         "thirty-two": "^1.0.2", | ||||||
|         "v-pagination-3": "^0.1.6", |         "v-pagination-3": "^0.1.6", | ||||||
|         "vue": "^3.2.8", |         "vue": "^3.2.8", | ||||||
|         "vue-chart-3": "^0.5.7", |         "vue-chart-3": "^0.5.7", | ||||||
|         "vue-confirm-dialog": "^1.0.2", |         "vue-confirm-dialog": "^1.0.2", | ||||||
|         "vue-i18n": "^9.1.7", |         "vue-i18n": "^9.1.7", | ||||||
|         "vue-multiselect": "^3.0.0-alpha.2", |         "vue-multiselect": "^3.0.0-alpha.2", | ||||||
|  |         "vue-qrcode": "^1.0.0", | ||||||
|         "vue-router": "^4.0.11", |         "vue-router": "^4.0.11", | ||||||
|         "vue-toastification": "^2.0.0-rc.1" |         "vue-toastification": "^2.0.0-rc.1" | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ class Database { | |||||||
|         "patch-setting-value-type.sql": true, |         "patch-setting-value-type.sql": true, | ||||||
|         "patch-improve-performance.sql": true, |         "patch-improve-performance.sql": true, | ||||||
|         "patch-monitor-public.sql": true, |         "patch-monitor-public.sql": true, | ||||||
|  |         "patch-2fa.sql": true, | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
							
								
								
									
										168
									
								
								server/server.js
									
									
									
									
									
								
							
							
						
						
									
										168
									
								
								server/server.js
									
									
									
									
									
								
							| @@ -22,11 +22,15 @@ 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 2FA Modules"); | ||||||
|  | const notp = require("notp"); | ||||||
|  | const base32 = require("thirty-two"); | ||||||
|  |  | ||||||
| console.log("Importing this project modules"); | console.log("Importing this project modules"); | ||||||
| debug("Importing Monitor"); | debug("Importing Monitor"); | ||||||
| const Monitor = require("./model/monitor"); | const Monitor = require("./model/monitor"); | ||||||
| debug("Importing Settings"); | debug("Importing Settings"); | ||||||
| const { getSettings, setSettings, setting, initJWTSecret, allowDevAllOrigin } = require("./util-server"); | const { getSettings, setSettings, setting, initJWTSecret, genSecret, allowDevAllOrigin } = require("./util-server"); | ||||||
|  |  | ||||||
| debug("Importing Notification"); | debug("Importing Notification"); | ||||||
| const { Notification } = require("./notification"); | const { Notification } = require("./notification"); | ||||||
| @@ -269,12 +273,38 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); | |||||||
|             if (user) { |             if (user) { | ||||||
|                 afterLogin(socket, user) |                 afterLogin(socket, user) | ||||||
|  |  | ||||||
|                 callback({ |                 if (user.twofaStatus == 0) { | ||||||
|                     ok: true, |                     callback({ | ||||||
|                     token: jwt.sign({ |                         ok: true, | ||||||
|                         username: data.username, |                         token: jwt.sign({ | ||||||
|                     }, jwtSecret), |                             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: "Invalid Token!", | ||||||
|  |                         }) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } else { |             } else { | ||||||
|                 callback({ |                 callback({ | ||||||
|                     ok: false, |                     ok: false, | ||||||
| @@ -290,6 +320,130 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); | |||||||
|             callback(); |             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/Uptime%20Kuma:${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: "Invalid Token.", | ||||||
|  |                     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) => { |         socket.on("needSetup", async (callback) => { | ||||||
|             callback(needSetup); |             callback(needSetup); | ||||||
|         }); |         }); | ||||||
|   | |||||||
| @@ -273,6 +273,16 @@ exports.getTotalClientInRoom = (io, roomName) => { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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; | ||||||
|  | } | ||||||
|  |  | ||||||
| exports.allowDevAllOrigin = (res) => { | exports.allowDevAllOrigin = (res) => { | ||||||
|     if (process.env.NODE_ENV === "development") { |     if (process.env.NODE_ENV === "development") { | ||||||
|         exports.allowAllOrigin(res); |         exports.allowAllOrigin(res); | ||||||
|   | |||||||
| @@ -4,16 +4,23 @@ | |||||||
|             <form @submit.prevent="submit"> |             <form @submit.prevent="submit"> | ||||||
|                 <h1 class="h3 mb-3 fw-normal" /> |                 <h1 class="h3 mb-3 fw-normal" /> | ||||||
|  |  | ||||||
|                 <div class="form-floating"> |                 <div v-if="!tokenRequired" class="form-floating"> | ||||||
|                     <input id="floatingInput" v-model="username" type="text" class="form-control" placeholder="Username"> |                     <input id="floatingInput" v-model="username" type="text" class="form-control" placeholder="Username"> | ||||||
|                     <label for="floatingInput">{{ $t("Username") }}</label> |                     <label for="floatingInput">{{ $t("Username") }}</label> | ||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
|                 <div class="form-floating mt-3"> |                 <div v-if="!tokenRequired" class="form-floating mt-3"> | ||||||
|                     <input id="floatingPassword" v-model="password" type="password" class="form-control" placeholder="Password"> |                     <input id="floatingPassword" v-model="password" type="password" class="form-control" placeholder="Password"> | ||||||
|                     <label for="floatingPassword">{{ $t("Password") }}</label> |                     <label for="floatingPassword">{{ $t("Password") }}</label> | ||||||
|                 </div> |                 </div> | ||||||
|  |  | ||||||
|  |                 <div v-if="tokenRequired"> | ||||||
|  |                     <div class="form-floating mt-3"> | ||||||
|  |                         <input id="floatingToken" v-model="token" type="text" maxlength="6" class="form-control" placeholder="123456"> | ||||||
|  |                         <label for="floatingToken">{{ $t("Token") }}</label> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |  | ||||||
|                 <div class="form-check mb-3 mt-3 d-flex justify-content-center pe-4"> |                 <div class="form-check mb-3 mt-3 d-flex justify-content-center pe-4"> | ||||||
|                     <div class="form-check"> |                     <div class="form-check"> | ||||||
|                         <input id="remember" v-model="$root.remember" type="checkbox" value="remember-me" class="form-check-input"> |                         <input id="remember" v-model="$root.remember" type="checkbox" value="remember-me" class="form-check-input"> | ||||||
| @@ -42,16 +49,24 @@ export default { | |||||||
|             processing: false, |             processing: false, | ||||||
|             username: "", |             username: "", | ||||||
|             password: "", |             password: "", | ||||||
|  |             token: "", | ||||||
|             res: null, |             res: null, | ||||||
|  |             tokenRequired: false, | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     methods: { |     methods: { | ||||||
|         submit() { |         submit() { | ||||||
|             this.processing = true; |             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.processing = false; | ||||||
|                 this.res = res; |                 console.log(res) | ||||||
|  |  | ||||||
|  |                 if (res.tokenRequired) { | ||||||
|  |                     this.tokenRequired = true; | ||||||
|  |                 } else { | ||||||
|  |                     this.res = res; | ||||||
|  |                 } | ||||||
|             }) |             }) | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -410,7 +410,7 @@ | |||||||
|  |  | ||||||
|                             <div class="form-check form-switch"> |                             <div class="form-check form-switch"> | ||||||
|                                 <input v-model="notification.applyExisting" class="form-check-input" type="checkbox"> |                                 <input v-model="notification.applyExisting" class="form-check-input" type="checkbox"> | ||||||
|                                 <label class="form-check-label">{{ $t("Also apply to existing monitors") }}</label> |                                 <label class="form-check-label">{{ $t("Apply on all existing monitors") }}</label> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|   | |||||||
							
								
								
									
										178
									
								
								src/components/TwoFADialog.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								src/components/TwoFADialog.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | |||||||
|  | <template> | ||||||
|  |     <form @submit.prevent="submit"> | ||||||
|  |         <div ref="modal" class="modal fade" tabindex="-1" data-bs-backdrop="static"> | ||||||
|  |             <div class="modal-dialog"> | ||||||
|  |                 <div class="modal-content"> | ||||||
|  |                     <div class="modal-header"> | ||||||
|  |                         <h5 class="modal-title"> | ||||||
|  |                             {{ $t("Setup 2FA") }} | ||||||
|  |                             <span v-if="twoFAStatus == true" class="badge bg-primary">{{ $t("Active") }}</span> | ||||||
|  |                             <span v-if="twoFAStatus == false" class="badge bg-primary">{{ $t("Inactive") }}</span> | ||||||
|  |                         </h5> | ||||||
|  |                         <button :disabled="processing" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" /> | ||||||
|  |                     </div> | ||||||
|  |                     <div class="modal-body"> | ||||||
|  |                         <div class="mb-3"> | ||||||
|  |                             <div v-if="uri && twoFAStatus == false" class="mx-auto text-center" style="width: 210px;"> | ||||||
|  |                                 <vue-qrcode :key="uri" :value="uri" type="image/png" :quality="1" :color="{ light: '#ffffffff' }" /> | ||||||
|  |                                 <button v-show="!showURI" type="button" class="btn btn-outline-primary btn-sm mt-2" @click="showURI = true">{{ $t("Show URI") }}</button> | ||||||
|  |                             </div> | ||||||
|  |                             <p v-if="showURI && twoFAStatus == false" class="text-break mt-2">{{ uri }}</p> | ||||||
|  |  | ||||||
|  |                             <button v-if="uri == null && twoFAStatus == false" class="btn btn-primary" type="button" @click="prepare2FA()"> | ||||||
|  |                                 {{ $t("Enable 2FA") }} | ||||||
|  |                             </button> | ||||||
|  |  | ||||||
|  |                             <button v-if="twoFAStatus == true" class="btn btn-danger" type="button" :disabled="processing" @click="confirmDisableTwoFA()"> | ||||||
|  |                                 {{ $t("Disable 2FA") }} | ||||||
|  |                             </button> | ||||||
|  |  | ||||||
|  |                             <div v-if="uri && twoFAStatus == false" class="mt-3"> | ||||||
|  |                                 <label for="basic-url" class="form-label">{{ $t("twoFAVerifyLabel") }}</label> | ||||||
|  |                                 <div class="input-group"> | ||||||
|  |                                     <input v-model="token" type="text" maxlength="6" class="form-control"> | ||||||
|  |                                     <button class="btn btn-outline-primary" type="button" @click="verifyToken()">{{ $t("Verify Token") }}</button> | ||||||
|  |                                 </div> | ||||||
|  |                                 <p v-show="tokenValid" class="mt-2" style="color: green">{{ $t("tokenValidSettingsMsg") }}</p> | ||||||
|  |                             </div> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |  | ||||||
|  |                     <div v-if="uri && twoFAStatus == false" class="modal-footer"> | ||||||
|  |                         <button type="submit" class="btn btn-primary" :disabled="processing || tokenValid == false" @click="confirmEnableTwoFA()"> | ||||||
|  |                             <div v-if="processing" class="spinner-border spinner-border-sm me-1"></div> | ||||||
|  |                             {{ $t("Save") }} | ||||||
|  |                         </button> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </form> | ||||||
|  |  | ||||||
|  |     <Confirm ref="confirmEnableTwoFA" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="save2FA"> | ||||||
|  |         {{ $t("confirmEnableTwoFAMsg") }} | ||||||
|  |     </Confirm> | ||||||
|  |  | ||||||
|  |     <Confirm ref="confirmDisableTwoFA" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="disable2FA"> | ||||||
|  |         {{ $t("confirmDisableTwoFAMsg") }} | ||||||
|  |     </Confirm> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script lang="ts"> | ||||||
|  | import { Modal } from "bootstrap" | ||||||
|  | import Confirm from "./Confirm.vue"; | ||||||
|  | import VueQrcode from "vue-qrcode" | ||||||
|  | import { useToast } from "vue-toastification" | ||||||
|  | const toast = useToast() | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |     components: { | ||||||
|  |         Confirm, | ||||||
|  |         VueQrcode, | ||||||
|  |     }, | ||||||
|  |     props: {}, | ||||||
|  |     data() { | ||||||
|  |         return { | ||||||
|  |             processing: false, | ||||||
|  |             uri: null, | ||||||
|  |             tokenValid: false, | ||||||
|  |             twoFAStatus: null, | ||||||
|  |             token: null, | ||||||
|  |             showURI: false, | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     mounted() { | ||||||
|  |         this.modal = new Modal(this.$refs.modal) | ||||||
|  |         this.getStatus(); | ||||||
|  |     }, | ||||||
|  |     methods: { | ||||||
|  |         show() { | ||||||
|  |             this.modal.show() | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         confirmEnableTwoFA() { | ||||||
|  |             this.$refs.confirmEnableTwoFA.show() | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         confirmDisableTwoFA() { | ||||||
|  |             this.$refs.confirmDisableTwoFA.show() | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         prepare2FA() { | ||||||
|  |             this.processing = true; | ||||||
|  |  | ||||||
|  |             this.$root.getSocket().emit("prepare2FA", (res) => { | ||||||
|  |                 this.processing = false; | ||||||
|  |  | ||||||
|  |                 if (res.ok) { | ||||||
|  |                     this.uri = res.uri; | ||||||
|  |                 } else { | ||||||
|  |                     toast.error(res.msg); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         save2FA() { | ||||||
|  |             this.processing = true; | ||||||
|  |  | ||||||
|  |             this.$root.getSocket().emit("save2FA", (res) => { | ||||||
|  |                 this.processing = false; | ||||||
|  |  | ||||||
|  |                 if (res.ok) { | ||||||
|  |                     this.$root.toastRes(res) | ||||||
|  |                     this.getStatus(); | ||||||
|  |                     this.modal.hide(); | ||||||
|  |                 } else { | ||||||
|  |                     toast.error(res.msg); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         disable2FA() { | ||||||
|  |             this.processing = true; | ||||||
|  |  | ||||||
|  |             this.$root.getSocket().emit("disable2FA", (res) => { | ||||||
|  |                 this.processing = false; | ||||||
|  |  | ||||||
|  |                 if (res.ok) { | ||||||
|  |                     this.$root.toastRes(res) | ||||||
|  |                     this.getStatus(); | ||||||
|  |                     this.modal.hide(); | ||||||
|  |                 } else { | ||||||
|  |                     toast.error(res.msg); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         verifyToken() { | ||||||
|  |             this.$root.getSocket().emit("verifyToken", this.token, (res) => { | ||||||
|  |                 if (res.ok) { | ||||||
|  |                     this.tokenValid = res.valid; | ||||||
|  |                 } else { | ||||||
|  |                     toast.error(res.msg); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         getStatus() { | ||||||
|  |             this.$root.getSocket().emit("twoFAStatus", (res) => { | ||||||
|  |                 if (res.ok) { | ||||||
|  |                     this.twoFAStatus = res.status; | ||||||
|  |                 } else { | ||||||
|  |                     toast.error(res.msg); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | @import "../assets/vars.scss"; | ||||||
|  |  | ||||||
|  | .dark { | ||||||
|  |     .modal-dialog .form-text, .modal-dialog p { | ||||||
|  |         color: $dark-font-color; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -17,8 +17,8 @@ export default { | |||||||
|     Down: "Inaktiv", |     Down: "Inaktiv", | ||||||
|     Pending: "Afventer", |     Pending: "Afventer", | ||||||
|     Unknown: "Ukendt", |     Unknown: "Ukendt", | ||||||
|     Pause: "Pause", |     Pause: "Stands", | ||||||
|     pauseDashboardHome: "Pauset", |     pauseDashboardHome: "Standset", | ||||||
|     Name: "Navn", |     Name: "Navn", | ||||||
|     Status: "Status", |     Status: "Status", | ||||||
|     DateTime: "Dato / Tid", |     DateTime: "Dato / Tid", | ||||||
| @@ -36,8 +36,8 @@ export default { | |||||||
|     hour: "Timer", |     hour: "Timer", | ||||||
|     "-hour": "-Timer", |     "-hour": "-Timer", | ||||||
|     checkEverySecond: "Tjek hvert {0} sekund", |     checkEverySecond: "Tjek hvert {0} sekund", | ||||||
|     "Avg.": "Gennemsnit", |     "Avg.": "Gns.", | ||||||
|     Response: " Respons", |     Response: "Respons", | ||||||
|     Ping: "Ping", |     Ping: "Ping", | ||||||
|     "Monitor Type": "Overvåger Type", |     "Monitor Type": "Overvåger Type", | ||||||
|     Keyword: "Nøgleord", |     Keyword: "Nøgleord", | ||||||
| @@ -103,29 +103,45 @@ export default { | |||||||
|     "Resolver Server": "Navne-server", |     "Resolver Server": "Navne-server", | ||||||
|     rrtypeDescription: "Vælg den type RR, du vil overvåge.", |     rrtypeDescription: "Vælg den type RR, du vil overvåge.", | ||||||
|     "Last Result": "Seneste resultat", |     "Last Result": "Seneste resultat", | ||||||
|     pauseMonitorMsg: "Er du sikker på, at du vil pause Overvågeren?", |     pauseMonitorMsg: "Er du sikker på, at du vil standse Overvågeren?", | ||||||
|     "Create your admin account": "Opret din administratorkonto", |     "Create your admin account": "Opret din administratorkonto", | ||||||
|     "Repeat Password": "Gentag adgangskoden", |     "Repeat Password": "Gentag adgangskoden", | ||||||
|     "Resource Record Type": "Resource Record Type", |     "Resource Record Type": "Resource Record Type", | ||||||
|     respTime: "Resp. Time (ms)", |     respTime: "Resp. Tid (ms)", | ||||||
|     notAvailableShort: "N/A", |     notAvailableShort: "N/A", | ||||||
|     Create: "Create", |     Create: "Opret", | ||||||
|     clearEventsMsg: "Are you sure want to delete all events for this monitor?", |     clearEventsMsg: "Er du sikker på vil slette alle events for denne Overvåger?", | ||||||
|     clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |     clearHeartbeatsMsg: "Er du sikker på vil slette alle heartbeats for denne Overvåger?", | ||||||
|     confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |     confirmClearStatisticsMsg: "Vil du helt sikkert slette ALLE statistikker?", | ||||||
|     "Clear Data": "Clear Data", |     "Clear Data": "Ryd Data", | ||||||
|     Events: "Events", |     Events: "Events", | ||||||
|     Heartbeats: "Heartbeats", |     Heartbeats: "Heartbeats", | ||||||
|     "Auto Get": "Auto Get", |     "Auto Get": "Auto-hent", | ||||||
|     enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |     enableDefaultNotificationDescription: "For hver ny overvåger aktiveres denne underretning som standard. Du kan stadig deaktivere underretningen separat for hver skærm.", | ||||||
|     "Default enabled": "Default enabled", |     "Default enabled": "Standard aktiveret", | ||||||
|     "Also apply to existing monitors": "Also apply to existing monitors", |     "Also apply to existing monitors": "Anvend også på eksisterende overvågere", | ||||||
|     "Import/Export Backup": "Import/Export Backup", |     "Import/Export Backup": " Importér/Eksportér sikkerhedskopi", | ||||||
|     Export: "Export", |     Export: "Eksport", | ||||||
|     Import: "Import", |     Import: "Import", | ||||||
|     backupDescription: "You can backup all monitors and all notifications into a JSON file.", |     backupDescription: "Du kan sikkerhedskopiere alle Overvågere og alle underretninger til en JSON-fil.", | ||||||
|     backupDescription2: "PS: History and event data is not included.", |     backupDescription2: "PS: Historik og hændelsesdata er ikke inkluderet.", | ||||||
|     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |     backupDescription3: "Følsom data, f.eks. underretnings-tokener, er inkluderet i eksportfilen. Gem den sikkert.", | ||||||
|     alertNoFile: "Please select a file to import.", |     alertNoFile: "Vælg en fil der skal importeres.", | ||||||
|     alertWrongFileType: "Please select a JSON file." |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -36,8 +36,8 @@ export default { | |||||||
|     hour: "Stunde", |     hour: "Stunde", | ||||||
|     "-hour": "-Stunden", |     "-hour": "-Stunden", | ||||||
|     checkEverySecond: "Überprüfe alle {0} Sekunden", |     checkEverySecond: "Überprüfe alle {0} Sekunden", | ||||||
|     "Avg.": "Durchschn. ", |     "Avg.": "Durchschn.", | ||||||
|     Response: " Antwortzeit", |     Response: "Antwortzeit", | ||||||
|     Ping: "Ping", |     Ping: "Ping", | ||||||
|     "Monitor Type": "Monitor Typ", |     "Monitor Type": "Monitor Typ", | ||||||
|     Keyword: "Schlüsselwort", |     Keyword: "Schlüsselwort", | ||||||
| @@ -114,12 +114,12 @@ export default { | |||||||
|     "Repeat Password": "Wiederhole das Passwort", |     "Repeat Password": "Wiederhole das Passwort", | ||||||
|     "Resource Record Type": "Resource Record Type", |     "Resource Record Type": "Resource Record Type", | ||||||
|     "Import/Export Backup": "Import/Export Backup", |     "Import/Export Backup": "Import/Export Backup", | ||||||
|     "Export": "Export", |     Export: "Export", | ||||||
|     "Import": "Import", |     Import: "Import", | ||||||
|     respTime: "Antw. Zeit (ms)", |     respTime: "Antw. Zeit (ms)", | ||||||
|     notAvailableShort: "N/A", |     notAvailableShort: "N/A", | ||||||
|     "Default enabled": "Standardmäßig aktiviert", |     "Default enabled": "Standardmäßig aktiviert", | ||||||
|     "Also apply to existing monitors": "Auch für alle existierenden Monitore aktivieren", |     "Apply on all existing monitors": "Auf alle existierenden Monitore anwenden", | ||||||
|     enableDefaultNotificationDescription: "Für jeden neuen Monitor wird diese Benachrichtigung standardmäßig aktiviert. Die Benachrichtigung kann weiterhin für jeden Monitor separat deaktiviert werden.", |     enableDefaultNotificationDescription: "Für jeden neuen Monitor wird diese Benachrichtigung standardmäßig aktiviert. Die Benachrichtigung kann weiterhin für jeden Monitor separat deaktiviert werden.", | ||||||
|     Create: "Erstellen", |     Create: "Erstellen", | ||||||
|     "Auto Get": "Auto Get", |     "Auto Get": "Auto Get", | ||||||
| @@ -128,5 +128,19 @@ export default { | |||||||
|     backupDescription3: "Sensible Daten wie Benachrichtigungstoken sind in der Exportdatei enthalten, bitte bewahre sie sorgfältig auf.", |     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.", |     alertNoFile: "Bitte wähle eine Datei zum importieren aus.", | ||||||
|     alertWrongFileType: "Bitte wähle eine JSON Datei aus.", |     alertWrongFileType: "Bitte wähle eine JSON Datei aus.", | ||||||
|     "Clear all statistics": "Lösche alle Statistiken" |     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", | ||||||
|  |     "Show URI": "URI Anzeigen", | ||||||
|  |     "Clear all statistics": "Lösche alle Statistiken", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "English", |     languageName: "English", | ||||||
|     checkEverySecond: "Check every {0} seconds.", |     checkEverySecond: "Check every {0} seconds.", | ||||||
|     "Avg.": "Avg. ", |     "Avg.": "Avg.", | ||||||
|     retriesDescription: "Maximum retries before the service is marked as down and a notification is sent", |     retriesDescription: "Maximum retries before the service is marked as down and a notification is sent", | ||||||
|     ignoreTLSError: "Ignore TLS/SSL error for HTTPS websites", |     ignoreTLSError: "Ignore TLS/SSL error for HTTPS websites", | ||||||
|     upsideDownModeDescription: "Flip the status upside down. If the service is reachable, it is DOWN.", |     upsideDownModeDescription: "Flip the status upside down. If the service is reachable, it is DOWN.", | ||||||
| @@ -20,6 +20,10 @@ export default { | |||||||
|     clearEventsMsg: "Are you sure want to delete all events for this monitor?", |     clearEventsMsg: "Are you sure want to delete all events for this monitor?", | ||||||
|     clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |     clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", | ||||||
|     confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |     confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", | ||||||
|  |     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?", | ||||||
|     Settings: "Settings", |     Settings: "Settings", | ||||||
|     Dashboard: "Dashboard", |     Dashboard: "Dashboard", | ||||||
|     "New Update": "New Update", |     "New Update": "New Update", | ||||||
| @@ -117,7 +121,7 @@ export default { | |||||||
|     respTime: "Resp. Time (ms)", |     respTime: "Resp. Time (ms)", | ||||||
|     notAvailableShort: "N/A", |     notAvailableShort: "N/A", | ||||||
|     "Default enabled": "Default enabled", |     "Default enabled": "Default enabled", | ||||||
|     "Also apply to existing monitors": "Also apply to existing monitors", |     "Apply on all existing monitors": "Apply on all existing monitors", | ||||||
|     Create: "Create", |     Create: "Create", | ||||||
|     "Clear Data": "Clear Data", |     "Clear Data": "Clear Data", | ||||||
|     Events: "Events", |     Events: "Events", | ||||||
| @@ -128,5 +132,15 @@ export default { | |||||||
|     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     alertNoFile: "Please select a file to import.", | ||||||
|     alertWrongFileType: "Please select a JSON file.", |     alertWrongFileType: "Please select a JSON file.", | ||||||
|     "Clear all statistics": "Clear all Statistics" |     "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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Español", |     languageName: "Español", | ||||||
|     checkEverySecond: "Comprobar cada {0} segundos.", |     checkEverySecond: "Comprobar cada {0} segundos.", | ||||||
|     "Avg.": "Media. ", |     "Avg.": "Media.", | ||||||
|     retriesDescription: "Número máximo de intentos antes de que el servicio se marque como CAÍDO y una notificación sea enviada.", |     retriesDescription: "Número máximo de intentos antes de que el servicio se marque como CAÍDO y una notificación sea enviada.", | ||||||
|     ignoreTLSError: "Ignorar error TLS/SSL para sitios web HTTPS", |     ignoreTLSError: "Ignorar error TLS/SSL para sitios web HTTPS", | ||||||
|     upsideDownModeDescription: "Invertir el estado. Si el servicio es alcanzable, está CAÍDO.", |     upsideDownModeDescription: "Invertir el estado. Si el servicio es alcanzable, está CAÍDO.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "eesti", |     languageName: "eesti", | ||||||
|     checkEverySecond: "Kontrolli {0} sekundilise vahega.", |     checkEverySecond: "Kontrolli {0} sekundilise vahega.", | ||||||
|     "Avg.": "≈ ", |     "Avg.": "≈", | ||||||
|     retriesDescription: "Mitu korda tuleb kontrollida, mille järel märkida 'maas' ja saata välja teavitus.", |     retriesDescription: "Mitu korda tuleb kontrollida, mille järel märkida 'maas' ja saata välja teavitus.", | ||||||
|     ignoreTLSError: "Eira TLS/SSL viga HTTPS veebisaitidel.", |     ignoreTLSError: "Eira TLS/SSL viga HTTPS veebisaitidel.", | ||||||
|     upsideDownModeDescription: "Käitle teenuse saadavust rikkena, teenuse kättesaamatust töötavaks.", |     upsideDownModeDescription: "Käitle teenuse saadavust rikkena, teenuse kättesaamatust töötavaks.", | ||||||
| @@ -10,7 +10,7 @@ export default { | |||||||
|     passwordNotMatchMsg: "Salasõnad ei kattu.", |     passwordNotMatchMsg: "Salasõnad ei kattu.", | ||||||
|     notificationDescription: "Teavitusmeetodi kasutamiseks seo see seirega.", |     notificationDescription: "Teavitusmeetodi kasutamiseks seo see seirega.", | ||||||
|     keywordDescription: "Jälgi võtmesõna HTML või JSON vastustes. (tõstutundlik)", |     keywordDescription: "Jälgi võtmesõna HTML või JSON vastustes. (tõstutundlik)", | ||||||
|     pauseDashboardHome: "Seiskamine", |     pauseDashboardHome: "Seismas", | ||||||
|     deleteMonitorMsg: "Kas soovid eemaldada seire?", |     deleteMonitorMsg: "Kas soovid eemaldada seire?", | ||||||
|     deleteNotificationMsg: "Kas soovid eemaldada selle teavitusmeetodi kõikidelt seiretelt?", |     deleteNotificationMsg: "Kas soovid eemaldada selle teavitusmeetodi kõikidelt seiretelt?", | ||||||
|     resoverserverDescription: "Cloudflare on vaikimisi pöördserver.", |     resoverserverDescription: "Cloudflare on vaikimisi pöördserver.", | ||||||
| @@ -109,23 +109,39 @@ export default { | |||||||
|     "Repeat Password": "korda salasõna", |     "Repeat Password": "korda salasõna", | ||||||
|     respTime: "Reageerimisaeg (ms)", |     respTime: "Reageerimisaeg (ms)", | ||||||
|     notAvailableShort: "N/A", |     notAvailableShort: "N/A", | ||||||
|     enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |     enableDefaultNotificationDescription: "Kõik järgnevalt lisatud seired kasutavad seda teavitusmeetodit. Seiretelt võib teavitusmeetodi ühekaupa eemaldada.", | ||||||
|     clearEventsMsg: "Are you sure want to delete all events for this monitor?", |     clearEventsMsg: "Kas soovid seire kõik sündmused kustutada?", | ||||||
|     clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |     clearHeartbeatsMsg: "Kas soovid seire kõik tuksed kustutada?", | ||||||
|     confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |     confirmClearStatisticsMsg: "Kas soovid KÕIK statistika kustutada?", | ||||||
|     "Import/Export Backup": "Import/Export Backup", |     "Import/Export Backup": "Impordi/Ekspordi varukoopia", | ||||||
|     Export: "Export", |     Export: "Eksport", | ||||||
|     Import: "Import", |     Import: "Import", | ||||||
|     "Default enabled": "Default enabled", |     "Default enabled": "Kasuta vaikimisi", | ||||||
|     "Also apply to existing monitors": "Also apply to existing monitors", |     "Also apply to existing monitors": "Aktiveeri teavitusmeetod olemasolevatel seiretel", | ||||||
|     Create: "Create", |     Create: "Loo konto", | ||||||
|     "Clear Data": "Clear Data", |     "Clear Data": "Eemalda andmed", | ||||||
|     Events: "Events", |     Events: "Sündmused", | ||||||
|     Heartbeats: "Heartbeats", |     Heartbeats: "Tuksed", | ||||||
|     "Auto Get": "Auto Get", |     "Auto Get": "Hangi automaatselt", | ||||||
|     backupDescription: "You can backup all monitors and all notifications into a JSON file.", |     backupDescription: "Varunda kõik seired ja teavitused JSON faili.", | ||||||
|     backupDescription2: "PS: History and event data is not included.", |     backupDescription2: "PS: Varukoopia EI sisalda seirete ajalugu ja sündmustikku.", | ||||||
|     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |     backupDescription3: "Varukoopiad sisaldavad teavitusmeetodite pääsuvõtmeid.", | ||||||
|     alertNoFile: "Please select a file to import.", |     alertNoFile: "Palun lisa fail, mida importida.", | ||||||
|     alertWrongFileType: "Please select a JSON file." |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "日本語", |     languageName: "日本語", | ||||||
|     checkEverySecond: "{0}秒ごとにチェックします。", |     checkEverySecond: "{0}秒ごとにチェックします。", | ||||||
|     "Avg.": "平均 ", |     "Avg.": "平均", | ||||||
|     retriesDescription: "サービスがダウンとしてマークされ、通知が送信されるまでの最大リトライ数", |     retriesDescription: "サービスがダウンとしてマークされ、通知が送信されるまでの最大リトライ数", | ||||||
|     ignoreTLSError: "HTTPS ウェブサイトの TLS/SSL エラーを無視する", |     ignoreTLSError: "HTTPS ウェブサイトの TLS/SSL エラーを無視する", | ||||||
|     upsideDownModeDescription: "ステータスの扱いを逆にします。サービスに到達可能な場合は、DOWNとなる。", |     upsideDownModeDescription: "ステータスの扱いを逆にします。サービスに到達可能な場合は、DOWNとなる。", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "한국어", |     languageName: "한국어", | ||||||
|     checkEverySecond: "{0} 초마다 체크해요.", |     checkEverySecond: "{0} 초마다 체크해요.", | ||||||
|     "Avg.": "평균 ", |     "Avg.": "평균", | ||||||
|     retriesDescription: "서비스가 중단된 후 알림을 보내기 전 최대 재시도 횟수", |     retriesDescription: "서비스가 중단된 후 알림을 보내기 전 최대 재시도 횟수", | ||||||
|     ignoreTLSError: "HTTPS 웹사이트에서 TLS/SSL 에러 무시하기", |     ignoreTLSError: "HTTPS 웹사이트에서 TLS/SSL 에러 무시하기", | ||||||
|     upsideDownModeDescription: "서버 상태를 반대로 표시해요. 서버가 작동하면 오프라인으로 표시할 거에요.", |     upsideDownModeDescription: "서버 상태를 반대로 표시해요. 서버가 작동하면 오프라인으로 표시할 거에요.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Nederlands", |     languageName: "Nederlands", | ||||||
|     checkEverySecond: "Controleer elke {0} seconden.", |     checkEverySecond: "Controleer elke {0} seconden.", | ||||||
|     "Avg.": "Gem. ", |     "Avg.": "Gem.", | ||||||
|     retriesDescription: "Maximum aantal nieuwe pogingen voordat de service wordt gemarkeerd als niet beschikbaar en er een melding wordt verzonden", |     retriesDescription: "Maximum aantal nieuwe pogingen voordat de service wordt gemarkeerd als niet beschikbaar en er een melding wordt verzonden", | ||||||
|     ignoreTLSError: "Negeer TLS/SSL-fout voor HTTPS-websites", |     ignoreTLSError: "Negeer TLS/SSL-fout voor HTTPS-websites", | ||||||
|     upsideDownModeDescription: "Draai de status om. Als de service bereikbaar is, is deze OFFLINE.", |     upsideDownModeDescription: "Draai de status om. Als de service bereikbaar is, is deze OFFLINE.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Polski", |     languageName: "Polski", | ||||||
|     checkEverySecond: "Sprawdzaj co {0} sekund.", |     checkEverySecond: "Sprawdzaj co {0} sekund.", | ||||||
|     "Avg.": "Średnia ", |     "Avg.": "Średnia", | ||||||
|     retriesDescription: "Maksymalna liczba powtórzeń, zanim usługa zostanie oznaczona jako wyłączona i zostanie wysłane powiadomienie", |     retriesDescription: "Maksymalna liczba powtórzeń, zanim usługa zostanie oznaczona jako wyłączona i zostanie wysłane powiadomienie", | ||||||
|     ignoreTLSError: "Ignoruj błąd TLS/SSL dla stron HTTPS", |     ignoreTLSError: "Ignoruj błąd TLS/SSL dla stron HTTPS", | ||||||
|     upsideDownModeDescription: "Odwróć status do góry nogami. Jeśli usługa jest osiągalna, to jest oznaczona jako niedostępna.", |     upsideDownModeDescription: "Odwróć status do góry nogami. Jeśli usługa jest osiągalna, to jest oznaczona jako niedostępna.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Русский", |     languageName: "Русский", | ||||||
|     checkEverySecond: "Проверять каждые {0} секунд.", |     checkEverySecond: "Проверять каждые {0} секунд.", | ||||||
|     "Avg.": "Средн. ", |     "Avg.": "Средн.", | ||||||
|     retriesDescription: "Максимальное количество попыток перед пометкой сервиса как недоступного и отправкой уведомления", |     retriesDescription: "Максимальное количество попыток перед пометкой сервиса как недоступного и отправкой уведомления", | ||||||
|     ignoreTLSError: "Игнорировать ошибку TLS/SSL для HTTPS сайтов", |     ignoreTLSError: "Игнорировать ошибку TLS/SSL для HTTPS сайтов", | ||||||
|     upsideDownModeDescription: "Реверс статуса сервиса. Если сервис доступен, то он помечается как НЕДОСТУПНЫЙ.", |     upsideDownModeDescription: "Реверс статуса сервиса. Если сервис доступен, то он помечается как НЕДОСТУПНЫЙ.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Srpski", |     languageName: "Srpski", | ||||||
|     checkEverySecond: "Proveri svakih {0} sekundi.", |     checkEverySecond: "Proveri svakih {0} sekundi.", | ||||||
|     "Avg.": "Prosečni ", |     "Avg.": "Prosečni", | ||||||
|     retriesDescription: "Maksimum pokušaja pre nego što se servis obeleži kao neaktivan i pošalje se obaveštenje.", |     retriesDescription: "Maksimum pokušaja pre nego što se servis obeleži kao neaktivan i pošalje se obaveštenje.", | ||||||
|     ignoreTLSError: "Ignoriši TLS/SSL greške za HTTPS veb stranice.", |     ignoreTLSError: "Ignoriši TLS/SSL greške za HTTPS veb stranice.", | ||||||
|     upsideDownModeDescription: "Obrnite status. Ako je servis dostupan, onda je obeležen kao neaktivan.", |     upsideDownModeDescription: "Obrnite status. Ako je servis dostupan, onda je obeležen kao neaktivan.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Српски", |     languageName: "Српски", | ||||||
|     checkEverySecond: "Провери сваких {0} секунди.", |     checkEverySecond: "Провери сваких {0} секунди.", | ||||||
|     "Avg.": "Просечни ", |     "Avg.": "Просечни", | ||||||
|     retriesDescription: "Максимум покушаја пре него што се сервис обележи као неактиван и пошаље се обавештење.", |     retriesDescription: "Максимум покушаја пре него што се сервис обележи као неактиван и пошаље се обавештење.", | ||||||
|     ignoreTLSError: "Игнориши TLS/SSL грешке за HTTPS веб странице.", |     ignoreTLSError: "Игнориши TLS/SSL грешке за HTTPS веб странице.", | ||||||
|     upsideDownModeDescription: "Обрните статус. Ако је сервис доступан, онда је обележен као неактиван.", |     upsideDownModeDescription: "Обрните статус. Ако је сервис доступан, онда је обележен као неактиван.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| export default { | export default { | ||||||
|     languageName: "Svenska", |     languageName: "Svenska", | ||||||
|     checkEverySecond: "Uppdatera var {0} sekund.", |     checkEverySecond: "Uppdatera var {0} sekund.", | ||||||
|     "Avg.": "Genomsnittligt ", |     "Avg.": "Genomsnittligt", | ||||||
|     retriesDescription: "Max antal försök innan tjänsten markeras som nere och en notis skickas", |     retriesDescription: "Max antal försök innan tjänsten markeras som nere och en notis skickas", | ||||||
|     ignoreTLSError: "Ignorera TLS/SSL-fel för webbsidor med HTTPS", |     ignoreTLSError: "Ignorera TLS/SSL-fel för webbsidor med HTTPS", | ||||||
|     upsideDownModeDescription: "Vänd upp och ner på statusen. Om tjänsten är nåbar visas den som NERE.", |     upsideDownModeDescription: "Vänd upp och ner på statusen. Om tjänsten är nåbar visas den som NERE.", | ||||||
| @@ -127,5 +127,21 @@ export default { | |||||||
|     backupDescription2: "PS: History and event data is not included.", |     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.", |     backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", | ||||||
|     alertNoFile: "Please select a file to import.", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -119,7 +119,6 @@ export default { | |||||||
|     "Auto Get": "自动获取", |     "Auto Get": "自动获取", | ||||||
|     enableDefaultNotificationDescription: "新的监控项将默认启用,你也可以在每个监控项中分别设置", |     enableDefaultNotificationDescription: "新的监控项将默认启用,你也可以在每个监控项中分别设置", | ||||||
|     "Default enabled": "默认开启", |     "Default enabled": "默认开启", | ||||||
|     "Also apply to existing monitors": "应用到所有监控项", |  | ||||||
|     "Import/Export Backup": "导入/导出备份", |     "Import/Export Backup": "导入/导出备份", | ||||||
|     Export: "导出", |     Export: "导出", | ||||||
|     Import: "导入", |     Import: "导入", | ||||||
| @@ -127,5 +126,21 @@ export default { | |||||||
|     backupDescription2: "注意: 不包括历史状态和事件数据", |     backupDescription2: "注意: 不包括历史状态和事件数据", | ||||||
|     backupDescription3: "导出的文件中可能包含敏感信息,如消息通知的 Token 信息,请小心存放!", |     backupDescription3: "导出的文件中可能包含敏感信息,如消息通知的 Token 信息,请小心存放!", | ||||||
|     alertNoFile: "请选择一个文件导入", |     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", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -119,7 +119,6 @@ export default { | |||||||
|     "Auto Get": "自動獲取", |     "Auto Get": "自動獲取", | ||||||
|     enableDefaultNotificationDescription: "新增監測器時這個通知會預設啟用,當然每個監測器亦可分別控制開關。", |     enableDefaultNotificationDescription: "新增監測器時這個通知會預設啟用,當然每個監測器亦可分別控制開關。", | ||||||
|     "Default enabled": "預設通知", |     "Default enabled": "預設通知", | ||||||
|     "Also apply to existing monitors": "同時取用至目前所有監測器", |  | ||||||
|     "Import/Export Backup": "匯入/匯出 備份", |     "Import/Export Backup": "匯入/匯出 備份", | ||||||
|     Export: "匯出", |     Export: "匯出", | ||||||
|     Import: "匯入", |     Import: "匯入", | ||||||
| @@ -127,5 +126,21 @@ export default { | |||||||
|     backupDescription2: "註:此備份不包括歷史記錄。", |     backupDescription2: "註:此備份不包括歷史記錄。", | ||||||
|     backupDescription3: "此備份可能包含了一些敏感資料如通知裡的 Token,請小心保存備份。", |     backupDescription3: "此備份可能包含了一些敏感資料如通知裡的 Token,請小心保存備份。", | ||||||
|     alertNoFile: "請選擇一個檔案", |     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": "清除所有歷史記錄", | ||||||
| } | } | ||||||
|   | |||||||
| @@ -224,11 +224,15 @@ export default { | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         login(username, password, callback) { |         login(username, password, token, callback) { | ||||||
|             socket.emit("login", { |             socket.emit("login", { | ||||||
|                 username, |                 username, | ||||||
|                 password, |                 password, | ||||||
|  |                 token, | ||||||
|             }, (res) => { |             }, (res) => { | ||||||
|  |                 if (res.tokenRequired) { | ||||||
|  |                     callback(res) | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 if (res.ok) { |                 if (res.ok) { | ||||||
|                     this.storage().token = res.token; |                     this.storage().token = res.token; | ||||||
| @@ -263,6 +267,26 @@ export default { | |||||||
|             this.clearData() |             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) { |         add(monitor, callback) { | ||||||
|             socket.emit("add", monitor, callback) |             socket.emit("add", monitor, callback) | ||||||
|         }, |         }, | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ | |||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
|             <div class="shadow-box table-shadow-box" style="overflow-x: scroll;"> |             <div class="shadow-box table-shadow-box" style="overflow-x: hidden;"> | ||||||
|                 <table class="table table-borderless table-hover"> |                 <table class="table table-borderless table-hover"> | ||||||
|                     <thead> |                     <thead> | ||||||
|                         <tr> |                         <tr> | ||||||
| @@ -178,5 +178,10 @@ table { | |||||||
|     tr { |     tr { | ||||||
|         transition: all ease-in-out 0.2ms; |         transition: all ease-in-out 0.2ms; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @media (max-width: 550px) { | ||||||
|  |         table-layout: fixed; | ||||||
|  |         overflow-wrap: break-word; | ||||||
|  |     } | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ | |||||||
|                         </span> |                         </span> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="col"> |                     <div class="col"> | ||||||
|                         <h4>{{ $t("Avg.") }}{{ pingTitle }}</h4> |                         <h4>{{ $t("Avg.") }} {{ pingTitle }}</h4> | ||||||
|                         <p>(24{{ $t("-hour") }})</p> |                         <p>(24{{ $t("-hour") }})</p> | ||||||
|                         <span class="num"><CountUp :value="avgPing" /></span> |                         <span class="num"><CountUp :value="avgPing" /></span> | ||||||
|                     </div> |                     </div> | ||||||
|   | |||||||
| @@ -219,6 +219,7 @@ export default { | |||||||
|             dnsresolvetypeOptions: [], |             dnsresolvetypeOptions: [], | ||||||
|  |  | ||||||
|             // Source: https://digitalfortress.tech/tips/top-15-commonly-used-regex/ |             // 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*$))", |             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*$))", | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -120,6 +120,14 @@ | |||||||
|                                 </form> |                                 </form> | ||||||
|                             </template> |                             </template> | ||||||
|  |  | ||||||
|  |                             <h2 class="mt-5 mb-2"> | ||||||
|  |                                 {{ $t("Two Factor Authentication") }} | ||||||
|  |                             </h2> | ||||||
|  |  | ||||||
|  |                             <div class="mb-3"> | ||||||
|  |                                 <button class="btn btn-primary me-2" type="button" @click="$refs.TwoFADialog.show()">{{ $t("2FA Settings") }}</button> | ||||||
|  |                             </div> | ||||||
|  |  | ||||||
|                             <h2 class="mt-5 mb-2">{{ $t("Import/Export Backup") }}</h2> |                             <h2 class="mt-5 mb-2">{{ $t("Import/Export Backup") }}</h2> | ||||||
|  |  | ||||||
|                             <p> |                             <p> | ||||||
| @@ -144,10 +152,10 @@ | |||||||
|                             <h2 class="mt-5 mb-2">{{ $t("Advanced") }}</h2> |                             <h2 class="mt-5 mb-2">{{ $t("Advanced") }}</h2> | ||||||
|  |  | ||||||
|                             <div class="mb-3"> |                             <div class="mb-3"> | ||||||
|                                 <button v-if="settings.disableAuth" class="btn btn-outline-primary me-1" @click="enableAuth">{{ $t("Enable Auth") }}</button> |                                 <button v-if="settings.disableAuth" class="btn btn-outline-primary me-1 mb-1" @click="enableAuth">{{ $t("Enable Auth") }}</button> | ||||||
|                                 <button v-if="! settings.disableAuth" class="btn btn-primary me-1" @click="confirmDisableAuth">{{ $t("Disable Auth") }}</button> |                                 <button v-if="! settings.disableAuth" class="btn btn-primary me-1 mb-1" @click="confirmDisableAuth">{{ $t("Disable Auth") }}</button> | ||||||
|                                 <button v-if="! settings.disableAuth" class="btn btn-danger me-1" @click="$root.logout">{{ $t("Logout") }}</button> |                                 <button v-if="! settings.disableAuth" class="btn btn-danger me-1 mb-1" @click="$root.logout">{{ $t("Logout") }}</button> | ||||||
|                                 <button class="btn btn-outline-danger me-1" @click="confirmClearStatistics">{{ $t("Clear all statistics") }}</button> |                                 <button class="btn btn-outline-danger me-1 mb-1" @click="confirmClearStatistics">{{ $t("Clear all statistics") }}</button> | ||||||
|                             </div> |                             </div> | ||||||
|                         </template> |                         </template> | ||||||
|                     </div> |                     </div> | ||||||
| @@ -186,6 +194,7 @@ | |||||||
|             </footer> |             </footer> | ||||||
|  |  | ||||||
|             <NotificationDialog ref="notificationDialog" /> |             <NotificationDialog ref="notificationDialog" /> | ||||||
|  |             <TwoFADialog ref="TwoFADialog" /> | ||||||
|  |  | ||||||
|             <Confirm ref="confirmDisableAuth" btn-style="btn-danger" :yes-text="$t('I understand, please disable')" :no-text="$t('Leave')" @yes="disableAuth"> |             <Confirm ref="confirmDisableAuth" btn-style="btn-danger" :yes-text="$t('I understand, please disable')" :no-text="$t('Leave')" @yes="disableAuth"> | ||||||
|                 <template v-if="$i18n.locale === 'es-ES' "> |                 <template v-if="$i18n.locale === 'es-ES' "> | ||||||
| @@ -269,6 +278,7 @@ import dayjs from "dayjs"; | |||||||
| import utc from "dayjs/plugin/utc" | import utc from "dayjs/plugin/utc" | ||||||
| import timezone from "dayjs/plugin/timezone" | import timezone from "dayjs/plugin/timezone" | ||||||
| import NotificationDialog from "../components/NotificationDialog.vue"; | import NotificationDialog from "../components/NotificationDialog.vue"; | ||||||
|  | import TwoFADialog from "../components/TwoFADialog.vue"; | ||||||
| dayjs.extend(utc) | dayjs.extend(utc) | ||||||
| dayjs.extend(timezone) | dayjs.extend(timezone) | ||||||
|  |  | ||||||
| @@ -279,6 +289,7 @@ const toast = useToast() | |||||||
| export default { | export default { | ||||||
|     components: { |     components: { | ||||||
|         NotificationDialog, |         NotificationDialog, | ||||||
|  |         TwoFADialog, | ||||||
|         Confirm, |         Confirm, | ||||||
|     }, |     }, | ||||||
|     data() { |     data() { | ||||||
| @@ -383,7 +394,7 @@ export default { | |||||||
|                 notificationList: this.$root.notificationList, |                 notificationList: this.$root.notificationList, | ||||||
|                 monitorList: monitorList, |                 monitorList: monitorList, | ||||||
|             } |             } | ||||||
|             exportData = JSON.stringify(exportData); |             exportData = JSON.stringify(exportData, null, 4); | ||||||
|             let downloadItem = document.createElement("a"); |             let downloadItem = document.createElement("a"); | ||||||
|             downloadItem.setAttribute("href", "data:application/json;charset=utf-8," + encodeURI(exportData)); |             downloadItem.setAttribute("href", "data:application/json;charset=utf-8," + encodeURI(exportData)); | ||||||
|             downloadItem.setAttribute("download", fileName); |             downloadItem.setAttribute("download", fileName); | ||||||
|   | |||||||
| @@ -87,7 +87,7 @@ export default { | |||||||
|                 if (res.ok) { |                 if (res.ok) { | ||||||
|                     this.processing = true; |                     this.processing = true; | ||||||
|  |  | ||||||
|                     this.$root.login(this.username, this.password, (res) => { |                     this.$root.login(this.username, this.password, "", (res) => { | ||||||
|                         this.processing = false; |                         this.processing = false; | ||||||
|                         this.$router.push("/") |                         this.$router.push("/") | ||||||
|                     }) |                     }) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user