Skip to content

Commit

Permalink
Add forgot password workflow.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaitlyn Parkhurst committed Oct 9, 2021
1 parent e0cdea8 commit a1dc2ee
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 4 deletions.
64 changes: 60 additions & 4 deletions Web/lib/BlogDB/Web/Controller/Root.pm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package BlogDB::Web::Controller::Root;
use Mojo::Base 'Mojolicious::Controller', -signatures;
use Try::Tiny;
use Data::UUID;

sub get_register ($c) {
$c->set_template( 'register' );
Expand Down Expand Up @@ -63,27 +64,82 @@ sub post_register ($c) {

sub get_forgot ($c) {
$c->set_template( 'forgot' );

}

sub post_forgot ($c) {
$c->set_template( 'forgot' );

my $username = $c->stash->{form_username} = $c->param('username');

# Find the user -- if they have an @, assume it's an email addresss.
my $person = $c->db->resultset('Person')->find( index($username, '@') == -1
? { username => $username }
: { email => $username }
);

push @{$c->stash->{errors}}, "No such username or email address."
unless $person;

return 0 if $c->stash->{errors}; # Drop out of processing if there are errors.

my $reset_token = $person->create_related( 'password_tokens', {
token => Data::UUID->new->create_str,
});

# TODO
# This is the part where we email $person->email with $c->url_for( 'reset', { token => $reset_token->token } );

$c->stash->{success} = 1;
}

sub get_reset ($c) {
$c->set_template( 'reset' );

$c->stash->{form_token} = $c->param('token');

}

sub post_reset ($c) {
$c->set_template( 'reset' );

my $form_token = $c->stash->{form_token} = $c->param('reset_token');
my $password = $c->stash->{form_password} = $c->param('password');
my $confirm = $c->stash->{form_confirm} = $c->param('confirm');

}
# Error Checking - We have all of the information.
push @{$c->stash->{errors}}, "Password is required." unless $password;
push @{$c->stash->{errors}}, "Confirm password is required." unless $password;
push @{$c->stash->{errors}}, "Password & Confirmation must match." unless $password eq $confirm;
push @{$c->stash->{errors}}, "Password must be at least 7 chars." unless 7 < length($password);

sub post_reset ($c) {
$c->set_template( 'login' );
return 0 if $c->stash->{errors}; # Drop out of processing, there are errors..

my $token = $c->db->resultset('PasswordToken')->search({
token => $form_token,
is_redeemed => 0,
})->first;

push @{$c->stash->{errors}}, "Invalid token" unless $token;;
return 0 if $c->stash->{errors}; # Drop out of processing, there are errors..

my $person = try {
$c->db->storage->schema->txn_do( sub {
# Update the user's password.
$token->person->auth_password->update_password( $password );

# Mark the token used.
$token->is_redeemed( 1 );
$token->update;

return $token->person;
});
} catch {
push @{$c->stash->{errors}}, "The password could not be reset: $_";
};

return 0 if $c->stash->{errors}; # Drop out of processing the registration if there are any errors.

$c->stash->{success} = 1;
}

sub post_login ($c) {
Expand Down
34 changes: 34 additions & 0 deletions Web/templates/default/forgot.html.tx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
%% cascade default::_::layout { title => 'Forgot Password',
%%
%% }

%% override panel -> {
<div class="row">
<!-- Error Handling On LHS -->
<div class="col">
%% if ( $errors.size() ) {
<div style="margin-top: 2em" class="alert alert-danger" role="alert">
There were errors with your request that could not be resolved:
<ul>
%% for $errors -> $error {
<li>[% $error %]</li>
%% }
</ul>
</div>
%% }
</div>

<!-- Forgot Handling On RHS -->
<div class="col">
<form method="post" action="[% $c.url_for( 'do_forgot_password' ) %]">
%% include 'default/_/form/input.tx' { type => 'text', name => 'username',
%% title => 'Username (or email)',
%% help => 'The username or email address you signed up with.',
%% value => $form_username,
%% };

<button type="submit" class="btn btn-primary float-end">Send Reset Email</button>

</form>
</div>
%% }
42 changes: 42 additions & 0 deletions Web/templates/default/reset.html.tx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
%% cascade default::_::layout { title => 'Reset Password',
%%
%% }

%% override panel -> {
<div class="row">
<!-- Error Handling On LHS -->
<div class="col">
%% if ( $errors.size() ) {
<div style="margin-top: 2em" class="alert alert-danger" role="alert">
There were errors with your request that could not be resolved:
<ul>
%% for $errors -> $error {
<li>[% $error %]</li>
%% }
</ul>
</div>
%% }
</div>

<!-- Forgot Handling On RHS -->
<div class="col">
<form method="post" action="[% $c.url_for( 'do_reset_password' ) %]">
<input type="hidden" name="reset_token" value="[% $form_token %]">

%% include 'default/_/form/input.tx' { type => 'password', name => 'password',
%% title => 'Password',
%% help => 'You will need your password to login.',
%% value => $form_password,
%% };

%% include 'default/_/form/input.tx' { type => 'password', name => 'confirm',
%% title => 'Confirm password',
%% help => mark_raw('Just to <strike>annoy you</strike> be sure it is correct.'),
%% value => $form_confirm,
%% };

<button type="submit" class="btn btn-primary float-end">Change Password</button>

</form>
</div>
%% }

0 comments on commit a1dc2ee

Please sign in to comment.