Actions for resetting passwords

This commit is contained in:
swag 2023-04-21 21:40:39 -04:00
parent 1c6e8811dc
commit 27fda1f00a
9 changed files with 138 additions and 17 deletions

View File

@ -32,7 +32,6 @@ Run the tests locally (against development environment):
## TODOs ## TODOs
1. Action for resetting passwords
1. Action for locking/unlocking accounts 1. Action for locking/unlocking accounts
1. CSS 1. CSS
1. "All new posts flagged" mode (require approval for new posts) 1. "All new posts flagged" mode (require approval for new posts)

View File

@ -160,6 +160,10 @@ sub startup($self) {
->to('moderator#hidden') ->to('moderator#hidden')
->name('hidden_list'); ->name('hidden_list');
$moderator->any([qw{GET POST}], '/reset')
->to('moderator#mod_reset')
->name('mod_reset');
my $mod_thread = $moderator->under('/thread'); my $mod_thread = $moderator->under('/thread');
$mod_thread->get('/unflag/:thread_id', [thread_id => qr/\d+/]) $mod_thread->get('/unflag/:thread_id', [thread_id => qr/\d+/])
@ -198,6 +202,10 @@ sub startup($self) {
$mod_admin->any([qw{GET POST}], '/create') $mod_admin->any([qw{GET POST}], '/create')
->to('moderator#create') ->to('moderator#create')
->name('create_mod'); ->name('create_mod');
$mod_admin->any([qw{GET POST}], '/reset')
->to('moderator#admin_reset')
->name('admin_reset');
} }
1; 1;

View File

@ -180,4 +180,57 @@ sub create($self) {
return $self->render; return $self->render;
} }
sub admin_reset($self) {
my $v;
$v = $self->validation if $self->req->method eq 'POST';
if ($v && $v->has_data) {
$v->required('email' );
$v->required('password');
if ($v->has_error) {
$self->stash(status => 400)
}
else {
my ($email, $password);
$email = $self->param('email' );
$password = $self->param('password');
$self->moderator->admin_reset($email, $password);
$self->stash(info => "Reset password for $email 🔐");
}
}
return $self->render;
}
sub mod_reset($self) {
my $v;
$v = $self->validation if $self->req->method eq 'POST';
if ($v && $v->has_data) {
$v->required('password');
if ($v->has_error) {
$self->stash(status => 400)
}
else {
my ($password, $mod_id);
$password = $self->param('password');
$mod_id = $self->session->{'mod_id'};
$self->moderator->mod_reset($mod_id, $password);
$self->flash(info => "Password has been reset 🔐");
return $self->redirect_to('flagged_list');
}
}
return $self->render;
}
1; 1;

View File

@ -172,4 +172,24 @@ sub hidden($self) {
END_SQL END_SQL
} }
sub admin_reset($self, $email, $password) {
my $password_hash = $self->authenticator->hash_password($password);
$self->pg->db->query(<<~'END_SQL', $password_hash, $email);
UPDATE moderators
SET password_hash = ?
WHERE email_addr = ?;
END_SQL
}
sub mod_reset($self, $mod_id, $password) {
my $password_hash = $self->authenticator->hash_password($password);
$self->pg->db->query(<<~'END_SQL', $password_hash, $mod_id);
UPDATE moderators
SET password_hash = ?
WHERE moderator_id = ?;
END_SQL
}
1; 1;

View File

