View | Details | Raw Unified | Return to bug 8753
Collapse All | Expand All

(-)a/C4/Auth.pm (+2 lines)
Lines 1043-1048 sub checkauth { Link Here
1043
        PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
1043
        PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
1044
        persona            => C4::Context->preference("Persona"),
1044
        persona            => C4::Context->preference("Persona"),
1045
        opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'},
1045
        opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'},
1046
        OpacResetPassword => C4::Context->preference("OpacResetPassword"),
1047
        OpacPasswordChange => C4::Context->preference("OpacPasswordChange"),
1046
    );
1048
    );
1047
1049
1048
    $template->param( OpacPublic => C4::Context->preference("OpacPublic"));
1050
    $template->param( OpacPublic => C4::Context->preference("OpacPublic"));
(-)a/C4/Members.pm (-1 / +81 lines)
Lines 41-46 use Koha::DateUtils; Link Here
41
use Text::Unaccent qw( unac_string );
41
use Text::Unaccent qw( unac_string );
42
use Koha::AuthUtils qw(hash_password);
42
use Koha::AuthUtils qw(hash_password);
43
43
44
## Password recovery
45
use CGI;
46
use Encode qw(encode decode);
47
use MIME::QuotedPrint qw(encode_qp);
48
use Mail::Sendmail;
49
44
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
50
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
45
51
46
BEGIN {
52
BEGIN {
Lines 109-115 BEGIN { Link Here
109
    push @EXPORT, qw(
115
    push @EXPORT, qw(
110
        &ModMember
116
        &ModMember
111
        &changepassword
117
        &changepassword
112
         &ModPrivacy
118
        &ModPrivacy
119
    );
120
121
    # Password recovery
122
    push @EXPORT, qw(
123
        &SendPasswordRecoveryEmail
113
    );
124
    );
114
125
115
    #Delete data
126
    #Delete data
Lines 2264-2269 sub ModPrivacy { Link Here
2264
                      privacy        => $privacy );
2275
                      privacy        => $privacy );
2265
}
2276
}
2266
2277
2278
2279
sub SendPasswordRecoveryEmail {
2280
    my $borrowernumber = shift;
2281
    my $email = shift;
2282
    my $dbh = C4::Context->dbh;
2283
    #use constant EMAIL_ENCODE = 'iso-8859-1';
2284
    my $emailEncode = 'iso-8859-1';
2285
    my $username = GetMemberDetails($borrowernumber)->{userid};
2286
2287
    #generate UUID
2288
    my @chars = ("A".."Z", "a".."z", "0".."9");
2289
    my $uuid_str;
2290
    $uuid_str .= $chars[rand @chars] for 1..32;
2291
2292
    #insert into database
2293
    my $sth = $dbh->prepare( 'INSERT INTO borrower_password_recovery VALUES (? ,? , ADDDATE(NOW(), INTERVAL 2 DAY) )' );
2294
    $sth->execute($borrowernumber, $uuid_str);
2295
2296
    my $userEmail = ( $email ) ? $email : GetFirstValidEmailAddress($borrowernumber);
2297
    #define to/from emails
2298
    my $kohaEmail = C4::Context->preference( 'KohaAdminEmailAddress' );
2299
2300
    #create link
2301
    my $uuidLink = "http://" . C4::Context->preference( 'OPACBaseURL' ) . "/cgi-bin/koha/opac-password-recovery.pl?uniqueKey=$uuid_str";
2302
    #warn $uuidLink;
2303
2304
    #build email content
2305
    my $query = new CGI;
2306
    my ( $template2, $borrower_number, $cookie ) = C4::Auth::get_template_and_user(
2307
    {
2308
        template_name   => "opac-send-password-recovery.tmpl",
2309
        query           => $query,
2310
        type            => "opac",
2311
        authnotrequired => 1,
2312
    }
2313
    );
2314
    $template2->param(
2315
        uuidLink         => $uuidLink,
2316
        username         => $username,
2317
    );
2318
2319
    # Getting template result and
2320
    my $template_res = $template2->output();
2321
2322
    #Mail attributes
2323
    my %mail = (
2324
        To  => $userEmail,
2325
        From  => $kohaEmail,
2326
        'Content-Type' => 'text/html; charset="' . $emailEncode . '"',
2327
    );
2328
2329
    #getting mail properties
2330
    if ( $template_res =~ /<SUBJECT>(.*)<END_SUBJECT>/s ) { $mail{'subject'} = decode( 'utf-8', $1 ); }
2331
    if ( $template_res =~ /<MESSAGE>\n(.*)\n<END_MESSAGE>/s ) { $mail{'body'} = decode( 'utf-8', $1 ); }
2332
    #send mail
2333
    if ( sendmail %mail )
2334
    {
2335
        # if it works....
2336
        return 1;
2337
    }
2338
    else
2339
    {
2340
        # if it doesnt work....
2341
        warn "Error sending mail: $Mail::Sendmail::error \n";
2342
        return 0;
2343
    }
2344
}
2345
2346
2267
=head2 AddMessage
2347
=head2 AddMessage
2268
2348
2269
  AddMessage( $borrowernumber, $message_type, $message, $branchcode );
