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