From 8a163eaede882ed6bafeb5fc89f3a597d5ee9920 Mon Sep 17 00:00:00 2001 From: Matthew Nickson Date: Sat, 1 Oct 2022 19:09:24 +0100 Subject: [PATCH] Added confirmation dialog for low interval A prompt has been added to confirm with the user that they wish to reduce the interval value to possibly unstable values. A random (pseudo random) code is generated which they must input in order to confirm their descision. Failiure to confirm their descision will result in an error when saving. As not to annoy the user too much, the promt is only required when it is detected that the interval value has been changed. Signed-off-by: Matthew Nickson --- src/languages/en.js | 6 ++++ src/pages/EditMonitor.vue | 70 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/languages/en.js b/src/languages/en.js index f05ce87c1..06cd49a09 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -526,4 +526,10 @@ export default { "Go back to the previous page.": "Go back to the previous page.", "Coming Soon": "Coming Soon", wayToGetClickSendSMSToken: "You can get API Username and API Key from {0} .", + lowIntervalWarning: "Are you sure want to set the interval value below 20 seconds? This is NOT supported and may make Uptime Kuma unstable.", + "Please use this option carefully!": "Please use this option carefully!", + enterConfirmationString: "To confirm, please enter the following: {0}", + confirmLowIntervalRequired: "You must confirm you want to use such a low interval before saving.", + errCodeMismatch: "Confirmation code did not match", + "Confirmed": "Confirmed", }; diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 2c0028fc4..58c5179d5 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -160,7 +160,16 @@
- +
{{ $t("minimumIntervalWarning") }}
@@ -371,6 +380,24 @@ + + +

{{ $t("lowIntervalWarning") }}

+

{{ $t("Please use this option carefully!") }}

+ +
+ + {{ lowIntervalConfirmation.testString }} + + +
+
@@ -379,6 +406,7 @@ import VueMultiselect from "vue-multiselect"; import { useToast } from "vue-toastification"; import CopyableInput from "../components/CopyableInput.vue"; +import Confirm from "../components/Confirm.vue"; import NotificationDialog from "../components/NotificationDialog.vue"; import ProxyDialog from "../components/ProxyDialog.vue"; import TagsManager from "../components/TagsManager.vue"; @@ -390,6 +418,7 @@ export default { components: { ProxyDialog, CopyableInput, + Confirm, NotificationDialog, TagsManager, VueMultiselect, @@ -404,6 +433,12 @@ export default { }, acceptedStatusCodeOptions: [], dnsresolvetypeOptions: [], + lowIntervalConfirmation: { + testString: "", + userString: "", + confirmed: false, + editedValue: false, + }, // Source: https://digitalfortress.tech/tips/top-15-commonly-used-regex/ 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*$))", @@ -526,6 +561,7 @@ export default { this.acceptedStatusCodeOptions = acceptedStatusCodeOptions; this.dnsresolvetypeOptions = dnsresolvetypeOptions; + this.lowIntervalConfirmation.testString = Math.random().toString(36).substring(2, 9); }, methods: { init() { @@ -604,6 +640,28 @@ export default { return true; }, + /** + * Show popup if the interval value is less than 20 + */ + checkIntervalValue() { + if (this.monitor.interval < 20) { + this.$refs.confirmLowIntervalValue.show(); + } + }, + + /** + * Check that the user inputed code is correct + */ + validateConfirmationString() { + if (this.lowIntervalConfirmation.testString === this.lowIntervalConfirmation.userString) { + this.lowIntervalConfirmation.confirmed = true; + toast.success(this.$t("Confirmed")); + } else { + this.lowIntervalConfirmation.confirmed = false; + toast.error(this.$t("errCodeMismatch")); + } + }, + async submit() { this.processing = true; @@ -612,6 +670,16 @@ export default { return; } + // Check user has confirmed use of low interval value. Only + // do this if the interval value has changed since last save + if (this.lowIntervalConfirmation.editedValue && this.monitor.interval < 20 && !this.lowIntervalConfirmation.confirmed) { + toast.error(this.$t("confirmLowIntervalRequired")); + this.processing = false; + return; + } + this.lowIntervalConfirmation.confirmed = false; + this.lowIntervalConfirmation.editedValue = false; + // Beautify the JSON format if (this.monitor.body) { this.monitor.body = JSON.stringify(JSON.parse(this.monitor.body), null, 4);