View | Details | Raw Unified | Return to bug 29925
Collapse All | Expand All

(-)a/installer/data/mysql/atomicupdate/bug_29925_password_reset.pl (+15 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number => "29925",
5
    description => "Add password reset option",
6
    up => sub {
7
        my ($args) = @_;
8
        my ($dbh, $out) = @$args{qw(dbh out)};
9
        $dbh->do(q{
10
            INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
11
            ('EnableExpiredPasswordReset', '0', NULL, 'Enable ability for patrons with expired password to reset their password directly', 'YesNo')
12
        });
13
        say $out "Added EnableExpirePasswordReset system preference";
14
    },
15
};
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (+8 lines)
Lines 362-367 Patrons: Link Here
362
               0: "Don't require"
362
               0: "Don't require"
363
         - a strong password for staff and patrons
363
         - a strong password for staff and patrons
364
         - (must contain at least one digit, one lowercase and one uppercase).
364
         - (must contain at least one digit, one lowercase and one uppercase).
365
     -
366
         - pref: EnableExpiredPasswordReset
367
           choices:
368
               1: "Enable"
369
               0: "Don't enable"
370
         - the ability for patrons to directly reset their password when it is expired.
371
         - If not enable patrons must either use the 'Forgot your password' feature or have staff
372
         - reset their password.
365
     -
373
     -
366
         - Block a patron's account if it reaches
374
         - Block a patron's account if it reaches
367
         - pref: FailedLoginAttempts
375
         - pref: FailedLoginAttempts
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt (-1 / +3 lines)
Lines 51-57 Link Here
51
    [% END %]
51
    [% END %]
52
[% ELSIF password_has_expired %]
52
[% ELSIF password_has_expired %]
53
    <div id="login_error"><strong>Error: </strong>Your password has expired!</div>
53
    <div id="login_error"><strong>Error: </strong>Your password has expired!</div>
