From 12eb817a904e46bdcc4e33c34aa5a5cfb1498700 Mon Sep 17 00:00:00 2001 From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Date: Thu, 16 Mar 2017 22:59:51 -0300 Subject: [PATCH] Bug 18298: Use the validate jQuery plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To validate password fields we need to use the validate jQuery plugin. To make things reusable this patch adds a new include file 'password_check.inc' at the intranet and opac sides, it creates 3 new validation methods: - password_strong => make sure the passwords are strong enough according to the values of the RequireStrongPassword and minPasswordLength prefs - password_no_spaces => prevent passwords to be entered with leading or trailing spaces - password_match => make sure both password fields match Signed-off-by: Marc VĂ©ron <veron@veron.ch> --- .../prog/en/includes/password_check.inc | 25 ++++++++ .../prog/en/modules/members/member-password.tt | 70 +++++++++++----------- .../prog/en/modules/members/memberentrygen.tt | 20 ++++++- koha-tmpl/intranet-tmpl/prog/js/members.js | 14 ----- .../bootstrap/en/includes/password_check.inc | 25 ++++++++ .../bootstrap/en/modules/opac-memberentry.tt | 18 ++++++ .../opac-tmpl/bootstrap/en/modules/opac-passwd.tt | 24 +++++++- 7 files changed, 142 insertions(+), 54 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/password_check.inc create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/includes/password_check.inc diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/password_check.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/password_check.inc new file mode 100644 index 0000000..eb730e6 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/password_check.inc @@ -0,0 +1,25 @@ +[% USE Koha %] +[% BLOCK add_password_check %] +<script type="text/javascript"> + var pwd_title = ""; + var pattern_title = ""; + var new_password_node_name = "[% new_password %]"; + [% IF Koha.Preference('RequireStrongPassword') %] + pwd_title = _("Password must contain at least %s characters, including UPPERCASE, lowercase and numbers").format([% minPasswordLength %]); + pattern_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{[% minPasswordLength %],}/; + [% ELSIF minPasswordLength %] + pwd_title = _("Password must contain at least %s characters").format([% minPasswordLength %]); + pattern_regex = /.{[% minPasswordLength %],}/; + [% END %] + jQuery.validator.addMethod("password_strong", function(value, element){ + return this.optional(element) || value == '****' || pattern_regex.test(value); + }, pwd_title); + jQuery.validator.addMethod("password_no_spaces", function(value, element){ + return ( this.optional(element) || !value.match(/^\s/) && !value.match(/\s$/) ); + }, _("Password contains leading and/or trailing spaces")); + jQuery.validator.addMethod("password_match", function(value, element){ + var new_password_node = $("input[name='" + new_password_node_name + "']:first"); + return this.optional(element) || value == $(new_password_node).val(); + }, _("Please enter the same password as above")); +</script> +[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt index 2c28996..5191551 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-password.tt @@ -1,3 +1,4 @@ +[% USE Koha %] [% USE Branches %] [% INCLUDE 'doc-head-open.inc' %] <title>Koha › Patrons › [% IF ( newpassword ) %]Password updated [% ELSE %]Update password for [% surname %], [% firstname %][% END %]</title> @@ -5,28 +6,7 @@ <script type="text/JavaScript"> //<![CDATA[ - function check_password( password ) { - if ( password.match(/^\s/) || password.match(/\s$/)) { - return false; - } - return true; - } - $(document).ready(function() { - var MSG_PASSWORD_CONTAINS_TRAILING_SPACES = _("Password contains leading and/or trailing spaces."); - $("#changepasswordf").submit(function(){ - if($("input[name='newpassword']").val() != $("input[name='newpassword2']").val()){ - alert(_("Passwords do not match")); - return false; - } else { - if ( ! check_password( $("input[name='newpassword']").val() ) ) { - alert(MSG_PASSWORD_CONTAINS_TRAILING_SPACES); - return false; - } else { - return true; -} - } - }); $("body").on('click', "#fillrandom",function(e) { e.preventDefault(); $.get("/cgi-bin/koha/members/member-password.pl?member=[% userid %]", function(response) { @@ -46,6 +26,24 @@ $("input[name^=newpassword]").show(); $("label[for=newpassword2]").show(); $(".loading").hide(); + $("label.error").hide(); + }); + [% IF NOMATCH %] + $("#newpassword").addClass('focus'); + [% END %] + + $("#changepasswordf").validate({ + rules: { + newpassword: { + required: true, + password_strong: true, + password_no_spaces: true + }, + newpassword2: { + required: true, + password_match: true + } + } }); }); //]]> @@ -98,21 +96,19 @@ <ol> <li><label for="newuserid">New username:</label> <input type="hidden" name="member" value="[% borrowernumber %]" /><input type="text" id="newuserid" name="newuserid" size="20" value="[% userid %]" /></li> - <li><label for="newpassword">New password:</label> - <div class="hint">Koha cannot display existing passwords. Leave the field blank to leave password unchanged.</div> - [% IF ( minPasswordLength ) %]<div class="hint">Minimum password length: [% minPasswordLength %]</div>[% END %] - [% IF ( NOMATCH ) %] - <input name="newpassword" id="newpassword" type="password" size="20" class="focus" /> - <input name="newpassword" id="newpassword_random" readonly="readonly" disabled="disabled" type="hidden" /> - [% ELSE %] - <input name="newpassword" id="newpassword" type="password" size="20" /> - <input name="newpassword" readonly="readonly" disabled="disabled" type="hidden" /> - [% END %] - </li> - <li><label for="newpassword2">Confirm new password:</label> - <input name="newpassword2" id="newpassword2" type="password" size="20" /> - <input name="newpassword2" id="newpassword2_random" readonly="readonly" disabled="disabled" type="hidden" /> - </li> + [% SET password_pattern = ".{" _ minPasswordLength _ ",}" %] + [% IF Koha.Preference('RequireStrongPassword') %] + [% SET password_pattern = '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{' _ minPasswordLength _ ',}' %] + [% END %] + <li> + <label for="newpassword">New password:</label> + <div class="hint">Koha cannot display existing passwords. Leave the field blank to leave password unchanged.</div> + <input name="newpassword" id="newpassword" type="password" size="20" /> + </li> + <li> + <label for="newpassword2">Confirm new password:</label> + <input name="newpassword2" id="newpassword2" type="password" size="20" /> + </li> </ol> </fieldset> <fieldset class="action"> @@ -131,3 +127,5 @@ </div> </div> [% INCLUDE 'intranet-bottom.inc' %] +[% PROCESS 'password_check.inc' %] +[% PROCESS 'add_password_check' new_password => 'newpassword' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt index ff3ef68..740786f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt @@ -72,6 +72,21 @@ $(document).ready(function() { } else {return false;} }); + + $("#entryform").validate({ + rules: { + password: { + required: true, + password_strong: true, + password_no_spaces: true + }, + password2: { + required: true, + password_match: true + } + } + }); + $("#saverecord").click(function(){ if( check_form_borrowers() ){ $("#entryform").submit(); @@ -88,8 +103,6 @@ $(document).ready(function() { var MSG_DUPLICATE_ORGANIZATION = _("Warning: Duplicate organization"); var MSG_LATE_EXPIRY = _("Warning: Expiration date falls before enrollment date"); var MSG_DUPLICATE_SUSPICION = _("Please confirm whether this is a duplicate patron"); - var MSG_PASSWORD_MISMATCH = _("The passwords entered do not match"); - var MSG_PASSWORD_CONTAINS_TRAILING_SPACES = _("Password contains leading and/or trailing spaces."); var MSG_MONTH = _("%s month") var MSG_MONTHS = _("%s months") var MSG_YEAR = _("%s year") @@ -1234,4 +1247,5 @@ $(document).ready(function() { [% END %] </div> [% INCLUDE 'intranet-bottom.inc' %] - +[% PROCESS 'password_check.inc' %] +[% PROCESS 'add_password_check' new_password => 'password' %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/members.js b/koha-tmpl/intranet-tmpl/prog/js/members.js index 3ea7868..10afad1 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/members.js +++ b/koha-tmpl/intranet-tmpl/prog/js/members.js @@ -103,20 +103,6 @@ function check_form_borrowers(nav){ } } } - if ( document.form.password ) { - if ( document.form.password.value != document.form.password2.value ){ - if ( message_champ !== '' ){ - message_champ += "\n"; - } - message_champ+= MSG_PASSWORD_MISMATCH; - statut=1; - } - - if ( ! check_password( document.form.password.value ) ) { - message_champ += MSG_PASSWORD_CONTAINS_TRAILING_SPACES; - statut = 1; - } - } //patrons form to test if you checked no to the question of double if (statut!=1 && document.form.check_member.value > 0 ) { diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/password_check.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/password_check.inc new file mode 100644 index 0000000..e2ed62e --- /dev/null +++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/password_check.inc @@ -0,0 +1,25 @@ +[% USE Koha %] +[% BLOCK add_password_check %] +<script type="text/javascript"> + var pwd_title = ""; + var pattern_title = ""; + var new_password_node_name = "[% new_password %]"; + [% IF Koha.Preference('RequireStrongPassword') %] + pwd_title = _("Password must contain at least %s characters, including UPPERCASE, lowercase and numbers").format([% minPasswordLength %]); + pattern_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{[% minPasswordLength %],}/; + [% ELSIF minPasswordLength %] + pwd_title = _("Password must contain at least %s characters").format([% minPasswordLength %]); + pattern_regex = /.{[% minPasswordLength %],}/; + [% END %] + jQuery.validator.addMethod("password_strong", function(value, element){ + return this.optional(element) || pattern_regex.test(value); + }, pwd_title); + jQuery.validator.addMethod("password_no_spaces", function(value, element){ + return ( this.optional(element) || !value.match(/^\s/) && !value.match(/\s$/) ); + }, _("Password contains leading and/or trailing spaces")); + jQuery.validator.addMethod("password_match", function(value, element){ + var new_password_node = $("input[name='" + new_password_node_name + "']:first"); + return this.optional(element) || value == $(new_password_node).val(); + }, _("Please enter the same password as above")); +</script> +[% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt index 231e2bf..6607ea8 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt @@ -987,6 +987,8 @@ [% INCLUDE 'opac-bottom.inc' %] [% BLOCK jsinclude %] <script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.validate.min.js"></script> + [% PROCESS 'password_check.inc' %] + [% PROCESS 'add_password_check' new_password => 'borrower_password' %] <script type="text/javascript"> //<![CDATA[ $(document).ready(function() { @@ -1011,6 +1013,22 @@ }, borrower_B_email: { email: true + }, + borrower_password: { + [% IF mandatory.defined('password') %] + required: true, + [% END %] + password_strong: true, + password_no_spaces: true + }, + borrower_password2: { + [% IF mandatory.defined('password') %] + required: true, + [% END %] + password_match: true + }, + captcha: { + required: true, } }, submitHandler: function(form) { diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-passwd.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-passwd.tt index 136bbac..baa083b 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-passwd.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-passwd.tt @@ -47,6 +47,7 @@ [% IF ( OpacPasswordChange ) %] [% IF ( Ask_data ) %] + <form action="/cgi-bin/koha/opac-passwd.pl" name="mainform" id="mainform" method="post"> <fieldset> [% UNLESS ( ShortPass ) %]<div class="alert alert-info">Your password must be at least [% minpasslen %] characters long.</div>[% END %] @@ -80,4 +81,25 @@ [% INCLUDE 'opac-bottom.inc' %] -[% BLOCK jsinclude %][% END %] +[% BLOCK jsinclude %] + <script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.validate.min.js"></script> + [% PROCESS 'password_check.inc' %] + [% PROCESS 'add_password_check' new_password => 'Newkey' %] + <script type="text/javascript"> + $(document).ready(function() { + $("#mainform").validate({ + rules: { + Newkey: { + required: true, + password_strong: true, + password_no_spaces: true + }, + Confirm: { + required: true, + password_match: true + } + } + }); + }); + </script> +[% END %] -- 2.9.3