@ -23,19 +23,24 @@ subtest Login => sub {
$t->get_ok('/moderator/flagged') $t->get_ok('/moderator/flagged')
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Flagged Posts/) ->text_like(h2 => qr/Flagged Posts/)
->element_exists('a[href*="/moderator/admin/create"]' ); ->element_exists('a[href*="/moderator/admin/create"]')
->element_exists('a[href*="/moderator/admin/reset"]' )
$t->get_ok('/moderator/hidden')
->status_is(200)
->text_like(h2 => qr/Hidden Posts/)
->element_exists('a[href*="/moderator/admin/create"]' );
}; };
subtest Create => sub { subtest Create => sub {
$t->get_ok('/moderator/admin/create') $t->get_ok('/moderator/admin/create')
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Create Moderator/) ->text_like(h2 => qr/Create Moderator/)
->element_exists('a[href*="/moderator/admin/create"]' ) ->element_exists('form input[name="name"]' )
->element_exists('form input[name="email"]' )
->element_exists('form input[name="password"]')
};
subtest Reset => sub {
$t->get_ok('/moderator/admin/reset')
->status_is(200)
->text_like(h2 => qr/Reset Password/)
->element_exists('a[href*="/moderator/admin/reset"]')
}; };
# Admin session ends # Admin session ends
@ -46,11 +51,11 @@ subtest Login => sub {
subtest 'No admin, no buttons', sub { subtest 'No admin, no buttons', sub {
$t->get_ok('/thread/single/1') $t->get_ok('/thread/single/1')
->status_is(200) ->status_is(200)
->element_exists_not('a[href*="/moderator/admin/create"]' ); ->element_exists_not('a[href*="/moderator/admin/create"]');
$t->get_ok('/remark/single/1') $t->get_ok('/remark/single/1')
->status_is(200) ->status_is(200)
->element_exists_not('a[href*="/moderator/admin/create"]' ); ->element_exists_not('a[href*="/moderator/admin/create"]');
$t->get_ok('/moderator/admin/create') $t->get_ok('/moderator/admin/create')
->status_is(302) ->status_is(302)

View File

@ -80,7 +80,7 @@ subtest Login => sub {
$t->get_ok('/moderator/flagged') $t->get_ok('/moderator/flagged')
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Flagged Posts/) ->text_like(h2 => qr/Flagged Posts/)
->element_exists('a[href*="/moderator/flagged"]' ) ->element_exists('a[href*="/moderator/flagged"]')
->element_exists('a[href*="/moderator/hidden"]' ) ->element_exists('a[href*="/moderator/hidden"]' )
->element_exists('a[href*="/logout"]' ) ->element_exists('a[href*="/logout"]' )
}; };
@ -89,11 +89,19 @@ subtest Login => sub {
$t->get_ok('/moderator/hidden') $t->get_ok('/moderator/hidden')
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Hidden Posts/) ->text_like(h2 => qr/Hidden Posts/)
->element_exists('a[href*="/moderator/flagged"]' ) ->element_exists('a[href*="/moderator/flagged"]')
->element_exists('a[href*="/moderator/hidden"]' ) ->element_exists('a[href*="/moderator/hidden"]' )
->element_exists('a[href*="/logout"]' ) ->element_exists('a[href*="/logout"]' )
}; };
subtest Reset => sub {
$t->get_ok('/moderator/reset')
->status_is(200)
->text_like(h2 => qr/Reset Password/)
->element_exists('a[href*="/moderator/reset"]')
->element_exists('form input[name="password"]')
};
# Mod session ends # Mod session ends
$t->get_ok('/logout') $t->get_ok('/logout')
->status_is(302) ->status_is(302)

View File

@ -19,6 +19,7 @@
<span>Moderate:</span> <span>Moderate:</span>
<%= link_to Flagged => 'flagged_list' %> <%= link_to Flagged => 'flagged_list' %>
<%= link_to Hidden => 'hidden_list' %> <%= link_to Hidden => 'hidden_list' %>
<%= link_to Reset => 'mod_reset' %>
<%= link_to Logout => 'mod_logout' %> <%= link_to Logout => 'mod_logout' %>
<% } =%> <% } =%>
</div> </div>
@ -26,6 +27,7 @@
<% if (is_admin) { =%> <% if (is_admin) { =%>
<span>Admin:</span> <span>Admin:</span>
<%= link_to Create => 'create_mod' %> <%= link_to Create => 'create_mod' %>
<%= link_to Reset => 'admin_reset' %>
<% } =%> <% } =%>
</div> </div>
</nav> </nav>

View File

@ -0,0 +1,15 @@
% layout 'default';
% title 'Reset Password';
<h2><%= title %></h2>
<form method="post">
<div class="email field">
<%= label_for email => 'Email' %>
<%= email_field 'email' %>
</div>
<div class="password field">
<%= label_for password => 'Password' %>
<%= password_field 'password' %>
</div>
<%= submit_button 'Reset' %>
</form>

View File

@ -0,0 +1,11 @@
% layout 'default';
% title 'Reset Password';
<h2><%= title %></h2>
<form method="post">
<div class="password field">
<%= label_for password => 'Password' %>
<%= password_field 'password' %>
</div>
<%= submit_button 'Reset' %>
</form>