changeset 392:c57b952c60be

feat: Improved user input validation More validation added and refactored.
author Thomas Junk <thomas.junk@intevation.de>
date Mon, 13 Aug 2018 17:35:56 +0200
parents 6f77f33af651
children d5d54c00da58
files client/src/components/Userdetail.vue
diffstat 1 files changed, 46 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/Userdetail.vue	Mon Aug 13 16:21:38 2018 +0200
+++ b/client/src/components/Userdetail.vue	Mon Aug 13 17:35:56 2018 +0200
@@ -11,7 +11,7 @@
             <div v-if="currentUser.isNew" class="form-group row">
               <label for="user">Username</label>
               <input type="user" class="form-control form-control-sm" id="user" aria-describedby="userHelp" v-model="currentUser.user">
-              <div v-show="errors.email" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.email }}</small></div>
+              <div v-show="errors.user" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.user }}</small></div>
             </div>
             <div class="form-group row">
               <label for="country">Country</label>
@@ -30,12 +30,13 @@
             </div>
             <div class="form-group row">
               <label for="role">Role</label>
-              <select class="form-control form-control-sm" v-model="currentUser.role">
+              <select class="form-control form-control-sm" v-on:change="validateRole" v-model="currentUser.role">
                 <option disabled value="">Please select one</option>
                 <option value="sys_admin">Sysadmin</option>
                 <option value="waterway_admin">Waterway Admin</option>
                 <option value="waterway_user">Waterway User</option>
               </select>
+              <div v-show="errors.role" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.role }}</small></div>
             </div>
             <div class="form-group row">
               <label for="password">Password</label>
@@ -83,6 +84,23 @@
 <script>
 import app from "../main";
 
+const isEmailValid = email => {
+  /* cf. types.go */
+  // eslint-disable-next-line
+  return /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/.test(
+    email
+  );
+};
+
+const violatedPasswordRules = password => {
+  return (
+    // rules according to issue 70
+    password.length < 7 ||
+    /\W/.test(password) == false ||
+    /\d/.test(password) == false
+  );
+};
+
 export default {
   name: "userdetail",
   data() {
@@ -95,6 +113,7 @@
       errors: {
         email: "",
         country: "",
+        role: "",
         password: "",
         passwordre: ""
       }
@@ -114,14 +133,17 @@
     user() {
       return this.$store.getters["usermanagement/currentUser"];
     },
-    validationErrors() {
-      const errorMessages = this.errors;
-      return (
-        errorMessages.email ||
-        errorMessages.country ||
-        errorMessages.password ||
-        errorMessages.passwordre
-      );
+    isFormValid() {
+      this.validateCountry();
+      this.validateRole();
+      this.validatePassword();
+      this.validateEmailaddress();
+      const valid =
+        isEmailValid(this.currentUser.email) &&
+        !this.currentUser.country &&
+        this.password === this.passwordre &&
+        (this.password === "" || violatedPasswordRules(this.password));
+      return valid;
     }
   },
   methods: {
@@ -129,11 +151,18 @@
       this.$store.commit("usermanagement/clearCurrentUser");
       this.$store.commit("usermanagement/setUserDetailsInvisible");
     },
-    validateCountry(event) {
-      if (event.target.value !== "") {
+    validateCountry() {
+      if (this.currentUser.country) {
         this.errors.country = "";
       } else {
-        this.errors.country = "Please choose a valid country";
+        this.errors.country = "Please choose a country";
+      }
+    },
+    validateRole() {
+      if (this.currentUser.role) {
+        this.errors.role = "";
+      } else {
+        this.errors.role = "Please choose a role";
       }
     },
     validatePassword() {
@@ -142,33 +171,22 @@
       } else {
         this.errors.passwordre = "";
       }
-      if (
-        // rules according to issue 70
-        this.password.length < 8 ||
-        /\W/.test(this.password) == false ||
-        /\d/.test(this.password) == false
-      ) {
+      if (this.password !== "" && violatedPasswordRules(this.password)) {
         this.errors.password =
           "Password should at least be 8 char long including 1 digit and 1 special char like $";
       } else {
         this.errors.password = "";
       }
     },
-    validateEmailaddress(event) {
-      if (
-        /* cf. types.go */
-        // eslint-disable-next-line
-        /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/.test(
-          event.target.value
-        )
-      ) {
+    validateEmailaddress() {
+      if (isEmailValid(this.currentUser.email)) {
         this.errors.email = "";
       } else {
         this.errors.email = "invalid email";
       }
     },
     save() {
-      if (this.validationErrors) return;
+      if (!this.isFormValid) return;
       if (this.password) this.currentUser.password = this.password;
       this.submitted = true;
       this.$store