_binary From 01807a5125aa0568c064a66d7732092cf2724ca0 Mon Sep 17 00:00:00 2001
From: Sarika Padmashali <sarika.padmashali92@yahoo.in>
Date: Thu, 15 Dec 2016 21:56:59 -0800
Subject: [PATCH] Client side validation Yioop Register Page

---
 src/controllers/RegisterController.php |  30 +++-
 src/scripts/input_validator.js         | 250 +++++++++++++++++++++++++++++++++
 src/views/RegisterView.php             |  24 +++-
 3 files changed, 296 insertions(+), 8 deletions(-)
 create mode 100644 src/scripts/input_validator.js

diff --git a/src/controllers/RegisterController.php b/src/controllers/RegisterController.php
index 1247ed6..9a1a09a 100755
--- a/src/controllers/RegisterController.php
+++ b/src/controllers/RegisterController.php
@@ -275,6 +275,33 @@ class RegisterController extends Controller implements CrawlConstants
         }
         //used to ensure that we have sessions active
         $_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
+        /*used to manage locales
+        *
+        * localization of the warning messages
+        */
+        $tl = ["input_validator_js_valid_email" =>
+            tl('input_validator_js_valid_email'),
+            "input_validator_js_invalid_email" =>
+            tl('input_validator_js_invalid_email'),
+            "input_validator_js_more_characters" =>
+            tl('input_validator_js_more_characters'),
+            "input_validator_js_strong_password" =>
+            tl('input_validator_js_strong_password'),
+            "input_validator_js_weak_password" =>
+            tl('input_validator_js_weak_password'),
+             "input_validator_js_enter_username" =>
+            tl('input_validator_js_enter_username'),
+            "input_validator_js_enter_firstname" =>
+            tl('input_validator_js_enter_firstname'),
+            "input_validator_js_enter_lastname" =>
+            tl('input_validator_js_enter_lastname'),
+            "input_validator_js_retype_password_matched" =>
+            tl('input_validator_js_retype_password_matched'),
+            "input_validator_js_retype_password_not_matched" =>
+            tl('input_validator_js_retype_password_not_matched'),
+            "input_validator_js_type_password" =>
+            tl('input_validator_js_type_password')];
+        $data['SCRIPT'] = 'tl = '.json_encode($tl).';';
         $this->displayView($view, $data);
     }
     /**
@@ -934,6 +961,7 @@ class RegisterController extends Controller implements CrawlConstants
     public function setupQuestionViewData()
     {
         $data = [];
+        $data['INCLUDE_SCRIPTS'] = ["input_validator"];
         $fields = $this->register_fields;
         foreach ($fields as $field) {
             $data[strtoupper($field)] = "";
@@ -944,7 +972,7 @@ class RegisterController extends Controller implements CrawlConstants
         }
         if (C\AUTHENTICATION_MODE == C\ZKP_AUTHENTICATION) {
             $data['AUTHENTICATION_MODE'] = C\ZKP_AUTHENTICATION;
-            $data['INCLUDE_SCRIPTS'] = ["sha1", "zkp"," big_int"];
+            $data['INCLUDE_SCRIPTS'] = ["sha1", "zkp"," big_int","input_validator"];
         } else {
             $data['AUTHENTICATION_MODE'] = C\NORMAL_AUTHENTICATION;
         }
diff --git a/src/scripts/input_validator.js b/src/scripts/input_validator.js
new file mode 100644
index 0000000..122a6d9
--- /dev/null
+++ b/src/scripts/input_validator.js
@@ -0,0 +1,250 @@
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009 - 2016  Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Sarika Padmashali
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009 - 2016
+ * @filesource
+ */
+/*
+     * checks whether the password retype field has been touched or not
+     * defaults to false
+     * @var boolean
+*/
+var clicked = false;
+/*
+     * checks whether the email is valid or not
+     * defaults to false
+     * @var boolean
+*/
+var email_valid = false;
+/*
+     * checks whether the password is valid or not
+     * defaults to false
+     * @var boolean
+*/
+var password_valid = false;
+/*
+     * checks whether the retyped password is valid or not
+     * defaults to false
+     * @var boolean
+*/
+var password_match_valid = false;
+/*
+     * defining translation variable
+*/
+var tl = document.tl;
+/*
+ * To validate email address
+ *
+ * Checks if the email address entered is in the correct format
+ * @return boolean true if the email address entered is valid else return false
+ */
+function validateEmail()
+{
+    var mail_format = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
+    var input_text = elt("email");
+    if(input_text.value.match(mail_format)) {
+        var email_error = elt("email-error");
+        email_error.innerHTML = "<span class=\"green\">" +
+            tl['input_validator_js_valid_email'] + "</span>";
+        email_valid  = true;
+        submitDisabled();
+        return true;
+    } else {
+        var email_error = elt("email-error");
+        email_error.innerHTML = "<span class=\"red\">" +
+            tl['input_validator_js_invalid_email'] + "</span>";
+        email_valid  = false;
+        submitDisabled();
+        return false;
+    }
+}
+/*
+ * To validate password
+ *
+ * Checks if the password entered is strong enough
+ * Warns the user of the password is weak or blank
+ * It also checks if the retyped password matches
+ */
+function passwordChanged()
+{
+    var strength = elt("strength");
+    var strong_regex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|" +
+        "((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g");
+    var enough_regex = new RegExp("(?=.{6,}).*", "g");
+    var password = elt("pass-word");
+    if (password.value.length==0) {
+        strength.innerHTML = tl['input_validator_js_type_password'];
+        password_valid = false;
+        submitDisabled();
+    } else if (enough_regex.test(password.value) == false) {
+        strength.innerHTML = "<span class=\"red\">" +
+         tl['input_validator_js_more_characters'] + "</span>";
+        password_valid = false;
+        submitDisabled();
+    } else if (strong_regex.test(password.value)) {
+        strength.innerHTML = "<span class=\"green\">" +
+            tl['input_validator_js_strong_password'] + "</span>";
+        password_valid = true;
+        if(clicked == true) {
+            passwordMatch();
+        }
+        submitDisabled();
+    } else {
+        strength.innerHTML = "<span class=\"red\">" +
+            tl['input_validator_js_weak_password'] + "</span>";
+        password_valid = false;
+        submitDisabled();
+    }
+}
+/*
+ * To check if retyped password matches
+ *
+ * Checks if the retyped password matches
+ * If not warns the user about it
+ */
+function passwordMatch()
+{
+    clicked = true;
+    var retyped_pass = elt("retype-password");
+    var password= elt("pass-word");
+    var password_match = elt("pass-match");
+    if ( retyped_pass.value == password.value) {
+        password_match_valid = true;
+        password_match.innerHTML = "<span class=\"green\">" +
+            tl['input_validator_js_retype_password_matched'] + "</span>";
+        submitDisabled();
+    } else {
+        password_match_valid = false;
+        password_match.innerHTML = "<span class=\"red\">" +
+            tl['input_validator_js_retype_password_not_matched'] + "</span>";
+        submitDisabled();
+    }
+}
+/*
+ * To check if user name is not blank
+ *
+ * Checks if the user name has been entered
+ * If not warns the user to enter the username
+ */
+function checkUser()
+{
+    var user =  elt("username").value;
+    var user_error = elt("user-error");
+    if (user == "") {
+        userValid = false;
+        user_error.innerHTML = "<span class=\"red\">" +
+            tl['input_validator_js_enter_username'] + "</span>";
+
+    } else {
+        user_error.innerHTML = "<span class=\"red\"></span>";
+    }
+    submitDisabled();
+}
+/*
+ * To check if first name is not blank
+ *
+ * Checks if the first name has been entered
+ * If not warns the user to enter the first name
+ */
+function checkFirst()
+{
+    var first =  elt("firstname").value;
+    var first_error = elt("first-error");
+    if (first == "") {
+        first_error.innerHTML = "<span class=\"red\">" +
+            tl['input_validator_js_enter_firstname'] + "</span>";
+    } else {
+        first_error.innerHTML = "<span class=\"red\"></span>";
+    }
+    submitDisabled();
+}
+/*
+ * To check if last name is not blank
+ *
+ * Checks if the last name has been entered
+ * If not warns the user to enter the last name
+ */
+function checkLast()
+{
+    var last =  elt("lastname").value;
+    var last_error = elt("last-error");
+    if (last == "") {
+        lastValid = false;
+        last_error.innerHTML = "<span class=\"red\">" +
+            tl['input_validator_js_enter_lastname'] + "</span>";
+    } else {
+        last_error.innerHTML = "<span class=\"red\"></span>";
+    }
+    submitDisabled();
+}
+/*
+ * Disables the submit button
+ *
+ * Enables the submit button only if all input fields are valid
+ * If not keeps the submit button disabled until the user corrects all the fields
+ */
+function submitDisabled()
+{
+    var user =  elt("username").value;
+    var first = elt("firstname").value;
+    var last = elt("lastname").value;
+    if (email_valid == true && password_valid == true &&
+        password_match_valid == true && first != "" &&last != "" && user!= "") {
+        elt("submit").disabled = false;
+    } else {
+        elt("submit").disabled = true;
+    }
+}
+/*
+ * event handler to check first name
+ *
+ */
+elt("firstname").addEventListener("keyup", checkFirst);
+/*
+ * event handler to check last name
+ *
+ */
+elt("lastname").addEventListener("keyup", checkLast);
+/*
+ * event handler to check user name
+ *
+ */
+elt("username").addEventListener("keyup", checkUser);
+/*
+ * event handler to validate email address
+ *
+ */
+elt("email").addEventListener("keyup",validateEmail);
+/*
+ * event handler to validate password
+ *
+ */
+elt("pass-word").addEventListener("keyup", passwordChanged);
+/*
+ * event handler to validate retyped password
+ *
+ */
+elt("retype-password").addEventListener("keyup", passwordMatch);
diff --git a/src/views/RegisterView.php b/src/views/RegisterView.php
index 1768bec..8af2839 100755
--- a/src/views/RegisterView.php
+++ b/src/views/RegisterView.php
@@ -198,7 +198,8 @@ class RegisterView extends View
                                 name="first" autocomplete="off"
                                 value = "<?= $data['FIRST'] ?>"/>
                             <?= in_array("first", $missing)
