App-ZofCMS
view release on metacpan or search on metacpan
lib/App/ZofCMS/Plugin/UserLogin/ForgotPassword.pm view on Meta::CPAN
return 1
if @$previous_tries > $attempts;
return 1
if @$previous_tries
and $previous_tries->[0]{time} > time() - $interval*60;
return 0;
}
sub set_stage {
my ( $self, $stage ) = @_;
$self->{T}{t}{"plug_forgot_password_stage_$stage"} = 1
if $self->{CONF}{use_stage_indicators};
}
sub dbh {
my $self = shift;
return $self->{DBH}
if $self->{DBH};
$self->{DBH} = DBI->connect_cached(
@{ $self->{CONF} }{ qw/dsn user pass opt/ },
);
return $self->{DBH};
}
sub has_value {
my $v = shift;
return 1
if defined $v and length $v;
return 0;
}
sub create_code_table {
my $conf = shift;
my $dbh = DBI->connect_cached(
@$conf{ qw/dsn user pass opt/ },
);
$dbh->do(
'CREATE TABLE `' . $conf->{code_table} . '` (
`login` TEXT,
`time` VARCHAR(10),
`code` TEXT
);'
);
}
sub change_pass_form_template {
return <<'END_HTML';
<form action="" method="POST" id="plug_forgot_password_new_pass_form">
<div>
<p>Please enter your new password.</p>
<input type="hidden" name="page" value="<tmpl_var escape='html'
name='page'>">
<input type="hidden" name="<tmpl_var escape='html' name='code_name'>"
value="<tmpl_var escape='html' name='code_value'>">
<input type="hidden" name="pulfp_has_change_pass" value="1">
<tmpl_if name='error'>
<p class="error"><tmpl_var escape='html' name='error'></p>
</tmpl_if>
<ul>
<li>
<label for="pulfp_pass">New password: </label
><input type="password"
class="input_password"
name="pulfp_pass"
id="pulfp_pass">
</li>
<li>
<label for="pulfp_repass">Retype new password: </label
><input type="password"
class="input_password"
name="pulfp_repass"
id="pulfp_repass">
</li>
</ul>
<tmpl_var name="submit_button">
</div>
</form>
END_HTML
}
sub email_template {
return <<'END_EMAIL_HTML';
<h2>Password Reset</h2>
<p>Hello. Someone (possibly you) requested a password reset. If that
was you, please follow this link to complete the action:
<a href="<tmpl_var escape='html' name='link'>"><tmpl_var escape='html'
name='link'></a></p>
<p>If you did not request anything, simply ignore this email.</p>
END_EMAIL_HTML
}
sub ask_login_form_template {
return <<'END_FORM';
<form action="" method="POST" id="plug_forgot_password_form">
<div>
<p>Please enter your login into the form below and an email with
further instructions will be sent to you.</p>
<input type="hidden" name="page" value="<tmpl_var escape='html'
name='page'>">
<input type="hidden" name="pulfp_ask_link" value="1">
<tmpl_if name='error'>
<p class="error"><tmpl_var escape='html' name='error'></p>
</tmpl_if>
<label for="pulfp_login">Your login: </label
><input type="text"
class="input_text"
name="pulfp_login"
id="pulfp_login">
<tmpl_var name="submit_button">
</div>
</form>
END_FORM
}
1;
__END__
=encoding utf8
=head1 NAME
App::ZofCMS::Plugin::UserLogin::ForgotPassword - addon plugin that adds functionality to let users reset passwords
=head1 SYNOPSIS
In your L<HTML::Template> template:
<tmpl_var name='plug_forgot_password'>
In your Main Config File or ZofCMS Template:
plugins => [ qw/UserLogin::ForgotPassword/ ],
plug_user_login_forgot_password => {
# mandatory
dsn => "DBI:mysql:database=test;host=localhost",
# everything below is optional...
# ...arguments' default values are shown
user => '',
pass => undef,
opt => { RaiseError => 1, AutoCommit => 1 },
users_table => 'users',
code_table => 'users_forgot_password',
q_code => 'pulfp_code',
max_abuse => '5:10:60', # 5 min. intervals, max 10 attempts per 60 min.
min_pass => 6,
code_expiry => 24*60*60, # 1 day
code_length => 6,
subject => 'Password Reset',
email_link => undef, # this will be guessed
from => undef,
email_template => undef, # use plugin's default template
create_table => undef,
login_page => '/',
mime_lite_params => undef,
email => undef, # use `email` column in users table
button_send_link => q|<input type="submit" class="input_submit"|
. q| value="Send password">|,
button_change_pass => q|<input type="submit" class="input_submit"|
lib/App/ZofCMS/Plugin/UserLogin/ForgotPassword.pm view on Meta::CPAN
line of the email sent to the user (the one containing the link to click).
B<Defaults to:> C<Password Reset>
=head3 C<from>
plug_user_login_forgot_password => {
from => undef,
...
plug_user_login_forgot_password => {
from => 'Zoffix Znet <zoffix@cpan.org>',
...
B<Optional>. Takes a scalar as a value that specifies the C<From> field for
your email. If not specified, the plugin will simply not set the C<From>
argument in L<MIME::Lite>'s C<new()> method (which is what this plugin uses
under the hood). See L<MIME::Lite>'s docs for more description.
B<Defaults to:> C<undef> (not specified)
=head3 C<email_link>
plug_user_login_forgot_password => {
email_link => undef, # guess the right page
...
# note how the URI ends with the "invitation" to append the reset
# ... code right to the end
plug_user_login_forgot_password => {
email_link => 'http://foobar.com/your_page?foo=bar&pulfp_code=',
...
B<Optional>. Takes either C<undef> or a string containing a link
as a value. Specifies the link to the page with this plugin enabled, this
link will be emailed to the user so that they could proceed to
enter their new password. When set to C<undef>, the plugin guesses the
current page (using C<%ENV>) and that's what it will use for the link.
If you specify the string, make sure to end it with C<pulfp_code=> (note
the equals sign at the end), where C<pulfp_code> is the value you have set
for C<q_code> argument. B<Defaults to:> C<undef> (makes the plugin guess
the right link)
=head3 C<email_template>
plug_user_login_forgot_password => {
email_template => undef, # use plugin's default template
...
plug_user_login_forgot_password => {
email_template => \'templates/file.tmpl', # read template from file
...
plug_user_login_forgot_password => {
email_template => '<p>Blah blah blah...', # use this string as template
...
B<Optional>. Takes a scalar, a scalar ref, or C<undef> as a value.
Specifies L<HTML::Template> template to use when generating the email
with the reset link. When set to C<undef>, plugin will use its default
template (see OUTPUT section below). If you're using your own template,
the C<link> template variable will contain the link the user needs to follow
(i.e., use C<< <tmpl_var escape='html' name='link'> >>).
B<Defaults to:> C<undef> (plugin's default, see OUTPUT section below)
=head3 C<login_page>
plug_user_login_forgot_password => {
login_page => '/',
...
plug_user_login_forgot_password => {
login_page => '/my-login-page',
...
plug_user_login_forgot_password => {
login_page => 'http://lolwut.com/your-login-page',
...
B<Optional>. As a value, takes either C<undef> or a URI. Once the user is
through will all the stuff plugin wants them to do, the plugin will tell
them that the password has been changed, and that they can no go ahead
and "log in". If C<login_page> is specified, the "log in" text will be
a link pointing to whatever you set in C<login_page>; otherwise, the
"log in" text will be just plain text. B<Defaults to:> C</> (i.e. web root)
=head3 C<mime_lite_params>
plug_user_login_forgot_password => {
mime_lite_params => undef,
...
plug_user_login_forgot_password => {
mime_lite_params => [
'smtp',
'meowmail',
Auth => [ 'FOO/bar', 'p4ss' ],
],
...
B<Optional>. Takes an arrayref or C<undef> as a value.
If specified, the arrayref will be directly dereferenced into
C<< MIME::Lite->send() >>. Here you can set any special send arguments you
need; see L<MIME::Lite> docs for more info. B<Note:> if the plugin refuses
to send email, it could well be that you need to set some
C<mime_lite_params>; on my box, without anything set, the plugin behaves
as if everything went through fine, but no email arrives.
B<Defaults to:> C<undef>
=head3 C<email>
plug_user_login_forgot_password => {
email => undef,
...
plug_user_login_forgot_password => {
email => 'foo@bar.com,meow.cans@catfood.com',
...
B<Optional>. Takes either C<undef> or email address(es) as a value.
This argument tells the plugin where to send the email containing password
reset link. If set to C<undef>, plugin will look into C<users_table> (see
above) and will assume that email address is associated with the user's
lib/App/ZofCMS/Plugin/UserLogin/ForgotPassword.pm view on Meta::CPAN
an email containing reset pass link.
=head2 C<plug_forgot_password_stage_code_invalid>
<tmpl_if name='plug_forgot_password_stage_code_invalid'>
Your reset code has expired, buddy. Hurry up, next time!
</tmpl_if>
This indicator is active when the plugin can't find the code the user
is giving it. Under natural circumstances, this will only occur when
the code has expired.
=head2 C<plug_forgot_password_stage_change_pass_ask>
<tmpl_if name='plug_forgot_password_stage_change_pass_ask'>
What's the new pass you want, buddy?
</tmpl_if>
This indicator turns on when the form asking the user for the new password
is active.
=head2 C<plug_forgot_password_stage_code_bad_pass_length>
<tmpl_if name='plug_forgot_password_stage_code_bad_pass_length'>
That pass's too short, dude.
</tmpl_if>
This indicator signals that the user attempted to use too short of a new
password (the length is controlled with the C<min_pass> plugin's argument).
=head2 C<plug_forgot_password_stage_code_bad_pass_copy>
<tmpl_if name='plug_forgot_password_stage_code_bad_pass_copy'>
It's really hard to type the same thing twice, ain't it?
</tmpl_if>
This indicator turns on if the user did not retype the new password
correctly.
=head2 C<plug_forgot_password_stage_change_pass_done>
<tmpl_if name='plug_forgot_password_stage_change_pass_done'>
Well, looks like you're all done with reseting your pass and what not.
</tmpl_if>
This indicator shows that the final stage of plugin's run has been reached;
i.e. the user has successfully reset the password and can go on with
their other business.
=head1 OUTPUT
The plugin generates a whole bunch of various output; what's below should
cover all the bases:
=head2 Default Email Template
<h2>Password Reset</h2>
<p>Hello. Someone (possibly you) requested a password reset. If that
was you, please follow this link to complete the action:
<a href="<tmpl_var escape='html' name='link'>"><tmpl_var escape='html'
name='link'></a></p>
<p>If you did not request anything, simply ignore this email.</p>
You can change this using C<email_template> argument. When using your
own, use C<< <tmpl_var escape='html' name='link'> >> to insert the
link the user needs to follow.
=head2 "Ask Login" Form Template
<form action="" method="POST" id="plug_forgot_password_form">
<div>
<p>Please enter your login into the form below and an email with
further instructions will be sent to you.</p>
<input type="hidden" name="page" value="<tmpl_var escape='html'
name='page'>">
<input type="hidden" name="pulfp_ask_link" value="1">
<tmpl_if name='error'>
<p class="error"><tmpl_var escape='html' name='error'></p>
</tmpl_if>
<label for="pulfp_login">Your login: </label
><input type="text"
class="input_text"
name="pulfp_login"
id="pulfp_login">
<input type="submit"
class="input_submit"
value="Send password">
</div>
</form>
This is the form that asks the user for their login in order to reset
the password. Submit button is plugin's default code, you can control
it with the C<button_send_link> plugin's argument.
=head2 "New Password" Form Template
<form action="" method="POST" id="plug_forgot_password_new_pass_form">
<div>
<p>Please enter your new password.</p>
<input type="hidden" name="page" value="<tmpl_var escape='html'
name='page'>">
<input type="hidden" name="<tmpl_var escape='html'
name='code_name'>"
value="<tmpl_var escape='html' name='code_value'>">
<input type="hidden" name="pulfp_has_change_pass" value="1">
<tmpl_if name='error'>
<p class="error"><tmpl_var escape='html' name='error'></p>
</tmpl_if>
<ul>
<li>
<label for="pulfp_pass">New password: </label
><input type="password"
class="input_password"
name="pulfp_pass"
id="pulfp_pass">
</li>
<li>
<label for="pulfp_repass">Retype new password: </label
><input type="password"
class="input_password"
name="pulfp_repass"
id="pulfp_repass">
</li>
</ul>
<input type="submit"
class="input_submit"
value="Change password">
</div>
</form>
This is the template for the form that asks the user for their new
password, as well as the retype of it for confirmation purposes. The code
for the submit button is what the plugin uses by default
(see C<button_change_pass> plugin's argument).
=head2 "Email Sent" Message
<p class="reset_link_send_success">Please check your email
for further instructions on how to reset your password.</p>
This message is shown when the user enters correct login and the
plugin successfully sents the user their reset link email.
=head2 "Expired Reset Code" Message
<p class="reset_code_expired">Your reset code has expired. Please try
resetting your password again.</p>
This will be shown if the user follows a reset link that contains
invalid (expired) reset code.
=head2 "Changes Successfull" Message
<p class="reset_pass_success">Your password has been successfully
changed. You can now use it to <a href="/">log in</a>.</p>
This will be shown when the plugin has done its business and the password
has been reset. Note that the "log in" text will only be a link if
C<login_page> plugin's argument is set; otherwise it will be plain text.
=head1 REQUIRED MODUILES
The plugin requires the following modules/versions for healthy operation:
App::ZofCMS::Plugin::Base => 0.0105
( run in 0.798 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )