Bug 22990: Add CSRF protection to boraccount, pay and suggestion
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / members / member-password.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE Koha %]
4 [% USE Branches %]
5 [% SET footerjs = 1 %]
6 [% INCLUDE 'doc-head-open.inc' %]
7 <title>
8     [% IF ( newpassword ) %]Password updated [% ELSE %]Update password for [% patron.surname | html %], [% patron.firstname | html %][% END %] &rsaquo; Patrons &rsaquo; Koha
9 </title>
10 [% INCLUDE 'doc-head-close.inc' %]
11 </head>
12
13 <body id="pat_member-password" class="pat">
14 [% WRAPPER 'header.inc' %]
15     [% INCLUDE 'patron-search-header.inc' %]
16 [% END %]
17
18 [% WRAPPER 'sub-header.inc' %]
19     [% WRAPPER breadcrumbs %]
20         [% WRAPPER breadcrumb_item %]
21             <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>
22         [% END %]
23         [% WRAPPER breadcrumb_item %]
24             <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% INCLUDE 'patron-title.inc' %]</a>
25         [% END %]
26         [% WRAPPER breadcrumb_item bc_active= 1 %]
27             [% IF ( newpassword ) %]
28                 <span>Password updated</span>
29             [% ELSE %]
30                 <span>Change username and/or password</span>
31             [% END %]
32         [% END %]
33     [% END #/ WRAPPER breadcrumbs %]
34 [% END #/ WRAPPER sub-header.inc %]
35
36 <div class="main container-fluid">
37     <div class="row">
38         <div class="col-sm-10 col-sm-push-2">
39             <main>
40
41 [% INCLUDE 'members-toolbar.inc' %]
42
43 [% IF ( newpassword ) %]
44 <h1>Password updated</h1>
45
46 [% ELSE %]
47
48 <form method="post" id="changepasswordf" action="/cgi-bin/koha/members/member-password.pl">
49 <input type="hidden" name="destination" value="[% destination | html %]" />
50 <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% patron.borrowernumber | html %]" />
51         [% IF ( errormsg ) %]
52                 <div class="dialog alert">
53                 <h4>The following errors have occurred:</h4>
54                 <ul>
55                 [% IF ( BADUSERID ) %]
56         <li>You have entered a username that already exists. Please choose another one.</li>
57                 [% END %]
58         [% IF ( ERROR_password_too_short ) %]
59             <li id="ERROR_short_password">Password must be at least [% patron.category.effective_min_password_length | html %] characters long.</li>
60         [% END %]
61         [% IF ( ERROR_password_too_weak ) %]
62             <li id="ERROR_weak_password">Password must contain at least one digit, one lowercase and one uppercase.</li>
63         [% END %]
64         [% IF ( ERROR_password_has_whitespaces ) %]
65             <li id="ERROR_weak_password">Password must not contain leading or trailing whitespaces.</li>
66         [% END %]
67         [% IF ( ERROR_from_plugin ) %]
68             <li id="ERROR_from_plugin">The password was rejected by a plugin.</li>
69         [% END %]
70                 [% IF ( NOPERMISSION ) %]
71                 <li>You do not have permission to edit this patron's login information.</li>
72                 [% END %]
73                 [% IF ( NOMATCH ) %]
74                 <li><strong>The passwords entered do not match</strong>. Please re-enter the new password.</li>
75                 [% END %]
76                 </ul>
77                 </div>
78         [% END %]
79
80
81     <fieldset class="brief rows"><legend><h1>Change username and/or password for [% patron.firstname | html %] [% patron.surname | html %]</h1></legend>
82         <ol>
83     <li><label for="newuserid">New username:</label>
84     <input type="hidden" name="member" value="[% patron.borrowernumber | html %]" /><input type="text" id="newuserid" name="newuserid" size="20" value="[% patron.userid | html %]" /></li>
85     [% SET password_pattern = ".{" _ patron.category.effective_min_password_length _ ",}" %]
86     [% IF patron.category.effective_require_strong_password %]
87         [% SET password_pattern = '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{' _ patron.category.effective_min_password_length _ ',}' %]
88     [% END %]
89     <li>
90         <label for="newpassword">New password:</label>
91         <input name="newpassword"  id="newpassword" type="password" size="20" autocomplete="new-password" />
92     </li>
93     <li>
94         <label for="newpassword2">Confirm new password:</label>
95         <input name="newpassword2"  id="newpassword2" type="password" size="20" autocomplete="new-password" />
96     </li>
97         </ol>
98     <div class="hint">Koha cannot display existing passwords. Leave the field blank to leave password unchanged.</div>
99 </fieldset>
100     <fieldset class="action">
101         <input type="hidden" name="csrf_token" value="[% csrf_token | html %]" />
102         <input type="submit" class="btn btn-primary" value="Save" />
103         <a class="cancel" href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | html %]">Cancel</a>
104     </fieldset>
105 </form>[% END %]
106
107
108 <div class="loading hide"><strong>Processing...</strong><img src="[% interface | html %]/[% theme | html %]/img/loading.gif" alt="" /></div>
109
110             </main>
111         </div> <!-- /.col-sm-10.col-sm-push-2 -->
112
113         <div class="col-sm-2 col-sm-pull-10">
114             <aside>
115                 [% INCLUDE 'circ-menu.inc' %]
116             </aside>
117         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
118     </div> <!-- /.row -->
119
120 [% MACRO jsinclude BLOCK %]
121     [% INCLUDE 'str/members-menu.inc' %]
122     [% Asset.js("js/members-menu.js") | $raw %]
123     <script>
124         function generate_password() {
125             // Always generate a strong password
126             var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
127             var length = [% patron.category.effective_min_password_length | html %];
128             if ( length < 8 ) length = 8;
129             var password='';
130             for ( var i = 0 ; i < length ; i++){
131                 password += chars.charAt(Math.floor(Math.random()*chars.length));
132             }
133             return password;
134         }
135         $(document).ready(function() {
136             $("body").on('click', "#fillrandom",function(e) {
137                 e.preventDefault();
138                 var password = '';
139                 var pattern_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{[% patron.category.effective_min_password_length | html %],}/;
140                 while ( ! pattern_regex.test( password ) ) {
141                     password = generate_password();
142                 }
143                 $("#newpassword").val(password);
144                 $("#newpassword").attr('type', 'text');
145                 $("#newpassword2").val(password);
146                 $("#newpassword2").attr('type', 'text');
147             });
148             $("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>");
149
150             [% IF logged_in_user.borrowernumber == patron.borrowernumber %]
151                 $("#newuserid").on("change", function(){
152                     $(this).parent().find("div.hint").remove();
153                     if ( "[% patron.userid | html %]" != $(this).val() ) {
154                         $(this).parent().append('<div class="hint">%s</div>'.format(_("You will be logged out if you modify your username")));
155                     }
156                 });
157             [% END %]
158
159             $(document).ajaxStart(function () {
160                 $("input[name^=newpassword]").hide();
161                 $("label[for=newpassword2]").hide();
162                 $(".hint:last").after($(".loading").show());
163             });
164             $(document).ajaxStop(function () {
165                 $("input[name^=newpassword]").show();
166                 $("label[for=newpassword2]").show();
167                 $(".loading").hide();
168                 $("label.error").hide();
169             });
170             [% IF NOMATCH %]
171                 $("#newpassword").addClass('focus');
172             [% END %]
173
174             $("#changepasswordf").validate({
175                 rules: {
176                     newpassword: {
177                         password_strong: true,
178                         password_no_spaces: true
179                     },
180                     newpassword2: {
181                         password_match: true
182                     }
183                 }
184             });
185         });
186     </script>
187     [% PROCESS 'password_check.inc' new_password => 'newpassword', minPasswordLength => patron.category.effective_min_password_length, RequireStrongPassword => patron.category.effective_require_strong_password %]
188 [% END %]
189
190 [% INCLUDE 'intranet-bottom.inc' %]