Bug 27974: Replace obsolete title-string sorting: Circulation templates
[koha.git] / opac / opac-password-recovery.pl
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4 use CGI;
5
6 use C4::Auth;
7 use C4::Koha;
8 use C4::Output;
9 use C4::Context;
10 use Koha::Patron::Password::Recovery
11   qw(SendPasswordRecoveryEmail ValidateBorrowernumber GetValidLinkInfo CompletePasswordRecovery DeleteExpiredPasswordRecovery);
12 use Koha::Patrons;
13 my $query = CGI->new;
14 use HTML::Entities;
15 use Try::Tiny;
16 use List::Util qw/any/;
17
18 my ( $template, $dummy, $cookie ) = get_template_and_user(
19     {
20         template_name   => "opac-password-recovery.tt",
21         query           => $query,
22         type            => "opac",
23         authnotrequired => 1,
24         debug           => 1,
25     }
26 );
27
28 my $email          = $query->param('email') // q{};
29 my $password       = $query->param('newPassword');
30 my $repeatPassword = $query->param('repeatPassword');
31 my $id             = $query->param('id');
32 my $uniqueKey      = $query->param('uniqueKey');
33 my $username       = $query->param('username') // q{};
34 my $borrower_number;
35
36 #errors
37 my $hasError;
38
39 #email form error
40 my $errNoBorrowerFound;
41 my $errNoBorrowerEmail;
42 my $errMultipleAccountsForEmail;
43 my $errAlreadyStartRecovery;
44 my $errResetForbidden;
45
46 #new password form error
47 my $errLinkNotValid;
48
49 if ( $query->param('sendEmail') || $query->param('resendEmail') ) {
50
51     #try with the main email
52     my $borrower;
53     my $search_results;
54     # Find the borrower by userid, card number, or email
55     if ($username) {
56         $search_results = Koha::Patrons->search( { -or => { userid => $username, cardnumber => $username }, login_attempts => { '!=', Koha::Patron::ADMINISTRATIVE_LOCKOUT } } );
57     }
58     elsif ($email) {
59         $search_results = Koha::Patrons->search( { -or => { email => $email, emailpro => $email, B_email  => $email }, login_attempts => { '!=', Koha::Patron::ADMINISTRATIVE_LOCKOUT } } );
60     }
61
62     if ( !defined $search_results || $search_results->count < 1) {
63         $hasError           = 1;
64         $errNoBorrowerFound = 1;
65     }
66     elsif ( $username && $search_results->count > 1) { # Multiple accounts for username
67         $hasError           = 1;
68         $errNoBorrowerFound = 1;
69     }
70     elsif ( $email && $search_results->count > 1) { # Muliple accounts for E-Mail
71         $hasError           = 1;
72         $errMultipleAccountsForEmail = 1;
73     }
74     elsif ( $borrower = $search_results->next() ) {    # One matching borrower
75
76         if ( $borrower->category->effective_reset_password ) {
77
78             my @emails = grep { $_ } ( $borrower->email, $borrower->emailpro, $borrower->B_email );
79
80             my $firstNonEmptyEmail;
81             $firstNonEmptyEmail = $emails[0] if @emails;
82
83             # Is the given email one of the borrower's ?
84             if ( $email && !( any { lc($_) eq lc($email) } @emails ) ) {
85                 $hasError    = 1;
86                 $errNoBorrowerFound = 1;
87             }
88
89             # If there is no given email, and there is no email on record
90             elsif ( !$email && !$firstNonEmptyEmail ) {
91                 $hasError           = 1;
92                 $errNoBorrowerEmail = 1;
93             }
94
95             # Check if a password reset already issued for this
96             # borrower AND we are not asking for a new email
97             elsif ( not $query->param('resendEmail') ) {
98                 if ( ValidateBorrowernumber( $borrower->borrowernumber ) ) {
99                     $hasError                = 1;
100                     $errAlreadyStartRecovery = 1;
101                 }
102                 else {
103                     DeleteExpiredPasswordRecovery( $borrower->borrowernumber );
104                 }
105             }
106             # Set the $email, if we don't have one.
107             if ( !$hasError && !$email ) {
108                 $email = $firstNonEmptyEmail;
109             }
110         }
111         else {
112             $hasError          = 1;
113             $errResetForbidden = 1;
114         }
115     }
116     else {    # 0 matching borrower
117         $hasError           = 1;
118         $errNoBorrowerFound = 1;
119     }
120     if ($hasError) {
121         $template->param(
122             hasError                => 1,
123             errNoBorrowerFound      => $errNoBorrowerFound,
124             errAlreadyStartRecovery => $errAlreadyStartRecovery,
125             errNoBorrowerEmail      => $errNoBorrowerEmail,
126             errMultipleAccountsForEmail => $errMultipleAccountsForEmail,
127             errResetForbidden       => $errResetForbidden,
128             password_recovery       => 1,
129             email                   => HTML::Entities::encode($email),
130             username                => $username
131         );
132     }
133     elsif ( SendPasswordRecoveryEmail( $borrower, $email, scalar $query->param('resendEmail') ) ) {    # generate uuid and send recovery email
134         $template->param(
135             mail_sent => 1,
136             email     => $email
137         );
138     }
139     else {    # if it doesn't work....
140         $template->param(
141             hasError          => 1,
142             password_recovery => 1,
143             sendmailError     => 1
144         );
145     }
146 }
147 elsif ( $query->param('passwordReset') ) {
148     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
149
150     my $error;
151     my $min_password_length = C4::Context->preference('minPasswordPreference');
152     my $require_strong_password = C4::Context->preference('RequireStrongPassword');
153     if ( not $borrower_number ) {
154         $error = 'errLinkNotValid';
155     } elsif ( $password ne $repeatPassword ) {
156         $error = 'errPassNotMatch';
157     } else {
158         my $borrower = Koha::Patrons->find($borrower_number);
159         $min_password_length = $borrower->category->effective_min_password_length;
160         $require_strong_password = $borrower->category->effective_require_strong_password;
161         try {
162             $borrower->set_password({ password => $password });
163
164             CompletePasswordRecovery($uniqueKey);
165             $template->param(
166                 password_reset_done => 1,
167                 username            => $username
168             );
169         }
170         catch {
171             if ( $_->isa('Koha::Exceptions::Password::TooShort') ) {
172                 $error = 'password_too_short';
173             }
174             elsif ( $_->isa('Koha::Exceptions::Password::WhitespaceCharacters') ) {
175                 $error = 'password_has_whitespaces';
176             }
177             elsif ( $_->isa('Koha::Exceptions::Password::TooWeak') ) {
178                 $error = 'password_too_weak';
179             }
180         };
181     }
182     if ( $error ) {
183         $template->param(
184             new_password => 1,
185             email        => $email,
186             uniqueKey    => $uniqueKey,
187             hasError     => 1,
188             $error       => 1,
189             minPasswordLength => $min_password_length,
190             RequireStrongPassword => $require_strong_password
191         );
192     }
193 }
194 elsif ($uniqueKey) {    #reset password form
195                         #check if the link is valid
196     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
197
198     if ( !$borrower_number ) {
199         $errLinkNotValid = 1;
200     }
201
202     my $borrower = Koha::Patrons->find($borrower_number);
203
204     $template->param(
205         new_password    => 1,
206         email           => $email,
207         uniqueKey       => $uniqueKey,
208         username        => $username,
209         errLinkNotValid => $errLinkNotValid,
210         hasError        => ( $errLinkNotValid ? 1 : 0 ),
211         minPasswordLength => $borrower->category->effective_min_password_length,
212         RequireStrongPassword => $borrower->category->effective_require_strong_password
213     );
214 }
215 else {    #password recovery form (to send email)
216     $template->param( password_recovery => 1 );
217 }
218
219 output_html_with_http_headers $query, $cookie, $template->output;