Line 0
Link Here
|
0 |
- |
1 |
#!/usr/bin/perl |
|
|
2 |
|
3 |
use strict; |
4 |
use Modern::Perl; |
5 |
|
6 |
use CGI; |
7 |
use Mail::Sendmail; |
8 |
use HTML::Entities; |
9 |
|
10 |
use C4::Auth; |
11 |
use C4::Koha; |
12 |
use C4::Members qw(changepassword GetMember GetMemberDetails SendPasswordRecoveryEmail); |
13 |
use C4::Output; |
14 |
use C4::Context; |
15 |
use Koha::AuthUtils qw(hash_password); |
16 |
|
17 |
my $query = new CGI; |
18 |
|
19 |
my ( $template, $borrowernumber, $cookie ) = get_template_and_user( |
20 |
{ |
21 |
template_name => "opac-password-recovery.tmpl", |
22 |
query => $query, |
23 |
type => "opac", |
24 |
authnotrequired => 1, |
25 |
debug => 1, |
26 |
} |
27 |
); |
28 |
|
29 |
my $email = $query->param('email') // q{}; |
30 |
my $password = $query->param('password'); |
31 |
my $repeatPassword = $query->param('repeatPassword'); |
32 |
my $minPassLength = C4::Context->preference('minPasswordLength'); |
33 |
my $id = $query->param('id'); |
34 |
my $uniqueKey = $query->param('uniqueKey'); |
35 |
my $username = $query->param('username'); |
36 |
my $borrower_number; |
37 |
|
38 |
#errors |
39 |
my $hasError; |
40 |
|
41 |
#email form error |
42 |
my $errNoEmailFound; |
43 |
my $errAlreadyStartRecovery; |
44 |
|
45 |
#new password form error |
46 |
my $errLinkNotValid; |
47 |
my $errPassNotMatch; |
48 |
my $errPassTooShort; |
49 |
|
50 |
my $dbh = C4::Context->dbh; |
51 |
|
52 |
if ( $query->param('sendEmail') || $query->param('resendEmail') ) { |
53 |
#send mail + confirmation |
54 |
|
55 |
#try with the main email |
56 |
my $borrower_number; |
57 |
$email ||= ''; # avoid undef |
58 |
my $borrower_infos = GetMember( email => $email ); |
59 |
$borrower_infos = GetMember( emailpro => $email ) unless $borrower_infos; |
60 |
$borrower_infos = GetMember( B_email => $email ) unless $borrower_infos; |
61 |
if($borrower_infos) { |
62 |
$borrower_number = $borrower_infos->{'borrowernumber'}; |
63 |
$username = GetMemberDetails($borrower_number)->{'userid'}; |
64 |
} |
65 |
|
66 |
if ( !$email || !$username || !$borrower_number ) { |
67 |
$hasError = 1; |
68 |
$errNoEmailFound = 1; |
69 |
} |
70 |
elsif ( !$query->param('resendEmail') ) { |
71 |
my $sth = $dbh->prepare( |
72 |
"SELECT borrowernumber FROM borrower_password_recovery WHERE NOW() < valid_until AND borrowernumber = ?" |
73 |
); |
74 |
$sth->execute($borrower_number); |
75 |
if ( my $already = $sth->fetchrow ) { |
76 |
$hasError = 1; |
77 |
$errAlreadyStartRecovery = 1; |
78 |
} |
79 |
} |
80 |
|
81 |
if ($hasError) { |
82 |
$template->param( |
83 |
hasError => 1, |
84 |
errNoEmailFound => $errNoEmailFound, |
85 |
errAlreadyStartRecovery => $errAlreadyStartRecovery, |
86 |
password_recovery => 1, |
87 |
email => HTML::Entities::encode($email), |
88 |
); |
89 |
} |
90 |
elsif ( SendPasswordRecoveryEmail( $borrower_number, $email, $query, $query->param('resendEmail') ) ) {#generate uuid and send recovery email |
91 |
$template->param( |
92 |
mail_sent => 1, |
93 |
email => $email |
94 |
); |
95 |
} |
96 |
else {# if it doesnt work.... |
97 |
$template->param( |
98 |
password_recovery => 1, |
99 |
sendmailError => 1 |
100 |
); |
101 |
} |
102 |
} |
103 |
elsif ( $query->param('passwordReset') ) { |
104 |
#new password form |
105 |
#check if the link is still valid |
106 |
my $sth = $dbh->prepare( |
107 |
"SELECT borrower_password_recovery.borrowernumber, userid |
108 |
FROM borrower_password_recovery, borrowers |
109 |
WHERE borrowers.borrowernumber = borrower_password_recovery.borrowernumber |
110 |
AND NOW() < valid_until |
111 |
AND uuid = ?" |
112 |
); |
113 |
$sth->execute($uniqueKey); |
114 |
( $borrower_number, $username ) = $sth->fetchrow; |
115 |
|
116 |
#validate password length & match |
117 |
if ( ($borrower_number) |
118 |
&& ( $password eq $repeatPassword ) |
119 |
&& ( length($password) >= $minPassLength ) ) |
120 |
{ #apply changes |
121 |
changepassword( $username, $borrower_number, hash_password($password) ); |
122 |
|
123 |
#remove entry |
124 |
my $sth = $dbh->prepare( |
125 |
"DELETE FROM borrower_password_recovery |
126 |
WHERE uuid = ? |
127 |
ORDER BY valid_until DESC LIMIT 1" |
128 |
); |
129 |
$sth->execute($uniqueKey); |
130 |
|
131 |
$template->param( |
132 |
password_reset_done => 1, |
133 |
username => $username |
134 |
); |
135 |
} |
136 |
else { #errors |
137 |
if ( !$borrower_number ) { #parameters not valid |
138 |
$errLinkNotValid = 1; |
139 |
} |
140 |
elsif ( $password ne $repeatPassword ) { #passwords does not match |
141 |
$errPassNotMatch = 1; |
142 |
} |
143 |
elsif ( length($password) < $minPassLength ) { #password too short |
144 |
$errPassTooShort = 1; |
145 |
} |
146 |
$template->param( |
147 |
new_password => 1, |
148 |
minPassLength => $minPassLength, |
149 |
email => $email, |
150 |
uniqueKey => $uniqueKey, |
151 |
errLinkNotValid => $errLinkNotValid, |
152 |
errPassNotMatch => $errPassNotMatch, |
153 |
errPassTooShort => $errPassTooShort, |
154 |
hasError => 1 |
155 |
); |
156 |
} |
157 |
} |
158 |
elsif ($uniqueKey) { #reset password form |
159 |
#check if the link is valid |
160 |
my $sth = $dbh->prepare( |
161 |
"SELECT borrower_password_recovery.borrowernumber, userid |
162 |
FROM borrower_password_recovery, borrowers |
163 |
WHERE borrowers.borrowernumber = borrower_password_recovery.borrowernumber |
164 |
AND NOW() < valid_until |
165 |
AND uuid = ?" |
166 |
); |
167 |
$sth->execute($uniqueKey); |
168 |
( $borrower_number, $username ) = $sth->fetchrow; |
169 |
if ( !$borrower_number ) { |
170 |
$errLinkNotValid = 1; |
171 |
} |
172 |
$template->param( |
173 |
new_password => 1, |
174 |
minPassLength => $minPassLength, |
175 |
email => $email, |
176 |
uniqueKey => $uniqueKey, |
177 |
username => $username, |
178 |
errLinkNotValid => $errLinkNotValid |
179 |
); |
180 |
} |
181 |
else { #password recovery form (to send email) |
182 |
$template->param( password_recovery => 1 ); |
183 |
} |
184 |
|
185 |
output_html_with_http_headers $query, $cookie, $template->output; |