Compare commits

...

19 Commits

29 changed files with 280 additions and 39 deletions

View File

@ -1,4 +1,4 @@
FROM docker.io/perl:5.36 FROM docker.io/perl:5.40
# Move it # Move it
WORKDIR /opt WORKDIR /opt

View File

@ -61,7 +61,7 @@ tests locally:
## TODOs ## TODOs
- Tripcodes/PGP signing somehow perhaps... - Stop working on this and start the imageboard
## AGPL-3.0+ANTIFA compliance ## AGPL-3.0+ANTIFA compliance

View File

@ -188,6 +188,11 @@ sub startup($self) {
->to('thread#flag') ->to('thread#flag')
->name('flag_thread'); ->name('flag_thread');
# Redirect for this old path to the new one
$thread->any([qw{GET POST}], '/post', sub ($c) {
$c->redirect_to('post_thread')
});
$human_thread->any([qw{GET POST}], '/post') $human_thread->any([qw{GET POST}], '/post')
->to('thread#create') ->to('thread#create')
->name('post_thread'); ->name('post_thread');

View File

@ -39,8 +39,15 @@ sub login($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('email' )->size(6, 320); $v->required('email' )->size(6, 320);
$v->required('password')->size(12, undef); $v->required('password')->size(12, undef);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
);
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -153,8 +160,15 @@ sub create($self) {
$v->required('name' )->size(1, 64); $v->required('name' )->size(1, 64);
$v->required('email' )->size(6, 320); $v->required('email' )->size(6, 320);
$v->required('password')->size(12, undef); $v->required('password')->size(12, undef);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -178,8 +192,15 @@ sub admin_reset($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('email' )->size(6, 320); $v->required('email' )->size(6, 320);
$v->required('password')->size(12, undef); $v->required('password')->size(12, undef);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -201,8 +222,15 @@ sub mod_reset($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('password')->size(12, undef); $v->required('password')->size(12, undef);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -226,8 +254,15 @@ sub lock_acct($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('email')->size(6, 320); $v->required('email')->size(6, 320);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -248,8 +283,15 @@ sub unlock_acct($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('email')->size(6, 320); $v->required('email')->size(6, 320);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -270,8 +312,15 @@ sub promote($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('email')->size(6, 320); $v->required('email')->size(6, 320);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {
@ -292,8 +341,15 @@ sub demote($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('email')->size(6, 320); $v->required('email')->size(6, 320);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {

View File

@ -20,8 +20,15 @@ sub captcha($self) {
if ($v && $v->has_data) { if ($v && $v->has_data) {
$v->required('answer')->num(1, 9); $v->required('answer')->num(1, 9);
$v->required('number')->size(1, 4); $v->required('number')->size(1, 4);
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {

View File

@ -36,8 +36,15 @@ sub create($self) {
$v->required('body' )->size(2, $body_limit); $v->required('body' )->size(2, $body_limit);
$v->optional('bump' ); $v->optional('bump' );
$v->optional('preview'); $v->optional('preview');
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
)
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {

View File

@ -15,8 +15,15 @@ sub create($self) {
$v->required('title' )->size(1, 127); $v->required('title' )->size(1, 127);
$v->required('body' )->size(2, $body_limit); $v->required('body' )->size(2, $body_limit);
$v->optional('preview'); $v->optional('preview');
$v->csrf_protect;
if ($v->has_error) { if ($v->has_error('csrf_token')) {
$self->stash(
status => 403,
error => 'Something went wrong, please try again. 🥺'
);
}
elsif ($v->has_error) {
$self->stash(status => 400) $self->stash(status => 400)
} }
else { else {

View File

@ -156,7 +156,8 @@ sub flagged($self) {
SELECT 'remark', SELECT 'remark',
remark_id remark_id
FROM remarks FROM remarks
WHERE flagged_status; WHERE flagged_status
ORDER BY id DESC;
END_SQL END_SQL
} }
@ -170,7 +171,8 @@ sub hidden($self) {
SELECT 'remark', SELECT 'remark',
remark_id remark_id
FROM remarks FROM remarks
WHERE hidden_status; WHERE hidden_status
ORDER BY id DESC;
END_SQL END_SQL
} }
@ -270,7 +272,8 @@ sub list($self) {
TO_CHAR(last_login_date, $1) AS last_login_date, TO_CHAR(last_login_date, $1) AS last_login_date,
lock_status, lock_status,
admin_status admin_status
FROM moderators; FROM moderators
ORDER BY last_login_date DESC;
END_SQL END_SQL
} }

View File

@ -73,7 +73,6 @@ table { width: 100%; }
table, th, td { table, th, td {
border-collapse: collapse; border-collapse: collapse;
border: 0.15em dotted black;
text-align: center; text-align: center;
} }

View File

@ -1,8 +1,6 @@
(function () { (function () {
const bodyStyle = document.body.style;
function setImage(url) { function setImage(url) {
bodyStyle.backgroundImage = "url('" + url + "')"; document.body.style.backgroundImage = "url('" + url + "')";
} }
switch (new Date().getMonth()) { switch (new Date().getMonth()) {

View File

@ -3,8 +3,7 @@
# PostText v0.1 # PostText v0.1
# Jul 22 2022 # Jul 22 2022
use v5.36; use v5.40;
#no warnings 'experimental';
use Mojo::File qw{curfile}; use Mojo::File qw{curfile};
use lib curfile->dirname->sibling('lib')->to_string; use lib curfile->dirname->sibling('lib')->to_string;
use Mojolicious::Commands; use Mojolicious::Commands;

View File

@ -10,6 +10,11 @@ my %valid_login = (
); );
subtest Login => sub { subtest Login => sub {
$t->get_ok('/login');
$valid_login{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/login', form => \%valid_login) $t->post_ok('/login', form => \%valid_login)
->status_is(302) ->status_is(302)
->header_like(Location => qr{moderator/flagged}); ->header_like(Location => qr{moderator/flagged});
@ -34,6 +39,7 @@ subtest Login => sub {
->element_exists('form input[name="name"]' ) ->element_exists('form input[name="name"]' )
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="password"]' ) ->element_exists('form input[name="password"]' )
->element_exists('form input[name="csrf_token"]')
}; };
subtest Reset => sub { subtest Reset => sub {
@ -43,6 +49,7 @@ subtest Login => sub {
->element_exists('a[href*="/moderator/admin/reset"]') ->element_exists('a[href*="/moderator/admin/reset"]')
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="password"]' ) ->element_exists('form input[name="password"]' )
->element_exists('form input[name="csrf_token"]' )
}; };
subtest Lock => sub { subtest Lock => sub {
@ -51,6 +58,7 @@ subtest Login => sub {
->text_like(h2 => qr/Lock Account/) ->text_like(h2 => qr/Lock Account/)
->element_exists('a[href*="/moderator/admin/lock"]') ->element_exists('a[href*="/moderator/admin/lock"]')
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="csrf_token"]' )
}; };
subtest Unlock => sub { subtest Unlock => sub {
@ -59,6 +67,7 @@ subtest Login => sub {
->text_like(h2 => qr/Unlock Account/) ->text_like(h2 => qr/Unlock Account/)
->element_exists('a[href*="/moderator/admin/unlock"]') ->element_exists('a[href*="/moderator/admin/unlock"]')
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="csrf_token"]' )
}; };
subtest Promote => sub { subtest Promote => sub {
@ -67,6 +76,7 @@ subtest Login => sub {
->text_like(h2 => qr/Promote Moderator/) ->text_like(h2 => qr/Promote Moderator/)
->element_exists('a[href*="/moderator/admin/promote"]') ->element_exists('a[href*="/moderator/admin/promote"]')
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="csrf_token"]' )
}; };
subtest Demote => sub { subtest Demote => sub {
@ -75,6 +85,7 @@ subtest Login => sub {
->text_like(h2 => qr/Demote Admin/) ->text_like(h2 => qr/Demote Admin/)
->element_exists('a[href*="/moderator/admin/demote"]') ->element_exists('a[href*="/moderator/admin/demote"]')
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="csrf_token"]' )
}; };
# Admin session ends # Admin session ends

View File

@ -25,18 +25,39 @@ subtest 'Bumping thread', sub {
$t->get_ok('/human/thread/bump/1')->status_is(302) $t->get_ok('/human/thread/bump/1')->status_is(302)
->header_like(Location => qr/captcha/); ->header_like(Location => qr/captcha/);
$t->get_ok($bump_thread_url)
->status_is(200)
->element_exists('input[name="answer"]' )
->element_exists('input[name="number"]' )
->element_exists('input[name="csrf_token"]');
# Bad CSRF
$t->post_ok($bump_thread_url, form => \%bad_bot)
->status_is(403)
->element_exists('p[class="stash-with-error"]')
->text_like(p => qr/Something went wrong/);
# Bad CAPTCHA # Bad CAPTCHA
$bad_bot{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($bump_thread_url, form => \%bad_bot) $t->post_ok($bump_thread_url, form => \%bad_bot)
->status_is(400) ->status_is(400)
->element_exists('p[class="stash-with-error"]') ->element_exists('p[class="stash-with-error"]')
->text_like(p => qr/Sounds like something a robot would say/); ->text_like(p => qr/Sounds like something a robot would say/);
$invalid_captcha{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($bump_thread_url, form => \%invalid_captcha) $t->post_ok($bump_thread_url, form => \%invalid_captcha)
->status_is(400) ->status_is(400)
->element_exists('p[class="field-with-error"]') ->element_exists('p[class="field-with-error"]')
->text_like(p => qr/Should be a single number/); ->text_like(p => qr/Should be a single number/);
# Solved CAPTCHA # Solved CAPTCHA
$good_human{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($bump_thread_url, form => \%good_human) $t->post_ok($bump_thread_url, form => \%good_human)
->status_is(302) ->status_is(302)
->header_like(Location => qr{human/thread/bump/1}); ->header_like(Location => qr{human/thread/bump/1});
@ -56,18 +77,35 @@ subtest 'Flagging thread', sub {
$t->get_ok('/human/thread/flag/1')->status_is(302) $t->get_ok('/human/thread/flag/1')->status_is(302)
->header_like(Location => qr/captcha/); ->header_like(Location => qr/captcha/);
# Bad CSRF
$t->get_ok($flag_thread_url);
$t->post_ok($flag_thread_url, form => \%bad_bot)
->status_is(403)
->element_exists('p[class="stash-with-error"]')
->text_like(p => qr/Something went wrong/);
# Bad CAPTCHA # Bad CAPTCHA
$bad_bot{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($flag_thread_url, form => \%bad_bot) $t->post_ok($flag_thread_url, form => \%bad_bot)
->status_is(400) ->status_is(400)
->element_exists('p[class="stash-with-error"]') ->element_exists('p[class="stash-with-error"]')
->text_like(p => qr/Sounds like something a robot would say/); ->text_like(p => qr/Sounds like something a robot would say/);
$invalid_captcha{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($flag_thread_url, form => \%invalid_captcha) $t->post_ok($flag_thread_url, form => \%invalid_captcha)
->status_is(400) ->status_is(400)
->element_exists('p[class="field-with-error"]') ->element_exists('p[class="field-with-error"]')
->text_like(p => qr/Should be a single number/); ->text_like(p => qr/Should be a single number/);
# Solved CAPTCHA # Solved CAPTCHA
$good_human{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($flag_thread_url, form => \%good_human) $t->post_ok($flag_thread_url, form => \%good_human)
->status_is(302) ->status_is(302)
->header_like(Location => qr{human/thread/flag/1}); ->header_like(Location => qr{human/thread/flag/1});
@ -83,18 +121,35 @@ subtest 'Flagging remark', sub {
$t->get_ok('/human/remark/flag/1')->status_is(302) $t->get_ok('/human/remark/flag/1')->status_is(302)
->header_like(Location => qr/captcha/); ->header_like(Location => qr/captcha/);
# Bad CSRF
$t->get_ok($flag_remark_url);
$t->post_ok($flag_remark_url, form => \%bad_bot)
->status_is(403)
->element_exists('p[class="stash-with-error"]')
->text_like(p => qr/Something went wrong/);
# Bad CAPTCHA # Bad CAPTCHA
$bad_bot{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($flag_remark_url, form => \%bad_bot) $t->post_ok($flag_remark_url, form => \%bad_bot)
->status_is(400) ->status_is(400)
->element_exists('p[class="stash-with-error"]') ->element_exists('p[class="stash-with-error"]')
->text_like(p => qr/Sounds like something a robot would say/); ->text_like(p => qr/Sounds like something a robot would say/);
$invalid_captcha{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($flag_remark_url, form => \%invalid_captcha) $t->post_ok($flag_remark_url, form => \%invalid_captcha)
->status_is(400) ->status_is(400)
->element_exists('p[class="field-with-error"]') ->element_exists('p[class="field-with-error"]')
->text_like(p => qr/Should be a single number/); ->text_like(p => qr/Should be a single number/);
# Solved CAPTCHA # Solved CAPTCHA
$good_human{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($flag_remark_url, form => \%good_human) $t->post_ok($flag_remark_url, form => \%good_human)
->status_is(302) ->status_is(302)
->header_like(Location => qr{human/remark/flag/1}); ->header_like(Location => qr{human/remark/flag/1});

View File

@ -19,14 +19,26 @@ subtest Login => sub {
->status_is(200) ->status_is(200)
->element_exists('form input[name="email"]' ) ->element_exists('form input[name="email"]' )
->element_exists('form input[name="password"]' ) ->element_exists('form input[name="password"]' )
->element_exists('form input[name="csrf_token"]')
->text_like(h2 => qr/Moderator Login/); ->text_like(h2 => qr/Moderator Login/);
# Bad CSRF token
$t->post_ok('/login', form => \%valid_login)
->status_is(403)
->text_like(p => qr/Something went wrong/);
$invalid_login{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/login', form => \%invalid_login) $t->post_ok('/login', form => \%invalid_login)
->status_is(403) ->status_is(403)
->element_exists('form input[name="email"]') ->element_exists('form input[name="email"]')
->element_exists('form input[name="password"]') ->element_exists('form input[name="password"]')
->text_like(p => qr/Invalid login/); ->text_like(p => qr/Invalid login/);
$valid_login{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/login', form => \%valid_login) $t->post_ok('/login', form => \%valid_login)
->status_is(302) ->status_is(302)
->header_like(Location => qr{moderator/flagged}); ->header_like(Location => qr{moderator/flagged});

View File

@ -44,6 +44,11 @@ $t->get_ok('/human/remark/post/1')->status_is(302)
->header_like(Location => qr/captcha/); ->header_like(Location => qr/captcha/);
# Do CAPTCHA # Do CAPTCHA
$t->get_ok($bump_thread_url);
$good_captcha{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($bump_thread_url, form => \%good_captcha) $t->post_ok($bump_thread_url, form => \%good_captcha)
->status_is(302) ->status_is(302)
->header_like(Location => qr{human/thread/bump/1}); ->header_like(Location => qr{human/thread/bump/1});
@ -57,6 +62,7 @@ subtest 'Post new thread', sub {
->element_exists('form input[name="title"]' ) ->element_exists('form input[name="title"]' )
->element_exists('form textarea[name="body"]' ) ->element_exists('form textarea[name="body"]' )
->element_exists('form button[type="submit"]' ) ->element_exists('form button[type="submit"]' )
->element_exists('form input[name="csrf_token"]')
->text_like(h2 => qr/New Thread/); ->text_like(h2 => qr/New Thread/);
# POST # POST
@ -67,14 +73,28 @@ subtest 'Post new thread', sub {
->element_exists('form button[type="submit"]') ->element_exists('form button[type="submit"]')
->text_like(h2 => qr/New Thread/); ->text_like(h2 => qr/New Thread/);
# No CSRF token
$t->post_ok('/human/thread/post', form => \%valid_thread)
->status_is(403)
->text_like(p => qr/Something went wrong/);
$invalid_title{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%invalid_title) $t->post_ok('/human/thread/post', form => \%invalid_title)
->status_is(400) ->status_is(400)
->text_like(p => qr/Must be between/); ->text_like(p => qr/Must be between/);
$invalid_thread{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%invalid_thread) $t->post_ok('/human/thread/post', form => \%invalid_thread)
->status_is(400) ->status_is(400)
->text_like(p => qr/Must be between/); ->text_like(p => qr/Must be between/);
$valid_thread{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%valid_thread) $t->post_ok('/human/thread/post', form => \%valid_thread)
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Thread #\d+/); ->text_like(h2 => qr/Thread #\d+/);
@ -104,10 +124,25 @@ subtest 'Post new remark', sub {
->element_exists('form button[type="submit"]' ) ->element_exists('form button[type="submit"]' )
->text_like(h2 => qr/Remark on Thread #/); ->text_like(h2 => qr/Remark on Thread #/);
# No CSRF token
$t->post_ok('/human/remark/post/1', form => \%valid_remark)
->status_is(403)
->text_like(p => qr/Something went wrong/);
$t->get_ok('/human/remark/post/1');
$valid_remark{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/remark/post/1', form => \%valid_remark) $t->post_ok('/human/remark/post/1', form => \%valid_remark)
->status_is(200) ->status_is(200)
->text_like(h2 => qr/Thread #1/); ->text_like(h2 => qr/Thread #1/);
$t->get_ok('/human/remark/post/1');
$invalid_remark{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/remark/post/1', form => \%invalid_remark) $t->post_ok('/human/remark/post/1', form => \%invalid_remark)
->status_is(400) ->status_is(400)
->text_like(p => qr/Must be between/); ->text_like(p => qr/Must be between/);

View File

@ -23,6 +23,11 @@ my %preview_remark = (
); );
# Do CAPTCHA # Do CAPTCHA
$t->get_ok($bump_thread_url);
$good_captcha{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($bump_thread_url, form => \%good_captcha) $t->post_ok($bump_thread_url, form => \%good_captcha)
->status_is(302) ->status_is(302)
->header_like(Location => qr{human/thread/bump/1}); ->header_like(Location => qr{human/thread/bump/1});
@ -36,10 +41,20 @@ subtest 'Check the form + button', sub {
}; };
subtest 'Submit input', sub { subtest 'Submit input', sub {
$t->get_ok('/human/remark/post/1');
$preview_remark{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/remark/post/1', form => \%preview_remark) $t->post_ok('/human/remark/post/1', form => \%preview_remark)
->status_is(200) ->status_is(200)
->text_like(p => qr/ayy\.\.\. lmao/); ->text_like(p => qr/ayy\.\.\. lmao/);
$t->get_ok('/human/thread/post');
$preview_thread{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok('/human/thread/post', form => \%preview_thread) $t->post_ok('/human/thread/post', form => \%preview_thread)
->status_is(200) ->status_is(200)
->text_like(p => qr/ayy\.\.\. lmao/); ->text_like(p => qr/ayy\.\.\. lmao/);

10
t/redirect_old_path.t Normal file
View File

@ -0,0 +1,10 @@
use Mojo::Base -strict;
use Test::More;
use Test::Mojo;
my $t = Test::Mojo->new('PostText');
$t->get_ok('/thread/post')->status_is(302)
->header_like(Location => qr{human/thread/post});
done_testing;

View File

@ -8,12 +8,23 @@ my %good_human = (answer => 1, number => '');
my $search_url = my $search_url =
'/captcha/H4sIABJ8PGUAA8soKSmw0tfPyU9OzMnILy6xMjYwMNDPKM1NzNMvTk0sSs4AAPrUR3kiAAAA%0A'; '/captcha/H4sIABJ8PGUAA8soKSmw0tfPyU9OzMnILy6xMjYwMNDPKM1NzNMvTk0sSs4AAPrUR3kiAAAA%0A';
subtest 'Search form', sub {
$t->get_ok('/thread/list')
->element_exists('form input[name="q"]' )
->element_exists('form button[type="submit"]');
};
subtest 'Search before CAPTCHA', sub { subtest 'Search before CAPTCHA', sub {
$t->get_ok('/human/search')->status_is(302) $t->get_ok('/human/search')->status_is(302)
->header_like(Location => qr/captcha/); ->header_like(Location => qr/captcha/);
}; };
subtest 'Search after CAPTCHA', sub { subtest 'Search after CAPTCHA', sub {
$t->get_ok($search_url);
$good_human{'csrf_token'} =
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
$t->post_ok($search_url, form => \%good_human) $t->post_ok($search_url, form => \%good_human)
->status_is(302) ->status_is(302)
->header_like(Location => qr{human/search}); ->header_like(Location => qr{human/search});

View File

@ -18,5 +18,6 @@
<%= label_for password => 'Password' %> <%= label_for password => 'Password' %>
<%= password_field password => (id => 'password') %> <%= password_field password => (id => 'password') %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Reset</button> <button type="submit" class="form-button">Reset</button>
</form> </form>

View File

@ -26,5 +26,6 @@
<%= label_for password => 'Password' %> <%= label_for password => 'Password' %>
<%= password_field password => (id => 'password') %> <%= password_field password => (id => 'password') %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Create</button> <button type="submit" class="form-button">Create</button>
</form> </form>

View File

@ -10,5 +10,6 @@
<%= label_for email => 'Email' %> <%= label_for email => 'Email' %>
<%= email_field email => (id => 'email', autofocus => undef) %> <%= email_field email => (id => 'email', autofocus => undef) %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Demote</button> <button type="submit" class="form-button">Demote</button>
</form> </form>

View File

@ -10,5 +10,6 @@
<%= label_for email => 'Email' %> <%= label_for email => 'Email' %>
<%= email_field email => (id => 'email', autofocus => undef) %> <%= email_field email => (id => 'email', autofocus => undef) %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Lock</button> <button type="submit" class="form-button">Lock</button>
</form> </form>

View File

@ -12,11 +12,12 @@
</div> </div>
<div class="form-field"> <div class="form-field">
<% if (my $error = validation->error('password')) { =%> <% if (my $error = validation->error('password')) { =%>
<p class="field-with-error">Must be between <%= $error->[2] %> <p class="field-with-error">Must be atleast <%= $error->[2] %>
and <%= $error->[3] %> characters.</p> characters.</p>
<% } =%> <% } =%>
<%= label_for password => 'Password' %> <%= label_for password => 'Password' %>
<%= password_field password => (id => 'password') %> <%= password_field password => (id => 'password') %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Login</button> <button type="submit" class="form-button">Login</button>
</form> </form>

View File

@ -10,6 +10,7 @@
<%= label_for password => 'Password' %> <%= label_for password => 'Password' %>
<%= password_field password => (id => 'password', autofocus => undef) %> <%= password_field password => (id => 'password', autofocus => undef) %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Reset</button> <button type="submit" class="form-button">Reset</button>
</form> </form>

View File

@ -10,5 +10,6 @@
<%= label_for email => 'Email' %> <%= label_for email => 'Email' %>
<%= email_field email => (id => 'email', autofocus => undef) %> <%= email_field email => (id => 'email', autofocus => undef) %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Promote</button> <button type="submit" class="form-button">Promote</button>
</form> </form>

View File

@ -10,5 +10,6 @@
<%= label_for email => 'Email' %> <%= label_for email => 'Email' %>
<%= email_field email => (id => 'email', autofocus => undef) %> <%= email_field email => (id => 'email', autofocus => undef) %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Unlock</button> <button type="submit" class="form-button">Unlock</button>
</form> </form>

View File

@ -26,5 +26,6 @@
) %> ) %>
</div> </div>
<%= hidden_field number => $roman_numeral, id => 'number' %> <%= hidden_field number => $roman_numeral, id => 'number' %>
<%= csrf_field %>
<button type="submit" class="form-button">Answer</button> <button type="submit" class="form-button">Answer</button>
</form> </form>

View File

@ -55,6 +55,7 @@
<%= check_box preview => 1, id => 'preview' %> <%= check_box preview => 1, id => 'preview' %>
<%= label_for preview => 'Preview' %> <%= label_for preview => 'Preview' %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Post</button> <button type="submit" class="form-button">Post</button>
</form> </form>
<%# Putting this first above the thread body (nested if, yucky sry) %> <%# Putting this first above the thread body (nested if, yucky sry) %>

View File

@ -61,5 +61,6 @@
<%= check_box preview => 1, id => 'preview' %> <%= check_box preview => 1, id => 'preview' %>
<%= label_for preview => 'Preview' %> <%= label_for preview => 'Preview' %>
</div> </div>
<%= csrf_field %>
<button type="submit" class="form-button">Post</button> <button type="submit" class="form-button">Post</button>
</form> </form>