-                                ?'<span class="red">*</span>':'' ?></td>
+                                ?'<span class="red">*</span>':'' ?>
+                            <span id="first-error"></span></td>
                     </tr>
                     <tr>
                         <th class="table-label">
@@ -213,7 +214,8 @@ class RegisterView extends View
                                 name="last" autocomplete="off"
                                 value = "<?= $data['LAST']  ?>"/>
                             <?= in_array("last", $missing) ?
-                                '<span class="red">*</span>':'' ?></td>
+                                '<span class="red">*</span>':'' ?>
+                            <span id="last-error"></span></td>
                     </tr>
                     <tr>
                         <th class="table-label"><label for="username">
@@ -226,7 +228,8 @@ class RegisterView extends View
                                 name="user" autocomplete="off"
                                 value = "<?= $data['USER'] ?>"/>
                             <?= in_array("user", $missing) ?
-                                '<span class="red">*</span>':'' ?></td>
+                                '<span class="red">*</span>':'' ?>
+                            <span id="user-error"></span></td>
                     </tr>
                     <tr>
                         <th class="table-label"><label for="email"><?=
@@ -239,7 +242,10 @@ class RegisterView extends View
                                 name="email" autocomplete="off"
                                 value = "<?= $data['EMAIL'] ?>"/>
                             <?= in_array("email", $missing)
-                                ? '<span class="red">*</span>':'' ?></td>
+                                ? '<span class="red">*</span>':'' ?>
+                            <span id="email-error"><?=
+                            tl('register_view_type_email_address')
+                            ?></span></td>
                     </tr>
                     <tr>
                         <th class="table-label">
@@ -254,7 +260,10 @@ class RegisterView extends View
                                 name="password" value="<?=
                                 $data['PASSWORD'] ?>" />
                             <?= in_array("password", $missing)
-                                ? '<span class="red">*</span>':'' ?></td>
+                                ? '<span class="red">*</span>':'' ?>
+                            <span id="strength"><?=
+                            tl('register_view_type_password')
+                            ?></span></td>
                     </tr>
                     <tr>
                         <th class="table-label">
@@ -269,7 +278,8 @@ class RegisterView extends View
                                 name="repassword" value="<?=
                                 $data['REPASSWORD'] ?>" />
                             <?= in_array("repassword", $missing)
-                                ?'<span class="red">*</span>' : '' ?></td>
+                                ?'<span class="red">*</span>' : '' ?>
+                            <span id="pass-match"></span></td>
                     </tr>
                     <?php
                     if (isset($_SESSION["random_string"]) ||
@@ -352,7 +362,7 @@ class RegisterView extends View
                         <input type="hidden"
                             name="<?php e(C\CSRF_TOKEN);?>"
                             value="<?php e($data[C\CSRF_TOKEN]); ?>"/>
-                            <button  type="submit"><?= 
+                            <button id="submit" type="submit" disabled><?=
                             tl('register_view_create_account')
                             ?></button>
                         </td>
-- 
2.6.4

