5 [% PROCESS 'i18n.inc' %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>[% FILTER collapse %]
9 [% IF ( newpassword ) %]
10 [% t("Password updated") | html %]
12 [% t("Update password for") | html %] [% INCLUDE 'patron-title.inc' no_html = 1 %]
14 [% t("Patrons") | html %] ›
15 [% t("Koha") | html %]
17 [% INCLUDE 'doc-head-close.inc' %]
20 <body id="pat_member-password" class="pat">
21 [% WRAPPER 'header.inc' %]
22 [% INCLUDE 'patron-search-header.inc' %]
25 [% WRAPPER 'sub-header.inc' %]
26 [% WRAPPER breadcrumbs %]
27 [% WRAPPER breadcrumb_item %]
28 <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>
30 [% WRAPPER breadcrumb_item %]
31 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% INCLUDE 'patron-title.inc' %]</a>
33 [% WRAPPER breadcrumb_item bc_active= 1 %]
34 [% IF ( newpassword ) %]
35 <span>Password updated</span>
37 <span>Change username and/or password</span>
40 [% END #/ WRAPPER breadcrumbs %]
41 [% END #/ WRAPPER sub-header.inc %]
43 <div class="main container-fluid">
45 <div class="col-sm-10 col-sm-push-2">
48 [% INCLUDE 'members-toolbar.inc' %]
50 [% IF ( newpassword ) %]
51 <h1>Password updated</h1>
55 <form method="post" id="changepasswordf" action="/cgi-bin/koha/members/member-password.pl">
56 <input type="hidden" name="destination" value="[% destination | html %]" />
57 <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" />
59 <div class="dialog alert">
60 <h4>The following errors have occurred:</h4>
62 [% IF ( BADUSERID ) %]
63 <li>You have entered a username that already exists. Please choose another one.</li>
65 [% IF ( ERROR_password_too_short ) %]
66 <li id="ERROR_short_password">Password must be at least [% patron.category.effective_min_password_length | html %] characters long.</li>
68 [% IF ( ERROR_password_too_weak ) %]
69 <li id="ERROR_weak_password">Password must contain at least one digit, one lowercase and one uppercase.</li>
71 [% IF ( ERROR_password_has_whitespaces ) %]
72 <li id="ERROR_weak_password">Password must not contain leading or trailing whitespaces.</li>
74 [% IF ( ERROR_from_plugin ) %]
75 <li id="ERROR_from_plugin">The password was rejected by a plugin.</li>
77 [% IF ( NOPERMISSION ) %]
78 <li>You do not have permission to edit this patron's login information.</li>
81 <li><strong>The passwords entered do not match</strong>. Please re-enter the new password.</li>
88 <fieldset class="brief rows"><legend><h1>Change username and/or password for [% patron.firstname | html %] [% patron.surname | html %]</h1></legend>
90 <li><label for="newuserid">New username:</label>
91 <input type="hidden" name="member" value="[% patron.borrowernumber | html %]" /><input type="text" id="newuserid" name="newuserid" size="20" value="[% patron.userid | html %]" /></li>
92 [% SET password_pattern = ".{" _ patron.category.effective_min_password_length _ ",}" %]
93 [% IF patron.category.effective_require_strong_password %]
94 [% SET password_pattern = '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{' _ patron.category.effective_min_password_length _ ',}' %]
97 <label for="newpassword">New password:</label>
98 <input name="newpassword" id="newpassword" type="password" size="20" autocomplete="new-password" />
101 <label for="newpassword2">Confirm new password:</label>
102 <input name="newpassword2" id="newpassword2" type="password" size="20" autocomplete="new-password" />
105 <div class="hint">Koha cannot display existing passwords. Leave the field blank to leave password unchanged.</div>
107 <fieldset class="action">
108 <input type="hidden" name="csrf_token" value="[% csrf_token | html %]" />
109 <input type="submit" class="btn btn-primary" value="Save" />
110 <a class="cancel" href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | html %]">Cancel</a>
115 <div class="loading hide"><strong>Processing...</strong><img src="[% interface | html %]/[% theme | html %]/img/loading.gif" alt="" /></div>
118 </div> <!-- /.col-sm-10.col-sm-push-2 -->
120 <div class="col-sm-2 col-sm-pull-10">
122 [% INCLUDE 'circ-menu.inc' %]
124 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
125 </div> <!-- /.row -->
127 [% MACRO jsinclude BLOCK %]
128 [% INCLUDE 'str/members-menu.inc' %]
129 [% Asset.js("js/members-menu.js") | $raw %]
131 function generate_password() {
132 // Always generate a strong password
133 var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
134 var length = [% patron.category.effective_min_password_length | html %];
135 if ( length < 8 ) length = 8;
137 for ( var i = 0 ; i < length ; i++){
138 password += chars.charAt(Math.floor(Math.random()*chars.length));
142 $(document).ready(function() {
143 $("body").on('click', "#fillrandom",function(e) {
146 var pattern_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{[% patron.category.effective_min_password_length | html %],}/;
147 while ( ! pattern_regex.test( password ) ) {
148 password = generate_password();
150 $("#newpassword").val(password);
151 $("#newpassword").attr('type', 'text');
152 $("#newpassword2").val(password);
153 $("#newpassword2").attr('type', 'text');
155 $("div.hint").eq(0).after(" <div class=\"hint\"><a href=\"#\" id=\"fillrandom\">"+_("Click to fill with a randomly generated suggestion. ")+"<strong>"+_("Passwords will be displayed as text")+"</strong>.</a></div>");
157 [% IF logged_in_user.borrowernumber == patron.borrowernumber %]
158 $("#newuserid").on("change", function(){
159 $(this).parent().find("div.hint").remove();
160 if ( "[% patron.userid | html %]" != $(this).val() ) {
161 $(this).parent().append('<div class="hint">%s</div>'.format(_("You will be logged out if you modify your username")));
166 $(document).ajaxStart(function () {
167 $("input[name^=newpassword]").hide();
168 $("label[for=newpassword2]").hide();
169 $(".hint:last").after($(".loading").show());
171 $(document).ajaxStop(function () {
172 $("input[name^=newpassword]").show();
173 $("label[for=newpassword2]").show();
174 $(".loading").hide();
175 $("label.error").hide();
178 $("#newpassword").addClass('focus');
181 $("#changepasswordf").validate({
184 password_strong: true,
185 password_no_spaces: true
194 [% PROCESS 'password_check.inc' new_password => 'newpassword', minPasswordLength => patron.category.effective_min_password_length, RequireStrongPassword => patron.category.effective_require_strong_password %]
197 [% INCLUDE 'intranet-bottom.inc' %]