54
    [% IF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
54
    [% IF Koha.Preference('EnableExpiredPasswordReset') && Koha.Preference('OpacBaseURL') %]
55
        <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-reset-password.pl">You must reset your password</a>.
56
    [% ELSIF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
55
        <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
57
        <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
56
    [% ELSE %]
58
    [% ELSE %]
57
        <p>You must contact the library to have your password reset</p>
59
        <p>You must contact the library to have your password reset</p>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt (-2 / +4 lines)
Lines 171-179 Link Here
171
                            <div class="alert alert-info">
171
                            <div class="alert alert-info">
172
                                <p><strong>Error: </strong>Your password has expired!</p>
172
                                <p><strong>Error: </strong>Your password has expired!</p>
173
                            </div>
173
                            </div>
174
                            [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
174
                            [% IF Koha.Preference('EnableExpiredPasswordReset') %]
175
                                <a href="/cgi-bin/koha/opac-reset-password.pl">Reset your password</a>.
176
                            [% ELSIF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
175
                                <div id="resetpassword">
177
                                <div id="resetpassword">
176
                                    <a href="/cgi-bin/koha/opac-password-recovery.pl">Reset your password?</a>
178
                                    <a href="/cgi-bin/koha/opac-password-recovery.pl">Reset your password</a>
177
                                </div>
179
                                </div>
178
                            [% ELSE %]
180
                            [% ELSE %]
179
                                <p>You must contact the library to reset your password</p>
181
                                <p>You must contact the library to reset your password</p>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-reset-password.tt (+157 lines)
Line 0 Link Here
1
[% USE raw %]
2
[% USE Koha %]
3
[% USE Categories %]
4
[% USE AdditionalContents %]
5
[% PROCESS 'html_helpers.inc' %]
6
[% INCLUDE 'doc-head-open.inc' %]
7
<title>
8
    Reset your password
9
    &rsaquo;
10
 [% IF ( LibraryNameTitle ) %][% LibraryNameTitle | html %][% ELSE %]Koha online[% END %] catalog
11
</title>
12
[% INCLUDE 'doc-head-close.inc' %]
13
[% BLOCK cssinclude %][% END %]
14
</head>
15
[% INCLUDE 'bodytag.inc' bodyid='opac-login-page' bodyclass='scrollto' %]
16
[% INCLUDE 'masthead.inc' %]
17
18
<div class="main">
19
    <nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumbs">
20
        <ol class="breadcrumb">
21
            <li class="breadcrumb-item">
22
                <a href="/cgi-bin/koha/opac-main.pl">Home</a>
23
            </li>
24
            <li class="breadcrumb-item active">
25
                <a href="#" aria-current="page">Reset your password</a>
26
            </li>
27
        </
28
    </nav> <!-- /#breadcrumbs -->
29
30
    <div class="container-fluid">
31
        <div class="row justify-content-center">
32
            <div class="col-md-10 col-lg-6">
33
                <div id="opac-auth" class="maincontent">
34
                    [% IF Koha.Preference( 'opacuserlogin' ) && Koha.Preference('EnableExpiredPasswordReset') %]
35
                        [% IF ( error ) %]
36
                            <div class="alert alert-warning">
37
                                <h2>There was a problem with your submission</h2>
38
                                <p>
39
                                    [% SWITCH error %]
40
                                        [% CASE  'no_change' %]
41
                                            New password must not be the same as old password.
42
                                        [% CASE  'passwords_mismatch' %]
43
                                            Passwords do not match.  Please re-type your new password.
44
                                        [% CASE 'password_too_short' %]
45
                                            Password must be at least [% minPasswordLength | html %] characters long.
46
                                        [% CASE 'password_too_weak' %]
47
                                            Password must contain at least one digit, one lowercase and one uppercase.
48
                                        [% CASE 'password_has_whitespaces' %]
49
                                            Password must not contain leading or trailing whitespaces.
50
                                        [% CASE 'invalid_credentials' %]
51
                                            You entered an incorrect username or password. Please try again! But note that passwords are case sensitive[% IF Koha.Preference('FailedLoginAttempts') %] and that your account will be locked out after a fixed number of failed login attempts[% END %]. Please contact a library staff member if you continue to have problems.
52
                                        [% CASE 'no_expire' %]
53
                                            Please log-in to account to update your password.</br>
54
                                            <a href="/cgi-bin/koha/opac-user.pl" class="nav-link login-link loginModal-trigger"><i class="fa fa-user fa-icon-black fa-fw" aria-hidden="true"></i> <span class="userlabel">Log in to your account</span></a>
55
                                        [% CASE 'account_locked' %]
56
                                            This account has been locked!
57
                                            [% IF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
58
                                                <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password via e-mail</a>.
59
                                            [% ELSE %]
60
                                                You must contact the library for assistance
61
                                            [% END %]
62
                                        [% CASE %]
63
                                            An unknown error occurred. PLease try again or contact the library for assistance
64
                                    [% END %]
65
                                </p>
66
                            </div>
67
                        [% END %]
68
                        [% IF ( password_updated ) %]
69
                            <div class="alert dialog-alert">
70
                                <h2>Your password has successfully been updated</h2>
71
                                <a href="/cgi-bin/koha/opac-main.pl" class="btn btn-primary">Go to OPAC</a>
72
                                [% IF ( Koha.Preference('staffClientBaseURL') && staff_access ) %]
73
                                    <a href="[% Koha.Preference('staffClientBaseURL') | url %]" class="btn btn-primary">Go to Staff client</a>
74
                                [% END %]
75
                            </div>
76
                        [% ELSE %]
77
                        <form action="/cgi-bin/koha/opac-reset-password.pl" name="mainform" id="mainform" method="post" autocomplete="off">
78
                            <legend class="sr-only">Reset your password</legend>
79
80
                            <fieldset class="brief">
81
                                <div class="form-group">
82
                                    <label for="userid">Login:</label>
83
                                    <input class="form-control" type="text"  size="25" id="userid"  name="userid" />
84
                                </div>
85
                                <div class="form-group">
86
                                    <label for="currentpassword">Current password:</label>
87
                                    <input class="form-control" autocomplete="off" type="password"  size="25" id="currentpassword"  name="currentpassword" />
88
                                </div>
89
                                <div class="form-group">
90
                                    <label for="newpassword">New password:</label>
91
                                    <input class="form-control" autocomplete="off" type="password"  size="25" id="newpassword"  name="newpassword" />
92
                                </div>
93
                                <div class="form-group">
94
                                    <label for="confirmpassword">Confirm new password:</label>
95
                                    <input class="form-control" autocomplete="off" type="password"  size="25" id="confirmpassword"  name="confirmpassword" />
96
                                </div>
97
                                <fieldset class="action">
98
                                    <input type="submit" value="Update password" class="btn btn-primary" />
99
                                </fieldset>
100
                                <input type="hidden" name="op" value="update" />
101
                            </fieldset>
102
                            [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
103
                                <div id="resetpassword">
104
                                    <a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a>
105
                                </div>
106
                            [% END %]
107
                        </form>
108
                        [% END # /IF Error_messages %]
109
110
                    [% ELSE %]
111
                        <h1>Resetting your password has not been enabled by the library.</h1>
112
                        [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
113
                            <div id="resetpassword">
114
                                <a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a>
115
                            </div>
116
                        [% ELSE %]
117
                            <p>You must contact the library to reset your password</p>
118
                        [% END %]
119
                    [% END # / IF opacuserlogin %]
120
121
                </div> <!-- /.opac-auth -->
122
            </div> <!-- /.col-md-10 col-lg-6 -->
123
        </div> <!-- /.row -->
124
    </div> <!-- /.container-fluid -->
125
</div> <!-- /.main -->
126
127
[% INCLUDE 'opac-bottom.inc' %]
128
[% BLOCK jsinclude %]
129
    [% Asset.js("lib/jquery/plugins/jquery.validate.min.js") | $raw %]
130
    <script>
131
        jQuery.validator.addMethod("password_no_spaces", function(value, element){
132
            return ( this.optional(element) || !value.match(/^\s/) && !value.match(/\s$/) );
133
        }, _("Password contains leading and/or trailing spaces"));
134
        jQuery.validator.addMethod("password_match", function(value, element){
135
            var new_password_node = $("input[name='newpassword']:first");
136
            return value == $(new_password_node).val();
137
        }, _("Please enter the same password as above"));
138
139
        $(document).ready(function() {
140
            $("#mainform").validate({
141
                rules: {
142
                    currentpassword: {
143
                        required: true,
144
                    },
145
                    newpassword: {
146
                        required: true,
147
                        password_no_spaces: true
148
                    },
149
                    confirmpassword: {
150
                        required: true,
151
                        password_match: true
152
                    }
153
                }
154
            });
155
        });
156
    </script>
157
[% END %]
(-)a/opac/opac-reset-password.pl (-1 / +110 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
# This script lets the users change the passwords by themselves.
3
#
4
# (c) 2005 Universidad ORT Uruguay.
5
#
6
# This file is part of the extensions and enhacments made to koha by Universidad ORT Uruguay
7
#
8
# Koha is free software; you can redistribute it and/or modify it
9
# under the terms of the GNU General Public License as published by
10
# the Free Software Foundation; either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# Koha is distributed in the hope that it will be useful, but
14
# WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21
use Modern::Perl;
22
23
use CGI qw ( -utf8 );
24
25
use C4::Auth qw( get_template_and_user checkpw checkpw_hash );
26
use C4::Context;
27
use C4::Output qw( output_html_with_http_headers );
28
use Koha::Patrons;
29
30
use Try::Tiny qw( catch try );
31
32
my $query = CGI->new;
33
34
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
35
    {
36
        template_name   => "opac-reset-password.tt",
37
        query           => $query,
38
        type            => "opac",
39
        authnotrequired => 1,
40
    }
41
);
42
43
my $op = $query->param('op');
44
45
if ( $op eq 'update' ) {
46
    my $userid          = $query->param('userid');
47
    my $currentpassword = $query->param('currentpassword');
48
    my $newpassword     = $query->param('newpassword');
49
    my $confirmpassword = $query->param('confirmpassword');
50
51
    my $patron = Koha::Patrons->find( { userid => $userid } );
52
    $patron = Koha::Patrons->find( { cardnumber => $userid } ) unless $patron;
53
54
    if ( $patron && $patron->password_expiration_date ) {
55
        if ( $patron->account_locked ) {
56
            $template->param( error => 'account_locked' );
57
        }
58
        elsif ( $currentpassword && $newpassword && $confirmpassword ) {
59
            my $error;
60
            if ( C4::Auth::checkpw_hash( $currentpassword, $patron->password ) ) {
61
62
                if ( $newpassword ne $confirmpassword ) {
63
                    $template->param( 'error' => 'passwords_mismatch' );
64
                }
65
                elsif ( $currentpassword eq $newpassword ) {
66
                    $template->param( 'error' => 'no_change' );
67
                }
68
                else {
69
                    try {
70
                        $patron->set_password( { password => $newpassword } );
71
                        $template->param( 'password_updated' => '1' );
72
                        $template->param( 'staff_access'     => 1 )
73
                          if $patron->has_permission( { catalogue => 1 } );
74
                    }
75
                    catch {
76
                        $error = 'password_too_short'
77
                          if $_->isa('Koha::Exceptions::Password::TooShort');
78
                        $error = 'password_too_weak'
79
                          if $_->isa('Koha::Exceptions::Password::TooWeak');
80
                        $error = 'password_has_whitespaces'
81
                          if $_->isa(
82
                            'Koha::Exceptions::Password::WhitespaceCharacters');
83
                        $template->param( 'error' => $error );
84
                    };
85
                }
86
            }
87
            else {
88
                $template->param( 'error' => 'invalid_credentials' );
89
                $patron->update(
90
                    { login_attempts => $patron->login_attempts + 1 } )
91
                  if !$patron->account_locked;
92
            }
93
        }
94
        else {
95
            $template->param( 'incomplete_form' => '1' );
96
        }
97
    }
98
    elsif ( !$patron ) {
99
        template->param( 'error' => 'invalid_credentials' );
100
    }
101
    elsif ( !$patron->password_expiration_date ) {
102
        $template->param( 'error' => 'no_expire' );
103
    }
104
    else {
105
        $template->param( 'error' => 'unknown' );
106
    }
107
}
108
109
output_html_with_http_headers $query, $cookie, $template->output, undef,
110
  { force_no_caching => 1 };

Return to bug 29925