Koha/opac/opac-password-recovery.pl
David Kuhn e29163af4c Bug 18616 - The "Add forgot password link to OPAC" should allow patrons to use their library card number in addition to username
Allow patrons to enter either their library card number or user name in the "Log in" box for password recovery.

Most patrons at our library use their card number to log in and are unaware of what their userid is. However there are some who have set a

customized userid and would prefer to use that. This patch would allow either to be entered for password recovery.

To test:
1. Enable the password recovery feature.
2. In the OPAC, click on "Forgot you password?" link and enter a valid library card number.
3. The error message "No account found with the provided information" appears.
4. Apply the patch.
5. Repeat step 2. The recovery email is now sent.

Note: Moved patch from 16711 back here and re-tested.
Signed-off-by: Marc Véron <veron@veron.ch>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
2017-07-06 14:52:53 -03:00

203 lines
6.6 KiB
Perl
Executable file

#!/usr/bin/perl
use Modern::Perl;
use CGI;
use C4::Auth;
use C4::Koha;
use C4::Output;
use C4::Context;
use Koha::Patron::Password::Recovery
qw(SendPasswordRecoveryEmail ValidateBorrowernumber GetValidLinkInfo CompletePasswordRecovery DeleteExpiredPasswordRecovery);
use Koha::Patrons;
use Koha::AuthUtils qw(hash_password);
use Koha::Patrons;
my $query = new CGI;
use HTML::Entities;
my ( $template, $dummy, $cookie ) = get_template_and_user(
{
template_name => "opac-password-recovery.tt",
query => $query,
type => "opac",
authnotrequired => 1,
debug => 1,
}
);
my $email = $query->param('email') // q{};
my $password = $query->param('password');
my $repeatPassword = $query->param('repeatPassword');
my $minPassLength = C4::Context->preference('minPasswordLength');
my $id = $query->param('id');
my $uniqueKey = $query->param('uniqueKey');
my $username = $query->param('username');
my $borrower_number;
#errors
my $hasError;
#email form error
my $errNoBorrowerFound;
my $errNoBorrowerEmail;
my $errMultipleAccountsForEmail;
my $errAlreadyStartRecovery;
my $errTooManyEmailFound;
my $errBadEmail;
#new password form error
my $errLinkNotValid;
my $errPassNotMatch;
my $errPassTooShort;
if ( $query->param('sendEmail') || $query->param('resendEmail') ) {
#try with the main email
$email ||= ''; # avoid undef
my $borrower;
my $search_results;
# Find the borrower by userid, card number, or email
if ($username) {
$search_results = Koha::Patrons->search( { -or => { userid => $username, cardnumber => $username } } );
}
elsif ($email) {
$search_results = Koha::Patrons->search( { -or => { email => $email, emailpro => $email, B_email => $email } } );
}
if ( not $search_results || $search_results->count < 1) {
$hasError = 1;
$errNoBorrowerFound = 1;
}
elsif ( $username && $search_results->count > 1) { # Multiple accounts for username
$hasError = 1;
$errNoBorrowerFound = 1;
}
elsif ( $email && $search_results->count > 1) { # Muliple accounts for E-Mail
$hasError = 1;
$errMultipleAccountsForEmail = 1;
}
elsif ( $borrower = $search_results->next() ) { # One matching borrower
$username ||= $borrower->userid;
my @emails = ( $borrower->email, $borrower->emailpro, $borrower->B_email );
my $firstNonEmptyEmail = '';
foreach my $address ( @emails ) {
$firstNonEmptyEmail = $address if length $address;
last if $firstNonEmptyEmail;
}
# Is the given email one of the borrower's ?
if ( $email && !( grep { $_ eq $email } @emails ) ) {
$hasError = 1;
$errNoBorrowerFound = 1;
}
# If we dont have an email yet. Get one of the borrower's email or raise an error.
elsif ( !$email && !( $email = $firstNonEmptyEmail ) ) {
$hasError = 1;
$errNoBorrowerEmail = 1;
}
# Check if a password reset already issued for this borrower AND we are not asking for a new email
elsif ( not $query->param('resendEmail') ) {
if ( ValidateBorrowernumber( $borrower->borrowernumber ) ) {
$hasError = 1;
$errAlreadyStartRecovery = 1;
}
else {
DeleteExpiredPasswordRecovery( $borrower->borrowernumber );
}
}
}
else { # 0 matching borrower
$hasError = 1;
$errNoBorrowerFound = 1;
}
if ($hasError) {
$template->param(
hasError => 1,
errNoBorrowerFound => $errNoBorrowerFound,
errTooManyEmailFound => $errTooManyEmailFound,
errAlreadyStartRecovery => $errAlreadyStartRecovery,
errBadEmail => $errBadEmail,
errNoBorrowerEmail => $errNoBorrowerEmail,
errMultipleAccountsForEmail => $errMultipleAccountsForEmail,
password_recovery => 1,
email => HTML::Entities::encode($email),
username => $username
);
}
elsif ( SendPasswordRecoveryEmail( $borrower, $email, $query->param('resendEmail') ) ) { # generate uuid and send recovery email
$template->param(
mail_sent => 1,
email => $email
);
}
else { # if it doesn't work....
$template->param(
password_recovery => 1,
sendmailError => 1
);
}
}
elsif ( $query->param('passwordReset') ) {
( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
#validate password length & match
if ( ($borrower_number)
&& ( $password eq $repeatPassword )
&& ( length($password) >= $minPassLength ) )
{ #apply changes
Koha::Patrons->find($borrower_number)->update_password( $username, hash_password($password) );
CompletePasswordRecovery($uniqueKey);
$template->param(
password_reset_done => 1,
username => $username
);
}
else { #errors
if ( !$borrower_number ) { #parameters not valid
$errLinkNotValid = 1;
}
elsif ( $password ne $repeatPassword ) { #passwords does not match
$errPassNotMatch = 1;
}
elsif ( length($password) < $minPassLength ) { #password too short
$errPassTooShort = 1;
}
$template->param(
new_password => 1,
minPassLength => $minPassLength,
email => $email,
uniqueKey => $uniqueKey,
errLinkNotValid => $errLinkNotValid,
errPassNotMatch => $errPassNotMatch,
errPassTooShort => $errPassTooShort,
hasError => 1
);
}
}
elsif ($uniqueKey) { #reset password form
#check if the link is valid
( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey);
if ( !$borrower_number ) {
$errLinkNotValid = 1;
}
$template->param(
new_password => 1,
minPassLength => $minPassLength,
email => $email,
uniqueKey => $uniqueKey,
username => $username,
errLinkNotValid => $errLinkNotValid,
hasError => ( $errLinkNotValid ? 1 : 0 ),
);
}
else { #password recovery form (to send email)
$template->param( password_recovery => 1 );
}
output_html_with_http_headers $query, $cookie, $template->output;