From e2eab9a50130a3d5175893ee4b7fc04c3215618c Mon Sep 17 00:00:00 2001
From: Blou
Date: Tue, 28 Jan 2014 16:08:51 -0500
Subject: [PATCH] Bug 8753 - Add forgot password link to OPAC
This includes fix following the most recent comments and a rebasing to 3.15.15
Fixes all comments specified by mtompsett.
TEST PLAN:
1) apply the patch
2) go to system preferences OPAC>>Privacy and set 'OpacResetPassword' to ON. That will cause the link 'Forgot your password' to show up on the welcome page, below connection box.
3) refresh front page, click on 'Forgot your password' and enter a VALID address (one that is associated to an entry in borrowers.email or borrowers.email_pro.
3b) Also try an INVALID address (valid yet not in your koha db). An error message will show up.
4) An email should be received at that address with a link.
5) Follow the link in the mail to fill the new password.
Until a satisfactory new password is entered, the old password is not reset.
6) Go to main page try the new password.
---
C4/Auth.pm | 2 +
C4/Members.pm | 92 ++++++++-
installer/data/mysql/kohastructure.sql | 11 ++
installer/data/mysql/sysprefs.sql | 1 +
installer/data/mysql/updatedatabase.pl | 15 ++
.../prog/en/modules/admin/preferences/opac.pref | 8 +
.../opac-tmpl/bootstrap/en/includes/masthead.inc | 5 +-
.../opac-tmpl/bootstrap/en/modules/opac-auth.tt | 4 +
.../opac-tmpl/bootstrap/en/modules/opac-main.tt | 3 +
.../bootstrap/en/modules/opac-password-recovery.tt | 132 +++++++++++++
.../en/modules/opac-send-password-recovery.tt | 19 ++
koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt | 3 +
koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt | 6 +-
.../prog/en/modules/opac-password-recovery.tt | 130 +++++++++++++
.../prog/en/modules/opac-send-password-recovery.tt | 17 ++
opac/opac-main.pl | 1 +
opac/opac-password-recovery.pl | 203 ++++++++++++++++++++
17 files changed, 649 insertions(+), 3 deletions(-)
create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt
create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-send-password-recovery.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-password-recovery.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-send-password-recovery.tt
create mode 100755 opac/opac-password-recovery.pl
diff --git a/C4/Auth.pm b/C4/Auth.pm
index 44edf67..7b1194e 100644
--- a/C4/Auth.pm
+++ b/C4/Auth.pm
@@ -1068,6 +1068,8 @@ sub checkauth {
PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
persona => C4::Context->preference("Persona"),
opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'},
+ OpacResetPassword => C4::Context->preference("OpacResetPassword"),
+ OpacPasswordChange => C4::Context->preference("OpacPasswordChange"),
);
$template->param( OpacPublic => C4::Context->preference("OpacPublic"));
diff --git a/C4/Members.pm b/C4/Members.pm
index 29eda68..41c7504 100644
--- a/C4/Members.pm
+++ b/C4/Members.pm
@@ -42,6 +42,12 @@ use Koha::Borrower::Debarments qw(IsDebarred);
use Text::Unaccent qw( unac_string );
use Koha::AuthUtils qw(hash_password);
+## Password recovery
+use CGI;
+use Encode qw(encode decode);
+use MIME::QuotedPrint qw(encode_qp);
+use Mail::Sendmail;
+
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
BEGIN {
@@ -112,7 +118,12 @@ BEGIN {
push @EXPORT, qw(
&ModMember
&changepassword
- &ModPrivacy
+ &ModPrivacy
+ );
+
+ # Password recovery
+ push @EXPORT, qw(
+ &SendPasswordRecoveryEmail
);
#Delete data
@@ -2241,6 +2252,85 @@ sub ModPrivacy {
privacy => $privacy );
}
+=head2 SendPasswordRecoveryEmail
+
+ SendPasswordRecoveryEmail( $borrowernumber, $email, $query );
+
+Sends email to user using template file opac-send-password-recovery.tt.
+The mail contains a link to the script for password reset, with a unique key stored
+in the database for validation
+
+$query is the CGI object, required to determine if http or https must be used
+
+=cut
+
+sub SendPasswordRecoveryEmail {
+ my $borrowernumber = shift;
+ my $email = shift;
+ my $query = shift;
+ my $dbh = C4::Context->dbh;
+ my $username = GetMemberDetails($borrowernumber)->{userid};
+
+ #generate UUID
+ my @chars = ("A".."Z", "a".."z", "0".."9");
+ my $uuid_str;
+ $uuid_str .= $chars[rand @chars] for 1..32;
+
+ #insert into database
+ my $expirydate = DateTime->now(time_zone => C4::Context->tz())->add( days => 2 );
+ my $sth = $dbh->prepare( 'INSERT INTO borrower_password_recovery VALUES (?, ?, ?)');
+ $sth->execute($borrowernumber, $uuid_str, $expirydate->ymd());
+
+ my $userEmail = ( $email ) ? $email : GetFirstValidEmailAddress($borrowernumber);
+ #define to/from emails
+ my $kohaEmail = C4::Context->preference( 'KohaAdminEmailAddress' );
+
+ #create link
+ my $protocol = $query->https() ? "https://" : "http://";
+ my $uuidLink = $protocol . C4::Context->preference( 'OPACBaseURL' ) . "/cgi-bin/koha/opac-password-recovery.pl?uniqueKey=$uuid_str";
+
+ #build email content
+ my ( $template2, $borrower_number, $cookie ) = C4::Auth::get_template_and_user(
+ {
+ template_name => "opac-send-password-recovery.tmpl",
+ query => $query,
+ type => "opac",
+ authnotrequired => 1,
+ }
+ );
+ $template2->param(
+ uuidLink => $uuidLink,
+ username => $username,
+ );
+
+ # Getting template result and
+ my $template_res = $template2->output();
+
+ #Mail attributes
+ my %mail = (
+ To => $userEmail,
+ From => $kohaEmail,
+ 'Content-Type' => 'text/html; charset=utf-8'
+ );
+
+ #getting mail properties
+ if ( $template_res =~ /(.*)/s ) { $mail{'subject'} = decode( 'utf-8', $1 ); }
+ if ( $template_res =~ /\n(.*)\n/s ) { $mail{'body'} = decode( 'utf-8', $1 ); }
+ #send mail
+ if ( sendmail %mail )
+ {
+ # if it works....
+ return 1;
+ }
+ else
+ {
+ # if it doesnt work....
+ warn "Error sending mail: $Mail::Sendmail::error \n";
+ return 0;
+ }
+}
+
+
=head2 AddMessage
AddMessage( $borrowernumber, $message_type, $message, $branchcode );
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 136104f..881db92 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -3393,6 +3393,17 @@ CREATE TABLE IF NOT EXISTS marc_modification_template_actions (
CONSTRAINT `mmta_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `marc_modification_templates` (`template_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+-- Table structure for table 'borrower_password_recovery'
+-- this stores the unique ID sent by email to the patron, for future validation
+--
+
+CREATE TABLE IF NOT EXISTS borrower_password_recovery (
+ borrowernumber int(11) NOT NULL,
+ uuid varchar(128) NOT NULL,
+ valid_until timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ KEY borrowernumber (borrowernumber)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql
index 1668d37..1ac0ad4 100644
--- a/installer/data/mysql/sysprefs.sql
+++ b/installer/data/mysql/sysprefs.sql
@@ -256,6 +256,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('opacreadinghistory','1','','If ON, enables display of Patron Circulation History in OPAC','YesNo'),
('OpacRenewalAllowed','0',NULL,'If ON, users can renew their issues directly from their OPAC account','YesNo'),
('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|null','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'),
+('OpacResetPassword','1','','Shows the \'Forgot your password?\' link in the OPAC','YesNo'),
('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'),
('OPACSearchForTitleIn','
','70|10','Enter the HTML that will appear in the \'Search for this title in\' box on the detail page in the OPAC. Enter {TITLE}, {AUTHOR}, or {ISBN} in place of their respective variables in the URL. Leave blank to disable \'More Searches\' menu.','Textarea'),
('OpacSeparateHoldings','0',NULL,'Separate current branch holdings from other holdings (OPAC)','YesNo'),
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index f98daa7..5c6fdad 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -7945,6 +7945,21 @@ if (CheckVersion($DBversion)) {
SetVersion($DBversion);
}
+$DBversion = "3.15.00.XXX";
+if ( CheckVersion($DBversion) ) {
+ $dbh->do("INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('OpacResetPassword','1','','Shows the ''Forgot your password?'' link in the OPAC','YesNo')");
+ $dbh->do(q{
+ CREATE TABLE IF NOT EXISTS borrower_password_recovery (
+ borrowernumber int(11) NOT NULL,
+ uuid varchar(128) NOT NULL,
+ valid_until timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ KEY borrowernumber (borrowernumber)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+ });
+ print "Upgrade to $DBversion done (Bug 8753: Add forgot password link to OPAC)\n";
+ SetVersion ($DBversion);
+}
+
=head1 FUNCTIONS
=head2 TableExists($table)
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
index 1364ff1..66eeb56 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
@@ -557,6 +557,14 @@ OPAC:
track: "Track"
no: "Don't track"
- links that patrons click on
+ -
+ - "The user "
+ - pref: OpacResetPassword
+ default: 1
+ choices:
+ yes: "can reset"
+ no: "can not reset"
+ - " their password on OPAC."
Shelf Browser:
-
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
index 1edc244..a786069 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
@@ -278,10 +278,13 @@
[% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]
[% END # /casAuthentication %]
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt
new file mode 100644
index 0000000..8dd44aa
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt
@@ -0,0 +1,132 @@
+[% USE Koha %]
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF (LibraryNameTitle) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog ›
+[% INCLUDE 'doc-head-close.inc' %]
+[% BLOCK cssinclude %][% END %]
+[% BLOCK jsinclude %]
+
+[% END %]
+
+
+
+
+
+[% INCLUDE 'masthead.inc' %]
+
+
+
+
+[% IF (!Koha.Preference('OpacResetPassword')) %]
+
You can't reset your password.
+[% ELSIF (password_recovery) %]
+ [% IF (hasError) %]
+
+ [% IF (sendmailError) %]
+ An error has occured while sending you the password recovery link.
+ Please try again later.
+ [% ELSIF (errNoEmailFound) %]
+ No account was found with the email address "[% email %]"
+ Check if you typed it correctly.
+ [% ELSIF (errTooManyEmailFound) %]
+ More than one account has been found for the email address: "[% email %]"
+ Try to use an alternative email if you have one.
+ [% ELSIF (errAlreadyStartRecovery) %]
+ The process of password recovery has already started for this account ("[% email %]")
+ Check your emails; you should receive the link to reset your password.
+ If you did not receive it, click here to get a new password recovery link
+ [% END %]
+
Please contact the staff if you need further assistance.
+
+ [% END %]
+
+ We could not authenticate you as the account owner.
+ Be sure to use the link you received in your email.
+
+ [% ELSE %]
+ [% IF (hasError) %]
+
+ [% IF (errPassNotMatch) %]
+ The passwords entered does not match.
+ Please try again.
+ [% ELSIF (errPassTooShort) %]
+ The password is too short.
+ The password must contain at least [% minPassLength %] characters.
+ [% END %]
+
+ [% END %]
+
+
+
+ [% END %]
+[% ELSIF (mail_sent) %]
+
A mail has been sent to "[% email %]".
+ It contains a link to create a new password.
+ This link will be valid for 2 days starting now.
The password has been changed for user "[% username %]".
+ You can now login using this form.
+[% END %]
+
+
+
+
+
+
+ [% INCLUDE 'usermenu.inc' %]
+
+
+
+[% INCLUDE 'opac-bottom.inc' %]
+
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-send-password-recovery.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-send-password-recovery.tt
new file mode 100644
index 0000000..85c6b7e
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-send-password-recovery.tt
@@ -0,0 +1,19 @@
+[% USE Koha %]
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF (LibraryNameTitle) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog ›
+[% INCLUDE 'doc-head-close.inc' %]
+[% BLOCK cssinclude %][% END %]
+
+[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] - Password recovery
+
+
+
+
This email has been sent in response to your password recovery request for the account [% username %].
+
+You can now create your new password using the following link:
+ [% uuidLink %]
+
+
This link will be valid for 2 days from this email's reception, then you must reapply if you do not change your password.
+
Thank you.
+
+
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt
index 7b8b8f9..9580668 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt
@@ -85,6 +85,9 @@ please choose against which one you would like to authenticate:
+[% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %]
+
If you don't have a password yet, stop by the circulation desk the next time you're in the library. We'll happily set one up for you.
Don't have a library card?
If you don't have a library card, stop by your local library to sign up[% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %] or register here[% END %].
[% END %]
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-password-recovery.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-password-recovery.tt
new file mode 100644
index 0000000..1c650c6
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-password-recovery.tt
@@ -0,0 +1,130 @@
+[% USE Koha %]
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF (LibraryNameTitle) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog ›
+[% INCLUDE 'doc-head-close.inc' %]
+
+
+
+
+
+
+
+[% INCLUDE 'masthead.inc' %]
+
+
+
+
+[% IF (!Koha.Preference('OpacResetPassword')) %]
+
You can't reset your password.
+[% ELSIF (password_recovery) %]
+ [% IF (hasError) %]
+
+ [% IF (sendmailError) %]
+ An error has occured while sending you the password recovery link.
+ Please try again later.
+ [% ELSIF (errNoEmailFound) %]
+ No account was found with the email address "[% email %]"
+ Check if you typed it correctly.
+ [% ELSIF (errTooManyEmailFound) %]
+ More than one account has been found for the email address: "[% email %]"
+ Try to use your alternative email if you have one.
+ [% ELSIF (errAlreadyStartRecovery) %]
+ The process of password recovery has already started for this account ("[% email %]")
+ Check your emails; you should receive the link to reset your password.
+ If you didn't receive it, click here to get a new password recovery link
+ [% END %]
+
Please contact the staff if you need further assistance.
+
+ [% END %]
+
+ We could not authenticate you as the account owner.
+ Be sure to use the link you received in your email.
+
+ [% ELSE %]
+ [% IF (hasError) %]
+
+ [% IF (errPassNotMatch) %]
+ The passwords entered does not match.
+ Please try again.
+ [% ELSIF (errPassTooShort) %]
+ The password is too short.
+ The password must contain at least [% minPassLength %] characters.
+ [% END %]
+
+ [% END %]
+
+
+
+ [% END %]
+[% ELSIF (mail_sent) %]
+
A mail has been sent to "[% email %]".
+ It contains a link to create a new password.
+ This link will be valid for 2 days starting now.