2349
  AddMessage( $borrowernumber, $message_type, $message, $branchcode );
(-)a/installer/data/mysql/kohastructure.sql (+11 lines)
Lines 3275-3280 ALTER TABLE `patron_list_patrons` Link Here
3275
  ADD CONSTRAINT patron_list_patrons_ibfk_1 FOREIGN KEY (patron_list_id) REFERENCES patron_lists (patron_list_id) ON DELETE CASCADE ON UPDATE CASCADE,
3275
  ADD CONSTRAINT patron_list_patrons_ibfk_1 FOREIGN KEY (patron_list_id) REFERENCES patron_lists (patron_list_id) ON DELETE CASCADE ON UPDATE CASCADE,
3276
  ADD CONSTRAINT patron_list_patrons_ibfk_2 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
3276
  ADD CONSTRAINT patron_list_patrons_ibfk_2 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
3277
3277
3278
--
3279
-- Table structure for table 'borrower_password_recovery'
3280
-- this stores the unique ID sent by email to the patron, for future validation
3281
--
3282
3283
CREATE TABLE IF NOT EXISTS `borrower_password_recovery` (
3284
  `borrowernumber` int(11) NOT NULL,
3285
  `uuid` varchar(128) NOT NULL,
3286
  `valid_until` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
3287
  KEY `borrowernumber` (`borrowernumber`)
3288
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
3278
3289
3279
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3290
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3280
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3291
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
(-)a/installer/data/mysql/sysprefs.sql (-1 / +2 lines)
Lines 253-258 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
253
('opacreadinghistory','1','','If ON, enables display of Patron Circulation History in OPAC','YesNo'),
253
('opacreadinghistory','1','','If ON, enables display of Patron Circulation History in OPAC','YesNo'),
254
('OpacRenewalAllowed','0',NULL,'If ON, users can renew their issues directly from their OPAC account','YesNo'),
254
('OpacRenewalAllowed','0',NULL,'If ON, users can renew their issues directly from their OPAC account','YesNo'),
255
('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|null','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'),
255
('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|null','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'),
256
('OpacResetPassword','1','','Shows the \'Forgot your password?\' link in the OPAC','YesNo'),
256
('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'),
257
('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'),
257
('OPACSearchForTitleIn','<li><a  href=\"http://worldcat.org/search?q={TITLE}\" target=\"_blank\">Other Libraries (WorldCat)</a></li>\n<li><a href=\"http://www.scholar.google.com/scholar?q={TITLE}\" target=\"_blank\">Other Databases (Google Scholar)</a></li>\n<li><a href=\"http://www.bookfinder.com/search/?author={AUTHOR}&amp;title={TITLE}&amp;st=xl&amp;ac=qr\" target=\"_blank\">Online Stores (Bookfinder.com)</a></li>\n<li><a href=\"http://openlibrary.org/search/?author=({AUTHOR})&title=({TITLE})\" target=\"_blank\">Open Library (openlibrary.org)</a></li>','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'),
258
('OPACSearchForTitleIn','<li><a  href=\"http://worldcat.org/search?q={TITLE}\" target=\"_blank\">Other Libraries (WorldCat)</a></li>\n<li><a href=\"http://www.scholar.google.com/scholar?q={TITLE}\" target=\"_blank\">Other Databases (Google Scholar)</a></li>\n<li><a href=\"http://www.bookfinder.com/search/?author={AUTHOR}&amp;title={TITLE}&amp;st=xl&amp;ac=qr\" target=\"_blank\">Online Stores (Bookfinder.com)</a></li>\n<li><a href=\"http://openlibrary.org/search/?author=({AUTHOR})&title=({TITLE})\" target=\"_blank\">Open Library (openlibrary.org)</a></li>','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'),
258
('OpacSeparateHoldings','0',NULL,'Separate current branch holdings from other holdings (OPAC)','YesNo'),
259
('OpacSeparateHoldings','0',NULL,'Separate current branch holdings from other holdings (OPAC)','YesNo'),
Lines 419-423 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
419
('XSLTResultsDisplay','default','','Enable XSL stylesheet control over results page display on intranet','Free'),
420
('XSLTResultsDisplay','default','','Enable XSL stylesheet control over results page display on intranet','Free'),
420
('yuipath','local','local|http://yui.yahooapis.com/2.5.1/build','Insert the path to YUI libraries, choose local if you use koha offline','Choice'),
421
('yuipath','local','local|http://yui.yahooapis.com/2.5.1/build','Insert the path to YUI libraries, choose local if you use koha offline','Choice'),
421
('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'),
422
('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'),
422
('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo')
423
('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo'),
423
;
424
;
(-)a/installer/data/mysql/updatedatabase.pl (+8 lines)
Lines 7306-7311 if ( CheckVersion($DBversion) ) { Link Here
7306
    SetVersion($DBversion);
7306
    SetVersion($DBversion);
7307
}
7307
}
7308
7308
7309
$DBversion = "3.13.00.XXX";
7310
if ( CheckVersion($DBversion) ) {
7311
    $dbh->do("INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
7312
VALUES('OpacResetPassword','1','Shows the ''Forgot your password?'' link in the OPAC','','YesNo');");
7313
    print "Upgrade to $DBversion done (Bug 8753:  Add forgot password link to OPAC)\n";
7314
    SetVersion($DBversion);
7315
}
7316
7309
=head1 FUNCTIONS
7317
=head1 FUNCTIONS
7310
7318
7311
=head2 TableExists($table)
7319
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (+7 lines)
Lines 551-556 OPAC: Link Here
551
                  track: "Track"
551
                  track: "Track"
552
                  no: "Don't track"
552
                  no: "Don't track"
553
            - links that patrons click on
553
            - links that patrons click on
554
        -
555
            - pref: OpacResetPassword
556
              default: 1
557
              choices:
558
                  yes: "On"
559
                  no: "Off"
560
            - ". If On, the user can reset his password on OPAC."
554
561
555
    Shelf Browser:
562
    Shelf Browser:
556
        -
563
        -
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt (+3 lines)
Lines 85-90 please choose against which one you would like to authenticate: </p> Link Here
85
</ol></fieldset>
85
</ol></fieldset>
86
86
87
<input type="submit" value="Log In" class="submit" />
87
<input type="submit" value="Log In" class="submit" />
88
[% IF OpacPasswordChange && OpacResetPassword %]
89
	<p><a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a></p>
90
[% END %]
88
<div id="nologininstructions">
91
<div id="nologininstructions">
89
    <h5>Don't have a password yet?</h5><p> 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.</p>
92
    <h5>Don't have a password yet?</h5><p> 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.</p>
90
    <h5>Don't have a library card?</h5><p> If you don't have a library card, stop by your local library to sign up[% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<span id="registrationinstructions"> or  <a href="/cgi-bin/koha/opac-memberentry.pl">register here</a></span>[% END %].  </p>
93
    <h5>Don't have a library card?</h5><p> If you don't have a library card, stop by your local library to sign up[% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<span id="registrationinstructions"> or  <a href="/cgi-bin/koha/opac-memberentry.pl">register here</a></span>[% END %].  </p>
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt (-1 / +5 lines)
Lines 60-66 Link Here
60
60
61
        [% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<div id="patronregistration">Don't have an account? <a href="/cgi-bin/koha/opac-memberentry.pl">Register here.</a></div>[% END %]
61
        [% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<div id="patronregistration">Don't have an account? <a href="/cgi-bin/koha/opac-memberentry.pl">Register here.</a></div>[% END %]
62
62
63
	 </fieldset></fieldset>
63
	 </fieldset>
64
	 [% IF OpacPasswordChange && OpacResetPassword %]
65
             <p><a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a></p>
66
     [% END %]
67
	 </fieldset>
64
	</form>
68
	</form>
65
	</div>
69
	</div>
66
    [% END %]
70
    [% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-password-recovery.tt (+129 lines)
Line 0 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
[% IF (LibraryNameTitle) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog &rsaquo;
3
[% INCLUDE 'doc-head-close.inc' %]
4
5
<script type="text/javascript" language="javascript">
6
   $(function() {
7
        $("#CheckAll").click(function(){
8
                $("[name=deleteRequest]").attr('checked', true);
9
                return false;
10
            });
11
12
        $("#CheckNone").click(function(){
13
                $("[name=deleteRequest]").attr('checked', false);
14
                return false;
15
            });
16
17
        $("select#type").change(function() {
18
            $("fieldset#serial, fieldset#book, fieldset#chapter").hide()
19
            $("fieldset#" + $(this).val() ).show();
20
        });
21
   });
22
</script>
23
</head>
24
<body>
25
26
<div id="doc3" class="yui-t1">
27
    <div id="bd">
28
[% INCLUDE 'masthead.inc' %]
29
        <div id="yui-main">
30
            <div class="yui-b">
31
                <div class="yui-g">
32
                    <div class="illrequest">
33
[% IF (!OpacResetPassword) %]
34
    <div class="dialog alert">You can't reset your password.</div>
35
[% ELSIF (password_recovery) %]
36
    [% IF (hasError) %]
37
        <span class="TxtErreur">
38
        [% IF (sendmailError) %]
39
            An error has occured while sending you the password recovery link.
40
            <br/>Please try again later.
41
        [% ELSIF (errNoEmailFound) %]
42
            No account was found with the email address "<strong>[% email %]</strong>"
43
            <br/>Check if you typed it correctly.
44
        [% ELSIF (errTooManyEmailFound) %]
45
            More than one account has been found for the email address: "<strong>[% email %]</strong>"
46
            <br/>Try yo use your alternative email if you have another.
47
        [% ELSIF (errAlreadyStartRecovery) %]
48
            The process of password recovery has already started for this account ("<strong>[% email %]</strong>")
49
            <br/>Check your emails; you should recieve the link to reset your password.
50
            <br/>If you didn't recieve it, <a href="/cgi-bin/koha/opac-password-recovery.pl?resendEmail=true&email=[% email %]">click here to get a new password recovery link</a>
51
        [% END %]
52
        <br/><br/>Please contact the staff if you need further assistance.
53
        </span>
54
    [% END %]
55
        <div id="password-recovery" class="container">
56
            <form action="/cgi-bin/koha/opac-password-recovery.pl" method="post">
57
                <input type="hidden" name="koha_login_context" value="opac" />
58
                <fieldset class="brief">
59
                    <legend>Password recovery form:</legend>
60
                        <p>To reset your password, enter your email address.
61
                        <br/>A link to reset your password will be sent at this address.</p>
62
                        <ol>
63
                            <li><label for="email">Email:</label><input type="text" id="email" size="40" name="email" value="[% email %]" /></li>
64
                        </ol>
65
                    <fieldset class="action">
66
                 <input type="submit" value="Submit" class="submit" name="sendEmail" />
67
                    </fieldset>
68
                 </fieldset>
69
            </form>
70
        </div>
71
72
[% ELSIF (new_password) %]
73
    [% IF (errLinkNotValid) %]
74
        <span class="TxtErreur"><h6>
75
        We could not authentify you as the account owner.
76
        <br/>Be sure to use the link you recieved in your email.
77
        </h6></span>
78
    [% ELSE %]
79
        [% IF (hasError) %]
80
            <span class="TxtErreur">
81
            [% IF (errPassNotMatch) %]
82
                The passwords entered does not match.
83
                <br/>Please try again.
84
            [% ELSIF (errPassTooShort) %]
85
                The password is too short.
86
                <br/>The password must contain at least [% minPassLength %] characters.
87
            [% END %]
88
            </span>
89
        [% END %]
90
            <div id="password-recovery" class="container">
91
                <form action="/cgi-bin/koha/opac-password-recovery.pl" method="post">
92
                    <input type="hidden" name="koha_login_context" value="opac" />
93
                    <fieldset class="brief">
94
                        <legend>Password recovery form:</legend>
95
                            <p class="light">The password must contain at least [% minPassLength %] characters.</p>
96
                            <ol>
97
                                <li><label for="password">New password:</label><input type="password" id="password" size="40" name="password" /></li>
98
                                <li><label for="repeatPassword">Confirm new password:</label><input type="password" id="repeatPassword" size="40" name="repeatPassword" /></li>
99
                            </ol>
100
                        <fieldset class="action">
101
                        <input type="hidden" name="username" value="[% username %]" />
102
                        <input type="hidden" name="uniqueKey" value="[% uniqueKey %]" />
103
                        <input type="submit" value="Submit" class="submit" name="passwordReset" />
104
                        </fieldset>
105
                     </fieldset>
106
                </form>
107
            </div>
108
    [% END %]
109
[% ELSIF (mail_sent) %]
110
    <p>A mail has been sent to "[% email %]".
111
    <br/>It contains a link to create a new password.
112
    <br/>This link will be valid for 2 days from now.</p>
113
    <br/><a href="/cgi-bin/koha/opac-main.pl"">Click here to return to the main page.</a>
114
[% ELSIF (password_reset_done) %]
115
    <p>The password has been changed for the user "[% username %]".
116
    <br/>You can now login using <a href="/cgi-bin/koha/opac-user.pl">this form</a>.</p>
117
[% END %]
118
                    </div>
119
                </div>
120
            </div>
121
        </div>
122
        <div class="yui-b">
123
            <div class="container">
124
                [% INCLUDE 'usermenu.inc' %]
125
            </div>
126
        </div>
127
    </div>
128
[% INCLUDE 'opac-bottom.inc' %]
129
</div>
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-send-password-recovery.tt (+13 lines)
Line 0 Link Here
1
<SUBJECT>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] - Password recovery<END_SUBJECT>
2
3
<MESSAGE>
4
<html>
5
<p>This email has been sent in response to your password recovery request for the account <strong>[% username %]</strong>.</p>
6
<p>
7
You can now create your new password using the following link:
8
<br/><a href="[% uuidLink %]">[% uuidLink %]</a>
9
</p>
10
<p>This link will be valid for 2 days from this email's reception, then you must reapply if you do not change your password.</p>
11
<p>Thank you.</p>
12
</html>
13
<END_MESSAGE>
(-)a/opac/opac-main.pl (+1 lines)
Lines 58-63 $template->param( Link Here
58
    koha_news_count     => $koha_news_count,
58
    koha_news_count     => $koha_news_count,
59
    display_daily_quote => C4::Context->preference('QuoteOfTheDay'),
59
    display_daily_quote => C4::Context->preference('QuoteOfTheDay'),
60
    daily_quote         => $quote,
60
    daily_quote         => $quote,
61
    OpacResetPassword   => C4::Context->preference('OpacResetPassword'),
61
);
62
);
62
63
63
# If GoogleIndicTransliteration system preference is On Set paramter to load Google's javascript in OPAC search screens
64
# If GoogleIndicTransliteration system preference is On Set paramter to load Google's javascript in OPAC search screens
(-)a/opac/opac-password-recovery.pl (-1 / +223 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
use strict;
4
5
use CGI;
6
use Mail::Sendmail;
7
use Digest::MD5 qw(md5_base64);
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
16
my $query = new CGI;
17
18
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
19
    {
20
        template_name   => "opac-password-recovery.tmpl",
21
        query           => $query,
22
        type            => "opac",
23
        authnotrequired => 1,
24
        debug           => 1,
25
    }
26
);
27
28
my $email           = $query->param('email');
29
my $password        = $query->param('password');
30
my $repeatPassword  = $query->param('repeatPassword');
31
my $minPassLength   = C4::Context->preference( 'minPasswordLength' );
32
my $id              = $query->param('id');
33
my $uniqueKey       = $query->param('uniqueKey');
34
my $username        = $query->param('username');
35
my $borrower_number;
36
37
#errors
38
my $hasError;
39
40
#email form error
41
my $errNoEmailFound;
42
my $errAlreadyStartRecovery;
43
44
#new password form error
45
my $errLinkNotValid;
46
my $errPassNotMatch;
47
my $errPassTooShort;
48
49
my $dbh = C4::Context->dbh;
50
51
$template->param( OpacResetPassword => C4::Context->preference("OpacResetPassword") );
52
53
if ( $query->param('sendEmail') || $query->param('resendEmail') )
54
{
55
#send mail + confirmation
56
57
    #try with the main email
58
    my $borrower_number;
59
    my $accountActivated;
60
    my %borrower_infos  = GetMember(email => $email);
61
    if ( %borrower_infos )
62
    {
63
        $borrower_number = GetMember(email => $email)->{'borrowernumber'};
64
        $username        = GetMemberDetails( $borrower_number )->{'userid'};
65
        $accountActivated = ( GetMemberDetails( $borrower_number )->{'categorycode'} ne 'UNAUTHORIZ' ) ? 1 : 0;
66
    }
67
    else
68
    {
69
        #try with the secondary email
70
        %borrower_infos  = GetMember(emailpro => $email);
71
        if ( %borrower_infos )
72
        {
73
            $borrower_number = GetMember(emailpro => $email)->{'borrowernumber'};
74
            $username        = GetMemberDetails( $borrower_number )->{'userid'};
75
            $accountActivated = ( GetMemberDetails( $borrower_number )->{'categorycode'} ne 'UNAUTHORIZ' ) ? 1 : 0;
76
        }
77
        else
78
        {
79
            #try when the other contact email
80
            %borrower_infos  = GetMember(B_email => $email);
81
            if ( %borrower_infos )
82
            {
83
                $borrower_number = GetMember(B_email => $email)->{'borrowernumber'};
84
                $username        = GetMemberDetails( $borrower_number )->{'userid'};
85
                $accountActivated = ( GetMemberDetails( $borrower_number )->{'categorycode'} ne 'UNAUTHORIZ' ) ? 1 : 0;
86
            }
87
        }
88
    }
89
90
    if ( !$email || !$username || !$borrower_number || !$accountActivated )
91
    {
92
        $hasError = 1;
93
        $errNoEmailFound = 1;
94
    }
95
    elsif ( !$query->param('resendEmail') )
96
    {
97
        my $sth = $dbh->prepare( "SELECT borrowernumber FROM borrower_password_recovery WHERE NOW() < valid_until AND borrowernumber = ?" );
98
        $sth->execute($borrower_number);
99
        if ( my $already = $sth->fetchrow )
100
        {
101
            $hasError = 1;
102
            $errAlreadyStartRecovery = 1;
103
        }
104
    }
105
106
    if ( $hasError )
107
    {
108
        $template->param(             hasError => 1,
109
                               errNoEmailFound => $errNoEmailFound,
110
                       errAlreadyStartRecovery => $errAlreadyStartRecovery,
111
                             password_recovery => 1,
112
                                         email => HTML::Entities::encode($email),
113
        );
114
    }
115
    else
116
    {
117
        #generate uuid and send recovery email
118
        if ( SendPasswordRecoveryEmail($borrower_number, $email) )
119
        {
120
			# if it works....
121
            $template->param(   mail_sent => 1,
122
                                    email => $email
123
            );
124
        }
125
        else
126
        {
127
			# if it doesnt work....
128
			$template->param( password_recovery => 1,
129
			                      sendmailError => 1
130
			);
131
        }
132
    }
133
}
134
elsif ( $query->param('passwordReset') )
135
{
136
#new password form
137
    #check if the link is still valid
138
    my $sth = $dbh->prepare( "SELECT borrower_password_recovery.borrowernumber, userid
139
                              FROM borrower_password_recovery, borrowers
140
                              WHERE borrowers.borrowernumber = borrower_password_recovery.borrowernumber
141
                              AND NOW() < valid_until
142
                              AND uuid = ?" );
143
    $sth->execute( $uniqueKey );
144
    ( $borrower_number , $username) = $sth->fetchrow;
145
146
    #validate password length & match
147
    if ( ( $borrower_number ) && ( $password eq $repeatPassword ) && ( length( $password ) >= $minPassLength ) )
148
    {
149
        #apply changes
150
        changepassword( $username, $borrower_number, md5_base64($password) );
151
        #this line needed to fix a log bug in "Log.pm:75"
152
        #
153
        #       if ( !$usernumber ) {  $usernumber=0; }
154
        #
155
156
        #remove entry
157
        my $sth = $dbh->prepare( "DELETE FROM borrower_password_recovery
158
                                  WHERE uuid = ?
159
                                  ORDER BY valid_until DESC LIMIT 1" );
160
        $sth->execute( $uniqueKey);
161
162
        $template->param( password_reset_done => 1,
163
                                     username => $username
164
        );
165
    }
166
    else
167
    {
168
        #errors
169
        if ( !$borrower_number )
170
        {
171
            #parameters not valid
172
            $errLinkNotValid = 1;
173
        }
174
        elsif ( $password ne $repeatPassword )
175
        {
176
            #passwords does not match
177
            $errPassNotMatch = 1;
178
        }
179
        elsif ( length( $password ) < $minPassLength )
180
        {
181
            #password too short
182
            $errPassTooShort = 1;
183
        }
184
        $template->param( new_password => 1,
185
                         minPassLength => $minPassLength,
186
                                 email => $email,
187
                             uniqueKey => $uniqueKey,
188
                       errLinkNotValid => $errLinkNotValid,
189
                       errPassNotMatch => $errPassNotMatch,
190
                       errPassTooShort => $errPassTooShort,
191
                              hasError => 1 );
192
    }
193
}
194
elsif ( $uniqueKey )
195
{
196
#reset password form
197
    #check if the link is valid
198
    my $sth = $dbh->prepare( "SELECT borrower_password_recovery.borrowernumber, userid
199
                              FROM borrower_password_recovery, borrowers
200
                              WHERE borrowers.borrowernumber = borrower_password_recovery.borrowernumber
201
                              AND NOW() < valid_until
202
                              AND uuid = ?" );
203
    $sth->execute( $uniqueKey );
204
    ( $borrower_number, $username ) = $sth->fetchrow;
205
    if( !$borrower_number )
206
    {
207
        $errLinkNotValid = 1;
208
    }
209
    $template->param( new_password => 1,
210
                     minPassLength => $minPassLength,
211
                             email => $email,
212
                         uniqueKey => $uniqueKey,
213
                          username => $username,
214
                   errLinkNotValid => $errLinkNotValid
215
   );
216
}
217
else
218
{
219
    #password recovery form (to send email)
220
    $template->param( password_recovery => 1 );
221
}
222
223
output_html_with_http_headers $query, $cookie, $template->output;

Return to bug 8753