Overhaul the account recovery form

This commit is contained in:
Chris 2017-01-02 00:04:43 +00:00
parent d4bbc72dfa
commit 1e298dbb10
3 changed files with 139 additions and 98 deletions

View File

@ -160,7 +160,7 @@ sub _recover_email {
"params" => { "uid" => $user -> {"user_id"}, "params" => { "uid" => $user -> {"user_id"},
"resetcode" => $actcode}, "resetcode" => $actcode},
"joinstr" => "&", "joinstr" => "&",
"pathinfo" => [ "recover" ]); "pathinfo" => [ "reset" ]);
my $status = $self -> {"messages"} -> queue_message(subject => $self -> {"template"} -> replace_langvar("LOGIN_RECOVER_SUBJECT"), my $status = $self -> {"messages"} -> queue_message(subject => $self -> {"template"} -> replace_langvar("LOGIN_RECOVER_SUBJECT"),
message => $self -> {"template"} -> load_template("login/email_recover.tem", message => $self -> {"template"} -> load_template("login/email_recover.tem",
@ -563,6 +563,81 @@ sub _validate_resend {
} }
## @method private @ validate_recover()
# Determine whether the email address the user entered is valid, and if so generate
# an act code to start the reset process.
#
# @return Two values: a reference to the user whose reset code has been send
# on success, or an error message, and a reference to a hash containing
# the data entered by the user.
sub _validate_recover {
my $self = shift;
my $args = {};
my $error;
# Get the recaptcha check out of the way first
# Pull the reCAPTCHA response code
($args -> {"recaptcha"}, $error) = $self -> validate_string("g-recaptcha-response", {"required" => 1,
"nicename" => "{L_LOGIN_RECAPTCHA}",
"minlen" => 2,
"formattest" => '^[-\w]+$',
"formatdesc" => "{L_LOGIN_ERR_BADRECAPTCHA}"
});
# Halt here if there are any problems.
return ($self -> {"template"} -> load_template("error/error_list.tem", {"%(message)s" => "{L_LOGIN_ERR_REGFAILED}",
"%(errors)s" => $error}), $args)
if($error);
# Is the response valid?
return ($self -> {"template"} -> load_template("error/error_list.tem", {"%(message)s" => "{L_LOGIN_ERR_REGFAILED}",
"%(errors)s" => "{L_LOGIN_ERR_RECAPTCHA}"}), $args)
unless($self -> _validate_recaptcha($args -> {"recaptcha"}));
# Get the email address entered by the user
($args -> {"email"}, $error) = $self -> validate_string("email", {"required" => 1,
"nicename" => "{L_LOGIN_RECOVER_EMAIL}",
"minlen" => 2,
"maxlen" => 256
});
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => $error}), $args)
if($error);
# Does the email look remotely valid?
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => "{L_LOGIN_ERR_BADEMAIL}"}), $args)
if($args -> {"email"} !~ /^[\w.+-]+\@([\w-]+\.)+\w+$/);
# Does the address correspond to an actual user?
my $user = $self -> {"session"} -> {"auth"} -> {"app"} -> get_user_byemail($args -> {"email"});
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => "{L_LOGIN_ERR_BADUSER}"}), $args)
if(!$user);
# Users can not recover an inactive account - they need to get a new act code
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => "{L_LOGIN_ERR_NORECINACT}"}), $args)
if($self -> {"session"} -> {"auth"} -> capabilities($user -> {"username"}, "activate") &&
!$self -> {"session"} -> {"auth"} -> activated($user -> {"username"}));
# Does the user's authmethod support activation anyway?
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => $self -> {"session"} -> {"auth"} -> capabilities($user -> {"username"}, "recover_message")}), $args)
if(!$self -> {"session"} -> {"auth"} -> capabilities($user -> {"username"}, "recover"));
my $newcode = $self -> {"session"} -> {"auth"} -> generate_actcode($user -> {"username"});
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => $self -> {"session"} -> {"auth"} -> {"app"} -> errstr()}), $args)
if(!$newcode);
# Get here and the user's account has been reset
$self -> _recover_email($user, $newcode);
return($user, $args);
}
## @method private @ validate_passchange() ## @method private @ validate_passchange()
# Determine whether the password change request made by the user is valid. If the # Determine whether the password change request made by the user is valid. If the
# password change is valid (passwords match, pass policy, and the old password is # password change is valid (passwords match, pass policy, and the old password is
@ -663,63 +738,6 @@ sub _validate_passchange {
} }
## @method private @ validate_recover()
# Determine whether the email address the user entered is valid, and if so generate
# an act code to start the reset process.
#
# @return Two values: a reference to the user whose reset code has been send
# on success, or an error message, and a reference to a hash containing
# the data entered by the user.
# FIXME: OVERHAUL
sub _validate_recover {
my $self = shift;
my $args = {};
my $error;
# Get the email address entered by the user
($args -> {"email"}, $error) = $self -> validate_string("email", {"required" => 1,
"nicename" => "{L_LOGIN_RECOVER_EMAIL}",
"minlen" => 2,
"maxlen" => 256
});
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => $error}), $args)
if($error);
# Does the email look remotely valid?
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => "{L_LOGIN_ERR_BADEMAIL}"}), $args)
if($args -> {"email"} !~ /^[\w.+-]+\@([\w-]+\.)+\w+$/);
# Does the address correspond to an actual user?
my $user = $self -> {"session"} -> {"auth"} -> {"app"} -> get_user_byemail($args -> {"email"});
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => "{L_LOGIN_ERR_BADUSER}"}), $args)
if(!$user);
# Users can not recover an inactive account - they need to get a new act code
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => "{L_LOGIN_ERR_NORECINACT}"}), $args)
if($self -> {"session"} -> {"auth"} -> capabilities($user -> {"username"}, "activate") &&
!$self -> {"session"} -> {"auth"} -> activated($user -> {"username"}));
# Does the user's authmethod support activation anyway?
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => $self -> {"session"} -> {"auth"} -> capabilities($user -> {"username"}, "recover_message")}), $args)
if(!$self -> {"session"} -> {"auth"} -> capabilities($user -> {"username"}, "recover"));
my $newcode = $self -> {"session"} -> {"auth"} -> generate_actcode($user -> {"username"});
return ($self -> {"template"} -> load_template("error/error.tem", { "%(message)s" => "{L_LOGIN_RECOVER_FAILED}",
"%(reason)s" => $self -> {"session"} -> {"auth"} -> {"app"} -> errstr()}), $args)
if(!$newcode);
# Get here and the user's account has been reset
$self -> recover_email($user, $newcode);
return($user, $args);
}
## @method private @ validate_reset() ## @method private @ validate_reset()
# Pull the userid and activation code out of the submitted data, and determine # Pull the userid and activation code out of the submitted data, and determine
# whether they are valid (and that the user's authmethod allows for resets). If # whether they are valid (and that the user's authmethod allows for resets). If
@ -772,7 +790,7 @@ sub _validate_reset {
if(!$newpass); if(!$newpass);
# Get here and the user's account has been reset # Get here and the user's account has been reset
$self -> reset_email($user, $newpass); $self -> _reset_email($user, $newpass);
return($user, $args); return($user, $args);
} }
@ -856,8 +874,8 @@ sub _generate_actcode_form {
return ("{L_LOGIN_TITLE}", return ("{L_LOGIN_TITLE}",
$self -> {"template"} -> load_template("login/form_activate.tem", {"%(error)s" => $error, $self -> {"template"} -> load_template("login/form_activate.tem", {"%(error)s" => $error,
"%(url-target)s" => $self -> build_url("block" => "login"), "%(url-target)s" => $self -> build_url("block" => "login", "pathinfo" => [ "activate" ]),
"%(url-resend)s" => $self -> build_url("block" => "login", "pathinfo" => [ "resend" ]),}), "%(url-resend)s" => $self -> build_url("block" => "login", "pathinfo" => [ "resend" ]),}),
$self -> {"template"} -> load_template("login/extrahead.tem"), $self -> {"template"} -> load_template("login/extrahead.tem"),
$self -> {"template"} -> load_template("login/extrajs.tem")); $self -> {"template"} -> load_template("login/extrajs.tem"));
} }
@ -880,7 +898,32 @@ sub _generate_resend_form {
return ("{L_LOGIN_RESEND_TITLE}", return ("{L_LOGIN_RESEND_TITLE}",
$self -> {"template"} -> load_template("login/form_resend.tem", {"%(error)s" => $error, $self -> {"template"} -> load_template("login/form_resend.tem", {"%(error)s" => $error,
"%(sitekey)s" => $self -> {"settings"} -> {"config"} -> {"Login:recaptcha_sitekey"}, "%(sitekey)s" => $self -> {"settings"} -> {"config"} -> {"Login:recaptcha_sitekey"},
"%(url-target)s" => $self -> build_url("block" => "login")}), "%(url-target)s" => $self -> build_url("block" => "login", "pathinfo" => [ "resend" ])
}),
$self -> {"template"} -> load_template("login/signup_extrahead.tem"),
$self -> {"template"} -> load_template("login/extrajs.tem"));
}
## @method private @ generate_recover_form($error)
# Generate a form through which the user may recover their account details.
#
# @param error A string containing errors related to recovery, or undef.
# @return An array containing the page title, content, extra header data, and
# extra javascript content.
sub _generate_recover_form {
my $self = shift;
my $error = shift;
# Wrap the error message in a message box if we have one.
$error = $self -> {"template"} -> load_template("error/error_box.tem", {"%(message)s" => $error})
if($error);
return ("{L_LOGIN_RECOVER_TITLE}",
$self -> {"template"} -> load_template("login/form_recover.tem", {"%(error)s" => $error,
"%(sitekey)s" => $self -> {"settings"} -> {"config"} -> {"Login:recaptcha_sitekey"},
"%(url-target)s" => $self -> build_url("block" => "login", "pathinfo" => [ "recover" ])
}),
$self -> {"template"} -> load_template("login/signup_extrahead.tem"), $self -> {"template"} -> load_template("login/signup_extrahead.tem"),
$self -> {"template"} -> load_template("login/extrajs.tem")); $self -> {"template"} -> load_template("login/extrajs.tem"));
} }
@ -922,27 +965,6 @@ sub _generate_passchange_form {
} }
## @method private @ generate_recover_form($error)
# Generate a form through which the user may recover their account details.
#
# @param error A string containing errors related to recovery, or undef.
# @return An array containing the page title, content, extra header data, and
# extra javascript content.
# FIXME: OVERHAUL
sub _generate_recover_form {
my $self = shift;
my $error = shift;
# Wrap the error message in a message box if we have one.
$error = $self -> {"template"} -> load_template("error/error_box.tem", {"%(message)s" => $error})
if($error);
return ("{L_LOGIN_TITLE}",
$self -> {"template"} -> load_template("login/recover_form.tem", {"%(error)s" => $error,
"%(target)s" => $self -> build_url("block" => "login")}));
}
# ============================================================================ # ============================================================================
# Response generators # Response generators
@ -1079,7 +1101,7 @@ sub _generate_resent {
summary => "{L_LOGIN_RESEND_SUMMARY}", summary => "{L_LOGIN_RESEND_SUMMARY}",
message => "{L_LOGIN_RESEND_MESSAGE}", message => "{L_LOGIN_RESEND_MESSAGE}",
buttons => [ {"message" => "{L_LOGIN_ACTIVATE}", buttons => [ {"message" => "{L_LOGIN_ACTIVATE}",
"colour" => "blue", "colour" => "standard",
"href" => $url} ])); "href" => $url} ]));
} }
@ -1089,22 +1111,19 @@ sub _generate_resent {
# sent to their email address. # sent to their email address.
# #
# @return An array of two values: the page title string, the 'recover sent' message. # @return An array of two values: the page title string, the 'recover sent' message.
# FIXME: OVERHAUL
sub _generate_recover { sub _generate_recover {
my $self = shift; my $self = shift;
my $url = $self -> build_url("block" => "login", "pathinfo" => []); my $url = $self -> build_url("block" => "login", "pathinfo" => []);
return ("{L_LOGIN_RECOVER_DONETITLE}", return ("{L_LOGIN_RECOVER_DONETITLE}",
$self -> message_box("{L_LOGIN_RECOVER_DONETITLE}", $self -> message_box(title => "{L_LOGIN_RECOVER_DONETITLE}",
"security", type => "account",
"{L_LOGIN_RECOVER_SUMMARY}", summary => "{L_LOGIN_RECOVER_SUMMARY}",
"{L_LOGIN_RECOVER_MESSAGE}", message => "{L_LOGIN_RECOVER_MESSAGE}",
undef, buttons => [ {"message" => "{L_LOGIN_LOGIN}",
"logincore", "colour" => "standard",
[ {"message" => "{L_LOGIN_LOGIN}", "href" => $url} ]));
"colour" => "blue",
"action" => "location.href='$url'"} ]));
} }

View File

@ -70,18 +70,21 @@ LOGIN_ACTIVATE_SUMMARY = Activation successful!
LOGIN_ACTIVATE_MESSAGE = Your new account has been acivated, and you can now <a href="%(url-login)s">sign in</a> using your username and the password emailed to you. LOGIN_ACTIVATE_MESSAGE = Your new account has been acivated, and you can now <a href="%(url-login)s">sign in</a> using your username and the password emailed to you.
# Recovery related # Recovery related
LOGIN_RECFORM = Recover account details LOGIN_RECOVER_TITLE = Recover account details
LOGIN_RECINTRO = If you have forgotten your username or password, enter the email address associated with your account in the field below. An email will be sent to you containing your username, and a link to click on to reset your password. If you do not have access to the email address associated with your account, please contact the site owner. LOGIN_RECOVER_DESC = If you have forgotten your username or password, enter the email address associated with your account in the field below. An email will be sent to you containing your username, and a link to click on to reset your password. If you do not have access to the email address associated with your account, please contact the site owner.
LOGIN_RECEMAIL = Email address LOGIN_RECOVER_EMAIL = Email address
LOGIN_DORECOVER = Recover account LOGIN_DORECOVER = Recover account
LOGIN_RECOVER_SUBJECT = Your {V_[sitename]} account LOGIN_RECOVER_SUBJECT = Your {V_[sitename]} account
LOGIN_RECOVER_GREET = Hi %(username)s LOGIN_RECOVER_GREET = Hi %(username)s
LOGIN_RECOVER_INTRO = You, or someone pretending to be you, has requested that your password be reset. In order to reset your account, please click on the following link, or copy and paste it into your web browser. LOGIN_RECOVER_INTRO = You, or someone pretending to be you, has requested that your password be reset. In order to reset your account, please click on the following link, or copy and paste it into your web browser.
LOGIN_RECOVER_IGNORE = If you did not request this reset, please either ignore this email or report it to the {V_[sitename]} administrator. LOGIN_RECOVER_IGNORE = If you did not request this reset, please either ignore this email or report it to the {V_[sitename]} administrator.
LOGIN_RECOVER_FAILED = Account recovery failed LOGIN_RECOVER_FAILED = Account recovery failed
LOGIN_RECOVER_DONETITLE = Account recovery code sent LOGIN_RECOVER_DONETITLE = Account recovery code sent
LOGIN_RECOVER_SUMMARY = Recovery code sent! LOGIN_RECOVER_SUMMARY = Recovery code sent!
LOGIN_RECOVER_MESSAGE = An account recovery code has been send to your email address.<br /><br />Please check your email for a message with the subject 'Your {V_[sitename]} account' and follow the instructions it contains. LOGIN_RECOVER_MESSAGE = An account recovery code has been send to your email address.<br /><br />Please check your email for a message with the subject 'Your {V_[sitename]} account' and follow the instructions it contains.
LOGIN_ERR_NOUID = No user id specified. LOGIN_ERR_NOUID = No user id specified.
LOGIN_ERR_BADUID = The specfied user id is not valid. LOGIN_ERR_BADUID = The specfied user id is not valid.
LOGIN_ERR_BADRECCHAR = Account reset codes may only contain alphanumeric characters. LOGIN_ERR_BADRECCHAR = Account reset codes may only contain alphanumeric characters.

View File

@ -0,0 +1,19 @@
<div class="small-8 small-centered columns">
%(error)s
<!-- Start recover form -->
<div class="recoverform callout secondary">
<div>{L_LOGIN_RECOVER_DESC}</div>
<form id="recoverform" method="post" action="%(url-target)s">
<div class="entry">
<label for="email">{L_LOGIN_RECOVER_EMAIL}:<br />
<input type="text" id="email" name="email" size="24" maxlength="255" value=""/>
</label>
</div>
<div class="g-recaptcha" data-sitekey="%(sitekey)s"></div>
<div class="submit clearfix">
<input type="submit" class="button float-right nomargin" id="dorecover" name="dorecover" value="{L_LOGIN_DORECOVER}" />
</div>
</form>
</div>
<!-- End recover form -->
</div>