VirtueMart Forum

VirtueMart 2 + 3 + 4 => Virtuemart Development and bug reports => Topic started by: kaiserdom on May 20, 2015, 16:01:30 PM

Title: Virtuemart 3 Password Validation - Client Side
Post by: kaiserdom on May 20, 2015, 16:01:30 PM
Hello everyone.

I was building an e-shop site with Joomla 3.4.1, VirtueMart 3.0.9. and PHP 5.5.12 when I ran into bricks wall. The problem is located  to the checkout area. I've set up the VM3 configuration in the way that allows "Not Registered Users" to checkout. And here they come my so-called "bugs":

First of all, the function myValidator(f, r) which is triggered with an onClick event in the "Register And Checkout" button, will not validate the Joomla options for a password of 8 characters long, with at least 1 digit being required. On the contrary, the VM3 registration system allows me to fill in the password with at least 1 character,as soon as this character is the same with password2 and even though it is a white space.

Secondly, if I have all the input fields filled-in but the two passwords fields are uneven, I will receive the following message:
[img=http://s2.postimg.org/af7lpc5xx/Error.jpg] (http://postimg.org/image/af7lpc5xx/)
I must repeat that all the name fields are properly filled-in.

Third and last, I'm wondering why the aforementioned system message isn't alerted in the same page ( com_virtuemart /user/edit_address.php)  in order to give me the opportunity to re-enter the passwords properly but it redirects me to the checkout page. This way I have to click again the "Add/Edit billing address information" button.
Title: Re: Virtuemart 3 Password Length Validation
Post by: kaiserdom on May 25, 2015, 01:37:23 AM
Client-side registration validation still doesn't work. Virtuemart passes wrong class names to userfields and that seems to be the problem. For example, the "Password Field" must have a class of "validate-password" and instead of that VM3 assigns a class of "inputbox". I read in another VM forum post that Joomla 3 validation is embedded in VM3, but I've seen no result till now. 
:(
Title: Re: Virtuemart 3 Password Length Validation
Post by: Milbo on May 27, 2015, 13:24:50 PM
try model userfields around line 869


$req = $_fld->required ? 'required' : '';
$class = 'class="validate-password '.$req.' inputbox"';
$_return['fields'][$_fld->name]['formcode'] = '<input type="password" id="' . $_prefix.$_fld->name . '_field" name="' . $_prefix.$_fld->name .'" '.($_fld->required ? ' class="required"' : ''). ' size="30" '.$class.' />'."\n";
Title: Re: Virtuemart 3 Password Length Validation
Post by: kaiserdom on May 29, 2015, 15:57:33 PM
Milbo thank you very much for your concern.

Your solution helped me a lot to achieve Client-Side-Validation with the help of HTML5 "pattern" attribute. The lines of code that I added to line 864 of file "mysite\administrator\components\com_virtuemart\models\userfields.php and gave me the desired effect are cited below:


case 'password':
$myReqAlert1="Password between 8 and 20 characters; must contain at least one lowercase letter, one uppercase letter, one numeric digit, and one special character, but cannot contain whitespace!";
$req = $_fld->required ? 'required' : '';
        $class = 'class="validate-password '.$req.' inputbox"';
        $_return['fields'][$_fld->name]['formcode'] = '<input type="password" title="'.$myReqAlert1.'" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}" id="' . $_prefix.$_fld->name . '_field" name="' . $_prefix.$_fld->name .'" '.($_fld->required ? ' class="required"' : ''). ' size="30" '.$class.' onchange="form.password2.pattern = this.value;" />'."\n";
break;
case 'password2':
$myReqAlert2="Confirmation password must be the same with password above! ";
$req = $_fld->required ? 'required' : '';
        $class = 'class="validate-password '.$req.' inputbox"';
        $_return['fields'][$_fld->name]['formcode'] = '<input type="password" title="'.$myReqAlert2.'" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}" id="' . $_prefix.$_fld->name . '_field" name="' . $_prefix.$_fld->name .'" '.($_fld->required ? ' class="required"' : ''). ' size="30" '.$class.' />'."\n";
break;



Now the problem is the Server-Side validation which allows (if someone pass through JavaScript) posts with no rules,  as soon as the two passwords are equal.




Title: Re: Virtuemart 3 Password Validation (50% solved - Client Side)
Post by: Milbo on June 01, 2015, 12:00:35 PM
use your switch right. use the fallthrough
Title: Re: Virtuemart 3 Password Validation (50% solved - Client Side)
Post by: kaiserdom on June 02, 2015, 17:05:09 PM
You mean something like that?

case 'password':
case 'password2':
                  $myReqString1="Password between 8 and 20 characters; must contain at least one lowercase letter, one uppercase letter, one numeric digit, and one special character, but cannot contain whitespace!";
                  $myReqString2="Confirmation password must be the same with password above! ";
                  $myAlert=($_fld->name=='password')?$myReqString1:$myReqString2;
  $equalPass=($_fld->name=='password')?'onchange="form.password2.pattern = this.value;"':'';
                  $req = $_fld->required ? 'required' : '';
                          $class = 'class="validate-password '.$req.' inputbox"';
                          $_return['fields'][$_fld->name]['formcode'] = '<input type="password" rel="popover" data-placement="left" data-content="'.$myAlert.'" data-trigger="focus" title="Instructions" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}" id="' . $_prefix.$_fld->name . '_field" name="' . $_prefix.$_fld->name .'" '.($_fld->required ? ' class="required"' : ''). ' size="30" '.$class.' '.$equalPass.' />'."\n";
break;



I've also put the script below in my_template/index.php in order to trigger field popovers:

...
<script type="text/javascript">
    jQuery(document).ready(function() {
        jQuery('[rel=popover]').popover();
    });
</script>
</body>
</html>



Finally I've included a nice image effect through css

#password_field:valid:focus, #password2_field:valid:focus {
      background: rgba(0, 0, 0, 0) url("../images/icone16.png") no-repeat scroll 130px -585px;
}

http://postimg.org/image/ml01klgwx/


#password_field:invalid:focus, #password2_field:invalid:focus {
      background: rgba(0, 0, 0, 0) url("../images/icone16.png") no-repeat scroll 130px -370px;
}

