Bug 8753 - Followup - change value text on syspref
[koha.git] / opac / opac-password-recovery.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use Modern::Perl;
5 use CGI;
6
7 use C4::Auth;
8 use C4::Koha;
9 use C4::Members qw(changepassword Search);
10 use C4::Output;
11 use C4::Context;
12 use C4::Passwordrecovery qw(SendPasswordRecoveryEmail ValidateBorrowernumber GetValidLinkInfo CompletePasswordRecovery);
13 use Koha::AuthUtils qw(hash_password);
14 my $query = new CGI;
15 use HTML::Entities;
16
17 my ( $template, $dummy, $cookie ) = get_template_and_user(
18     {
19         template_name   => "opac-password-recovery.tt",
20         query           => $query,
21         type            => "opac",
22         authnotrequired => 1,
23         debug           => 1,
24     }
25 );
26
27 my $email          = $query->param('email') // q{};
28 my $password       = $query->param('password');
29 my $repeatPassword = $query->param('repeatPassword');
30 my $minPassLength  = C4::Context->preference('minPasswordLength');
31 my $id             = $query->param('id');
32 my $uniqueKey      = $query->param('uniqueKey');
33 my $username       = $query->param('username');
34 my $borrower_number;
35
36 #errors
37 my $hasError;
38
39 #email form error
40 my $errNoBorrowerFound;
41 my $errNoBorrowerEmail;
42 my $errAlreadyStartRecovery;
43 my $errTooManyEmailFound;
44 my $errBadEmail;
45
46 #new password form error
47 my $errLinkNotValid;
48 my $errPassNotMatch;
49 my $errPassTooShort;
50
51 if ( $query->param('sendEmail') || $query->param('resendEmail') ) {
52     my $protocol = $query->https() ? "https://" : "http://";
53     #try with the main email
54     $email ||= ''; # avoid undef
55     my $borrower;
56     my $search_results;
57     # Find the borrower by his userid or email
58     if( $username ){
59         $search_results = Search({ userid => $username });
60     }
61     elsif ( $email ){
62         $search_results = Search({ '' => $email }, undef, undef, undef, ['emailpro', 'email', 'B_email']);
63     }
64     if ( not $search_results ){
65        $hasError            = 1;
66        $errNoBorrowerFound  = 1;
67     }
68     elsif(scalar @$search_results > 1){ # Many matching borrowers
69        $hasError             = 1;
70        $errTooManyEmailFound = 1;
71     }
72     elsif( $borrower = shift @$search_results ){ # One matching borrower
73         $username ||= $borrower->{'userid'};
74         my @emails = ( $borrower->{'email'}, $borrower->{'emailpro'}, $borrower->{'B_email'} );
75         # Is the given email one of the borrower's ?
76         if( $email && !($email ~~ @emails) ){
77              $hasError    = 1;
78              $errBadEmail = 1;
79         }
80         # If we dont have an email yet. Get one of the borrower's email or raise an error.
81         # FIXME: That ugly shift-grep contraption.
82         # $email = shift [ grep { length() } @emails ]
83         # It's supposed to get a non-empty string from the @emails array. There's surely a simpler way
84         elsif( !$email && !($email = shift [ grep { length() } @emails ]) ){
85              $hasError           = 1;
86              $errNoBorrowerEmail = 1;
87         }
88         # Check if a password reset already issued for this borrower AND we are not asking for a new email
89         elsif( ValidateBorrowernumber( $borrower->{'borrowernumber'} ) && !$query->param('resendEmail') ){
90             $hasError                = 1;
91             $errAlreadyStartRecovery = 1;
92         }
93     }
94     else{ # 0 matching borrower
95         $hasError           = 1;
96         $errNoBorrowerFound = 1;
97     }
98     if ($hasError) {
99         $template->param(
100             hasError                => 1,
101             errNoBorrowerFound      => $errNoBorrowerFound,
102             errTooManyEmailFound    => $errTooManyEmailFound,
103             errAlreadyStartRecovery => $errAlreadyStartRecovery,
104             errBadEmail             => $errBadEmail,
105             errNoBorrowerEmail      => $errNoBorrowerEmail,
106             password_recovery       => 1,
107             email                   => HTML::Entities::encode($email),
108             username                => $username
109         );
110     }
111     elsif ( SendPasswordRecoveryEmail( $borrower, $email, $protocol, $query->param('resendEmail') ) ) {#generate uuid and send recovery email
112         $template->param(
113             mail_sent => 1,
114             email     => $email
115         );
116     }
117     else {# if it doesn't work....
118         $template->param(
119             password_recovery => 1,
120             sendmailError     => 1
121         );
122     }
123 }
124 elsif ( $query->param('passwordReset') ) {
125     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
126     #validate password length & match
127     if (   ($borrower_number)
128         && ( $password eq $repeatPassword )
129         && ( length($password) >= $minPassLength ) )
130     {  #apply changes
131         changepassword( $username, $borrower_number, hash_password($password) );
132         CompletePasswordRecovery($uniqueKey);
133         $template->param(
134             password_reset_done => 1,
135             username            => $username
136         );
137     }
138     else { #errors
139         if ( !$borrower_number ) { #parameters not valid
140             $errLinkNotValid = 1;
141         }
142         elsif ( $password ne $repeatPassword ) { #passwords does not match
143             $errPassNotMatch = 1;
144         }
145         elsif ( length($password) < $minPassLength ) { #password too short
146             $errPassTooShort = 1;
147         }
148         $template->param(
149             new_password    => 1,
150             minPassLength   => $minPassLength,
151             email           => $email,
152             uniqueKey       => $uniqueKey,
153             errLinkNotValid => $errLinkNotValid,
154             errPassNotMatch => $errPassNotMatch,
155             errPassTooShort => $errPassTooShort,
156             hasError        => 1
157         );
158     }
159 }
160 elsif ($uniqueKey) {  #reset password form
161     #check if the link is valid
162     ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
163
164     if ( !$borrower_number ) {
165         $errLinkNotValid = 1;
166     }
167
168     $template->param(
169         new_password    => 1,
170         minPassLength   => $minPassLength,
171         email           => $email,
172         uniqueKey       => $uniqueKey,
173         username        => $username,
174         errLinkNotValid => $errLinkNotValid
175     );
176 }
177 else { #password recovery form (to send email)
178     $template->param( password_recovery => 1 );
179 }
180
181 output_html_with_http_headers $query, $cookie, $template->output;