From 49f23a86e4e6ea751beee8c8dbc55b9766891a4e Mon Sep 17 00:00:00 2001 From: Csaern Date: Mon, 9 Dec 2024 12:39:29 +0100 Subject: [PATCH] Added Component to visualize the strength of the password at registration --- client/src/components/Login/RegisterForm.vue | 143 ++++++++++++++++++- 1 file changed, 140 insertions(+), 3 deletions(-) diff --git a/client/src/components/Login/RegisterForm.vue b/client/src/components/Login/RegisterForm.vue index d2237174c182..2ec40b62ed97 100644 --- a/client/src/components/Login/RegisterForm.vue +++ b/client/src/components/Login/RegisterForm.vue @@ -14,7 +14,7 @@ import { BFormInput, BFormText, } from "bootstrap-vue"; -import { computed, type Ref, ref } from "vue"; +import { computed, type Ref, ref, watch } from "vue"; import { Toast } from "@/composables/toast"; import localize from "@/utils/localization"; @@ -43,7 +43,7 @@ const emit = defineEmits<{ const email = ref(null); const confirm = ref(null); -const password = ref(null); +const password = ref(null); const username = ref(null); const subscribe = ref(null); const messageText: Ref = ref(null); @@ -53,11 +53,72 @@ const labelPublicName = ref(localize("Public name")); const labelEmailAddress = ref(localize("Email address")); const labelConfirmPassword = ref(localize("Confirm password")); const labelSubscribe = ref(localize("Stay in the loop and join the galaxy-announce mailing list.")); +const showPasswordGuidelines: Ref = ref(false); + const custosPreferred = computed(() => { return props.enableOidc && props.preferCustosLogin; }); +// reactive variable for password strength and color +const passwordStrength = ref("empty"); +const strengthScore = ref(0); +const commonPasswords = ["password", "123456", "123456789", "qwerty", "abc123", "password1", "111111", "letmein", "123123", "admin"]; + +// evaluation of password strength +function evaluatePasswordStrength(newPassword: string) { + if (newPassword.length === 0) { + passwordStrength.value = "empty"; + return; + } + + strengthScore.value = 0; + + // score for length + if (newPassword.length >= 8) {strengthScore.value++} + if (newPassword.length >= 12) {strengthScore.value++} + + // testing if password contains different characters + const hasLowerCase = /[a-z]/.test(newPassword); + const hasUpperCase = /[A-Z]/.test(newPassword); + const hasNumbers = /[0-9]/.test(newPassword); + const hasSpecialChars = /[!@#$%^&*(),.?":{}|<>]/.test(newPassword); + + if (hasLowerCase) {strengthScore.value++} + if (hasUpperCase) {strengthScore.value++} + if (hasNumbers) {strengthScore.value++} + if (hasSpecialChars) {strengthScore.value++} + + // check for common password + if (commonPasswords.includes(newPassword)) { + strengthScore.value = 0; // score gets zero if common + passwordStrength.value = "weak"; + return; + } + + // check for repeating characters + const repeatedCharMatch = newPassword.match(/(.)\1{2,}/); + if (repeatedCharMatch) { + strengthScore.value--; + } + + // evaluation of the strength + if (strengthScore.value <= 2) { + passwordStrength.value = "weak"; + } else if (strengthScore.value <= 4) { + passwordStrength.value = "medium"; + } else { + passwordStrength.value = "strong"; + } +} + +// function to watch the evaluation of the password +watch(password, (newPassword) => { + if (typeof newPassword === "string") { + evaluatePasswordStrength(newPassword); + } +}); + function toggleLogin() { emit("toggle-login"); } @@ -85,6 +146,7 @@ async function submit() { messageText.value = errorMessageAsString(error, "Registration failed for an unknown reason."); } } +