http://postimg.org/image/lib7hqyd9/

Beware with icone16.png url reference, because I moved the image in folder by preference.
It works fine, but there is no Server-Side validation for password. I believe that I'll give it up and mark this issue as solved.
Title: Re: Virtuemart 3 Password Validation (50% solved - Client Side)
Post by: ftorrado on August 09, 2021, 16:41:59 PM
You just saved my day. I know that the option to register is not the best practice for an online shop, but sometimes a developer has clients that don't care about best practices. It was my case.

Thank you very much for sharing your solution.

Quote from: kaiserdom on June 02, 2015, 17:05:09 PM
You mean something like that?

case 'password':
case 'password2':
                  $myReqString1="Password between 8 and 20 characters; must contain at least one lowercase letter, one uppercase letter, one numeric digit, and one special character, but cannot contain whitespace!";
                  $myReqString2="Confirmation password must be the same with password above! ";
                  $myAlert=($_fld->name=='password')?$myReqString1:$myReqString2;
  $equalPass=($_fld->name=='password')?'onchange="form.password2.pattern = this.value;"':'';
                  $req = $_fld->required ? 'required' : '';
                          $class = 'class="validate-password '.$req.' inputbox"';
                          $_return['fields'][$_fld->name]['formcode'] = '<input type="password" rel="popover" data-placement="left" data-content="'.$myAlert.'" data-trigger="focus" title="Instructions" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}" id="' . $_prefix.$_fld->name . '_field" name="' . $_prefix.$_fld->name .'" '.($_fld->required ? ' class="required"' : ''). ' size="30" '.$class.' '.$equalPass.' />'."\n";
break;



I've also put the script below in my_template/index.php in order to trigger field popovers:

...
<script type="text/javascript">
    jQuery(document).ready(function() {
        jQuery('[rel=popover]').popover();
    });
</script>
</body>
</html>



Finally I've included a nice image effect through css

#password_field:valid:focus, #password2_field:valid:focus {
      background: rgba(0, 0, 0, 0) url("../images/icone16.png") no-repeat scroll 130px -585px;
}

http://postimg.org/image/ml01klgwx/


#password_field:invalid:focus, #password2_field:invalid:focus {
      background: rgba(0, 0, 0, 0) url("../images/icone16.png") no-repeat scroll 130px -370px;
}

http://postimg.org/image/lib7hqyd9/

Beware with icone16.png url reference, because I moved the image in folder by preference.
It works fine, but there is no Server-Side validation for password. I believe that I'll give it up and mark this issue as solved.
Title: Re: Virtuemart 3 Password Validation - Client Side
Post by: Milbo on October 05, 2021, 14:30:32 PM
Interesting to see this old post. We may add that.

The clienside validation would be here user model line 1157   public function validateUserData(&$data,$type='BT',$showInfo = false)