Compare commits
No commits in common. "main" and "slapbird" have entirely different histories.
@ -1,10 +1,11 @@
|
||||
FROM docker.io/perl:5.40
|
||||
FROM docker.io/perl:5.36
|
||||
|
||||
# Move it
|
||||
WORKDIR /opt
|
||||
COPY lib/ ./lib/
|
||||
COPY migrations/ ./migrations/
|
||||
COPY public/ ./public/
|
||||
COPY t/ ./t/
|
||||
COPY templates/ ./templates/
|
||||
COPY script/ ./script/
|
||||
COPY cpanfile .
|
||||
|
@ -61,7 +61,7 @@ tests locally:
|
||||
|
||||
## TODOs
|
||||
|
||||
- Do I need `SUM` for `by_id()`?
|
||||
- Tripcodes/PGP signing somehow perhaps...
|
||||
|
||||
## AGPL-3.0+ANTIFA compliance
|
||||
|
||||
|
2
cpanfile
2
cpanfile
@ -7,4 +7,4 @@ requires 'XML::RSS';
|
||||
requires 'Text::Markdown';
|
||||
requires 'HTML::Restrict';
|
||||
requires 'Roman::Unicode';
|
||||
requires 'SlapbirdAPM::Agent::Mojo', '>= 0.012';
|
||||
requires 'SlapbirdAPM::Agent::Mojo';
|
||||
|
@ -4,10 +4,7 @@
|
||||
remarks_per_page => 5,
|
||||
results_per_page => 5,
|
||||
body_max_length => 8_000,
|
||||
version => 'Feb 11 2025',
|
||||
secrets => ['t0p_s3cr3t'],
|
||||
version => 'cool version string here',
|
||||
slapbirdapm_api_key => 'AyyLmao39b4eb99de26d437633e49555',
|
||||
development => {
|
||||
pg_string =>
|
||||
'postgresql://post_text:t0p_s3cr3t@127.0.0.1/post_text'
|
||||
|
@ -36,8 +36,6 @@ sub startup($self) {
|
||||
|
||||
$self->helper(hr => sub ($c) {
|
||||
state $hr = HTML::Restrict->new(
|
||||
# filter_text breaks greater and less than symbols in Markdown code blocks
|
||||
# Also breaks Markdown quote blocks
|
||||
filter_text => 0,
|
||||
strip_enclosed_content => [],
|
||||
rules => {
|
||||
@ -97,7 +95,7 @@ sub startup($self) {
|
||||
# Finish configuring some things
|
||||
$self->secrets($self->config->{'secrets'}) || die $@;
|
||||
|
||||
$self->pg->migrations->from_dir('migrations')->migrate(16);
|
||||
$self->pg->migrations->from_dir('migrations')->migrate(15);
|
||||
|
||||
if (my $threads_per_page = $self->config->{'threads_per_page'}) {
|
||||
$self->thread->per_page($threads_per_page)
|
||||
@ -146,14 +144,7 @@ sub startup($self) {
|
||||
$c->session(expires => 1);
|
||||
|
||||
$c->redirect_to('threads_list');
|
||||
})->name('new_session');
|
||||
|
||||
# Hide a version string to check build later
|
||||
if (my $version = $self->config->{'version'}) {
|
||||
$r->get('/version', sub ($c) {
|
||||
$c->render(text => $version . "\n")
|
||||
})->name('version_string');
|
||||
}
|
||||
});
|
||||
|
||||
# Static pages
|
||||
$r->get('/about')->to('page#about')->name('about_page');
|
||||
@ -197,11 +188,6 @@ sub startup($self) {
|
||||
->to('thread#flag')
|
||||
->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')
|
||||
->to('thread#create')
|
||||
->name('post_thread');
|
||||
|
@ -39,15 +39,8 @@ sub login($self) {
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('email' )->size(6, 320);
|
||||
$v->required('password')->size(12, undef);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
);
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -160,15 +153,8 @@ sub create($self) {
|
||||
$v->required('name' )->size(1, 64);
|
||||
$v->required('email' )->size(6, 320);
|
||||
$v->required('password')->size(12, undef);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -192,15 +178,8 @@ sub admin_reset($self) {
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('email' )->size(6, 320);
|
||||
$v->required('password')->size(12, undef);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -222,15 +201,8 @@ sub mod_reset($self) {
|
||||
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('password')->size(12, undef);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -254,15 +226,8 @@ sub lock_acct($self) {
|
||||
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('email')->size(6, 320);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -283,15 +248,8 @@ sub unlock_acct($self) {
|
||||
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('email')->size(6, 320);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -312,15 +270,8 @@ sub promote($self) {
|
||||
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('email')->size(6, 320);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -341,15 +292,8 @@ sub demote($self) {
|
||||
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('email')->size(6, 320);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
|
@ -20,15 +20,8 @@ sub captcha($self) {
|
||||
if ($v && $v->has_data) {
|
||||
$v->required('answer')->num(1, 9);
|
||||
$v->required('number')->size(1, 4);
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
|
@ -36,16 +36,8 @@ sub create($self) {
|
||||
$v->required('body' )->size(2, $body_limit);
|
||||
$v->optional('bump' );
|
||||
$v->optional('preview');
|
||||
$v->optional('markdown');
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
)
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -53,7 +45,6 @@ sub create($self) {
|
||||
my $remark_body = $v->param('body' );
|
||||
my $bump_thread = $v->param('bump' );
|
||||
my $preview = $v->param('preview');
|
||||
my $markdown = $v->param('markdown');
|
||||
|
||||
$self->session(author => $remark_author);
|
||||
|
||||
@ -61,8 +52,7 @@ sub create($self) {
|
||||
$self->remark->create(
|
||||
$thread_id,
|
||||
$remark_author,
|
||||
$remark_body,
|
||||
$markdown
|
||||
$remark_body
|
||||
);
|
||||
|
||||
$self->thread->bump($thread_id) if $bump_thread;
|
||||
@ -73,7 +63,7 @@ sub create($self) {
|
||||
})->fragment('remarks'));
|
||||
}
|
||||
|
||||
$draft = {body => $remark_body, markdown => $markdown};
|
||||
$draft = $remark_body;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,16 +15,8 @@ sub create($self) {
|
||||
$v->required('title' )->size(1, 127);
|
||||
$v->required('body' )->size(2, $body_limit);
|
||||
$v->optional('preview');
|
||||
$v->optional('markdown');
|
||||
$v->csrf_protect;
|
||||
|
||||
if ($v->has_error('csrf_token')) {
|
||||
$self->stash(
|
||||
status => 403,
|
||||
error => 'Something went wrong, please try again. 🥺'
|
||||
);
|
||||
}
|
||||
elsif ($v->has_error) {
|
||||
if ($v->has_error) {
|
||||
$self->stash(status => 400)
|
||||
}
|
||||
else {
|
||||
@ -32,7 +24,6 @@ sub create($self) {
|
||||
my $thread_title = $v->param('title' );
|
||||
my $thread_body = $v->param('body' );
|
||||
my $preview = $v->param('preview');
|
||||
my $markdown = $v->param('markdown');
|
||||
|
||||
$self->session(author => $thread_author);
|
||||
|
||||
@ -40,8 +31,7 @@ sub create($self) {
|
||||
my $new_thread_id = $self->thread->create(
|
||||
$thread_author,
|
||||
$thread_title,
|
||||
$thread_body,
|
||||
$markdown
|
||||
$thread_body
|
||||
);
|
||||
|
||||
return $self->redirect_to(
|
||||
@ -49,7 +39,7 @@ sub create($self) {
|
||||
);
|
||||
}
|
||||
|
||||
$draft = {body => $thread_body, markdown => $markdown};
|
||||
$draft = $thread_body;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,8 +156,7 @@ sub flagged($self) {
|
||||
SELECT 'remark',
|
||||
remark_id
|
||||
FROM remarks
|
||||
WHERE flagged_status
|
||||
ORDER BY id DESC;
|
||||
WHERE flagged_status;
|
||||
END_SQL
|
||||
}
|
||||
|
||||
@ -171,8 +170,7 @@ sub hidden($self) {
|
||||
SELECT 'remark',
|
||||
remark_id
|
||||
FROM remarks
|
||||
WHERE hidden_status
|
||||
ORDER BY id DESC;
|
||||
WHERE hidden_status;
|
||||
END_SQL
|
||||
}
|
||||
|
||||
@ -238,8 +236,7 @@ sub thread_by_id($self, $thread_id) {
|
||||
t.thread_title AS title,
|
||||
t.thread_body AS body,
|
||||
COUNT(r.*) AS remark_tally,
|
||||
t.bump_tally AS bump_tally,
|
||||
t.markdown_status AS markdown
|
||||
t.bump_tally AS bump_tally
|
||||
FROM threads AS t
|
||||
LEFT JOIN remarks AS r
|
||||
ON t.thread_id = r.thread_id
|
||||
@ -256,8 +253,7 @@ sub remark_by_id($self, $remark_id) {
|
||||
TO_CHAR(remark_date, ?) AS date,
|
||||
remark_author AS author,
|
||||
remark_body AS body,
|
||||
thread_id,
|
||||
markdown_status AS markdown
|
||||
thread_id
|
||||
FROM remarks
|
||||
WHERE remark_id = ?;
|
||||
END_SQL
|
||||
@ -274,8 +270,7 @@ sub list($self) {
|
||||
TO_CHAR(last_login_date, $1) AS last_login_date,
|
||||
lock_status,
|
||||
admin_status
|
||||
FROM moderators
|
||||
ORDER BY last_login_date DESC;
|
||||
FROM moderators;
|
||||
END_SQL
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,7 @@ sub by_page_for($self, $thread_id, $this_page = 1) {
|
||||
SELECT remark_id AS id,
|
||||
TO_CHAR(remark_date, ?) AS date,
|
||||
remark_author AS author,
|
||||
remark_body AS body,
|
||||
markdown_status AS markdown
|
||||
remark_body AS body
|
||||
FROM remarks
|
||||
WHERE thread_id = ?
|
||||
AND NOT hidden_status
|
||||
@ -28,25 +27,9 @@ sub by_page_for($self, $thread_id, $this_page = 1) {
|
||||
END_SQL
|
||||
}
|
||||
|
||||
sub create(
|
||||
$self,
|
||||
$thread_id,
|
||||
$author,
|
||||
$body,
|
||||
$markdown //= 0,
|
||||
$hidden = 0,
|
||||
$flagged = 0
|
||||
)
|
||||
{
|
||||
sub create($self, $thread_id, $author, $body, $hidden = 0, $flagged = 0) {
|
||||
my $clean_body = $self->hr->process($body);
|
||||
my @data = (
|
||||
$thread_id,
|
||||
$author,
|
||||
$clean_body,
|
||||
$hidden,
|
||||
$flagged,
|
||||
$markdown
|
||||
);
|
||||
my @data = ($thread_id, $author, $clean_body, $hidden, $flagged);
|
||||
|
||||
$self->pg->db->query(<<~'END_SQL', @data);
|
||||
INSERT INTO remarks (
|
||||
@ -54,10 +37,9 @@ sub create(
|
||||
remark_author,
|
||||
remark_body,
|
||||
hidden_status,
|
||||
flagged_status,
|
||||
markdown_status
|
||||
flagged_status
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?);
|
||||
VALUES (?, ?, ?, ?, ?);
|
||||
END_SQL
|
||||
}
|
||||
|
||||
@ -87,8 +69,7 @@ sub last_for($self, $thread_id) {
|
||||
SELECT remark_id AS id,
|
||||
TO_CHAR(remark_date, ?) AS date,
|
||||
remark_author AS author,
|
||||
remark_body AS body,
|
||||
markdown_status AS markdown
|
||||
remark_body AS body
|
||||
FROM remarks
|
||||
WHERE thread_id = ?
|
||||
ORDER BY remark_date
|
||||
@ -104,8 +85,7 @@ sub by_id($self, $remark_id) {
|
||||
TO_CHAR(remark_date, ?) AS date,
|
||||
remark_author AS author,
|
||||
remark_body AS body,
|
||||
thread_id,
|
||||
markdown_status AS markdown
|
||||
thread_id
|
||||
FROM remarks
|
||||
WHERE remark_id = ?
|
||||
AND NOT hidden_status;
|
||||
@ -142,8 +122,7 @@ sub feed($self) {
|
||||
$self->pg->db->query(<<~'END_SQL', $date_format)->hashes;
|
||||
SELECT remark_id AS id,
|
||||
TO_CHAR(remark_date, ?) AS date,
|
||||
remark_body AS body,
|
||||
markdown_status AS markdown
|
||||
remark_body AS body
|
||||
FROM remarks
|
||||
WHERE NOT hidden_status
|
||||
GROUP BY remark_id
|
||||
|
@ -8,25 +8,9 @@ has per_page => 5;
|
||||
|
||||
has date_format => 'Dy, FMDD Mon YYYY HH24:MI:SS TZHTZM';
|
||||
|
||||
sub create(
|
||||
$self,
|
||||
$author,
|
||||
$title,
|
||||
$body,
|
||||
$markdown //= 0,
|
||||
$hidden = 0,
|
||||
$flagged = 0
|
||||
)
|
||||
{
|
||||
sub create($self, $author, $title, $body, $hidden = 0, $flagged = 0) {
|
||||
my $clean_body = $self->hr->process($body);
|
||||
my @data = (
|
||||
$author,
|
||||
$title,
|
||||
$clean_body,
|
||||
$hidden,
|
||||
$flagged,
|
||||
$markdown
|
||||
);
|
||||
my @data = ($author, $title, $clean_body, $hidden, $flagged);
|
||||
|
||||
$self->pg->db->query(<<~'END_SQL', @data)->hash->{'thread_id'};
|
||||
INSERT INTO threads (
|
||||
@ -34,10 +18,9 @@ sub create(
|
||||
thread_title,
|
||||
thread_body,
|
||||
hidden_status,
|
||||
flagged_status,
|
||||
markdown_status
|
||||
flagged_status
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
RETURNING thread_id;
|
||||
END_SQL
|
||||
# The indented heredoc got a little confused by this one...
|
||||
@ -60,8 +43,7 @@ sub by_page($self, $this_page = 1) {
|
||||
THEN 1
|
||||
ELSE 0
|
||||
END) AS remark_tally,
|
||||
t.bump_tally AS bump_tally,
|
||||
t.markdown_status AS markdown
|
||||
t.bump_tally AS bump_tally
|
||||
FROM threads AS t
|
||||
LEFT JOIN remarks AS r
|
||||
ON t.thread_id = r.thread_id
|
||||
@ -105,8 +87,7 @@ sub by_id($self, $thread_id) {
|
||||
t.thread_title AS title,
|
||||
t.thread_body AS body,
|
||||
COUNT(r.*) AS remark_tally,
|
||||
t.bump_tally AS bump_tally,
|
||||
t.markdown_status AS markdown
|
||||
t.bump_tally AS bump_tally
|
||||
FROM threads AS t
|
||||
LEFT JOIN remarks AS r
|
||||
ON t.thread_id = r.thread_id
|
||||
@ -140,8 +121,7 @@ sub feed($self) {
|
||||
SELECT thread_id AS id,
|
||||
TO_CHAR(thread_date, ?) AS date,
|
||||
thread_title AS title,
|
||||
thread_body AS body,
|
||||
markdown_status AS markdown
|
||||
thread_body AS body
|
||||
FROM threads
|
||||
WHERE NOT hidden_status
|
||||
GROUP BY thread_id
|
||||
|
@ -1,5 +0,0 @@
|
||||
ALTER TABLE threads
|
||||
DROP COLUMN markdown_status;
|
||||
|
||||
ALTER TABLE remarks
|
||||
DROP COLUMN markdown_status;
|
@ -1,22 +0,0 @@
|
||||
ALTER TABLE threads
|
||||
ADD COLUMN markdown_status BOOLEAN;
|
||||
|
||||
-- Since Markdown was default, set existing threads to true
|
||||
UPDATE threads
|
||||
SET markdown_status = TRUE;
|
||||
|
||||
-- Now we can make it NOT NULL
|
||||
ALTER TABLE threads
|
||||
ALTER COLUMN markdown_status
|
||||
SET NOT NULL;
|
||||
|
||||
-- Do the same for remarks
|
||||
ALTER TABLE remarks
|
||||
ADD COLUMN markdown_status BOOLEAN;
|
||||
|
||||
UPDATE remarks
|
||||
SET markdown_status = TRUE;
|
||||
|
||||
ALTER TABLE remarks
|
||||
ALTER COLUMN markdown_status
|
||||
SET NOT NULL;
|
@ -27,7 +27,6 @@
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: black;
|
||||
background-image: url('/images/background_stars_anm.gif');
|
||||
width: 95vmin;
|
||||
margin: 0 auto;
|
||||
@ -74,6 +73,7 @@ table { width: 100%; }
|
||||
|
||||
table, th, td {
|
||||
border-collapse: collapse;
|
||||
border: 0.15em dotted black;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -130,9 +130,3 @@
|
||||
padding: 1em;
|
||||
background-color: var(--transparent);
|
||||
}
|
||||
|
||||
.plain-text {
|
||||
white-space: pre-wrap;
|
||||
display: inline-block;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
(function () {
|
||||
const bodyStyle = document.body.style;
|
||||
|
||||
function setImage(url) {
|
||||
document.body.style.backgroundImage = "url('" + url + "')";
|
||||
bodyStyle.backgroundImage = "url('" + url + "')";
|
||||
}
|
||||
|
||||
switch (new Date().getMonth()) {
|
||||
|
@ -3,7 +3,8 @@
|
||||
# PostText v0.1
|
||||
# Jul 22 2022
|
||||
|
||||
use v5.40;
|
||||
use v5.36;
|
||||
#no warnings 'experimental';
|
||||
use Mojo::File qw{curfile};
|
||||
use lib curfile->dirname->sibling('lib')->to_string;
|
||||
use Mojolicious::Commands;
|
||||
|
11
t/admin.t
11
t/admin.t
@ -10,11 +10,6 @@ my %valid_login = (
|
||||
);
|
||||
|
||||
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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{moderator/flagged});
|
||||
@ -39,7 +34,6 @@ subtest Login => sub {
|
||||
->element_exists('form input[name="name"]' )
|
||||
->element_exists('form input[name="email"]' )
|
||||
->element_exists('form input[name="password"]')
|
||||
->element_exists('form input[name="csrf_token"]')
|
||||
};
|
||||
|
||||
subtest Reset => sub {
|
||||
@ -49,7 +43,6 @@ subtest Login => sub {
|
||||
->element_exists('a[href*="/moderator/admin/reset"]')
|
||||
->element_exists('form input[name="email"]' )
|
||||
->element_exists('form input[name="password"]' )
|
||||
->element_exists('form input[name="csrf_token"]' )
|
||||
};
|
||||
|
||||
subtest Lock => sub {
|
||||
@ -58,7 +51,6 @@ subtest Login => sub {
|
||||
->text_like(h2 => qr/Lock Account/)
|
||||
->element_exists('a[href*="/moderator/admin/lock"]')
|
||||
->element_exists('form input[name="email"]' )
|
||||
->element_exists('form input[name="csrf_token"]' )
|
||||
};
|
||||
|
||||
subtest Unlock => sub {
|
||||
@ -67,7 +59,6 @@ subtest Login => sub {
|
||||
->text_like(h2 => qr/Unlock Account/)
|
||||
->element_exists('a[href*="/moderator/admin/unlock"]')
|
||||
->element_exists('form input[name="email"]' )
|
||||
->element_exists('form input[name="csrf_token"]' )
|
||||
};
|
||||
|
||||
subtest Promote => sub {
|
||||
@ -76,7 +67,6 @@ subtest Login => sub {
|
||||
->text_like(h2 => qr/Promote Moderator/)
|
||||
->element_exists('a[href*="/moderator/admin/promote"]')
|
||||
->element_exists('form input[name="email"]' )
|
||||
->element_exists('form input[name="csrf_token"]' )
|
||||
};
|
||||
|
||||
subtest Demote => sub {
|
||||
@ -85,7 +75,6 @@ subtest Login => sub {
|
||||
->text_like(h2 => qr/Demote Admin/)
|
||||
->element_exists('a[href*="/moderator/admin/demote"]')
|
||||
->element_exists('form input[name="email"]' )
|
||||
->element_exists('form input[name="csrf_token"]' )
|
||||
};
|
||||
|
||||
# Admin session ends
|
||||
|
55
t/human.t
55
t/human.t
@ -25,39 +25,18 @@ subtest 'Bumping thread', sub {
|
||||
$t->get_ok('/human/thread/bump/1')->status_is(302)
|
||||
->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_bot{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok($bump_thread_url, form => \%bad_bot)
|
||||
->status_is(400)
|
||||
->element_exists('p[class="stash-with-error"]')
|
||||
->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)
|
||||
->status_is(400)
|
||||
->element_exists('p[class="field-with-error"]')
|
||||
->text_like(p => qr/Should be a single number/);
|
||||
|
||||
# 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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/thread/bump/1});
|
||||
@ -77,35 +56,18 @@ subtest 'Flagging thread', sub {
|
||||
$t->get_ok('/human/thread/flag/1')->status_is(302)
|
||||
->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_bot{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok($flag_thread_url, form => \%bad_bot)
|
||||
->status_is(400)
|
||||
->element_exists('p[class="stash-with-error"]')
|
||||
->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)
|
||||
->status_is(400)
|
||||
->element_exists('p[class="field-with-error"]')
|
||||
->text_like(p => qr/Should be a single number/);
|
||||
|
||||
# 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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/thread/flag/1});
|
||||
@ -121,35 +83,18 @@ subtest 'Flagging remark', sub {
|
||||
$t->get_ok('/human/remark/flag/1')->status_is(302)
|
||||
->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_bot{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok($flag_remark_url, form => \%bad_bot)
|
||||
->status_is(400)
|
||||
->element_exists('p[class="stash-with-error"]')
|
||||
->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)
|
||||
->status_is(400)
|
||||
->element_exists('p[class="field-with-error"]')
|
||||
->text_like(p => qr/Should be a single number/);
|
||||
|
||||
# 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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/remark/flag/1});
|
||||
|
98
t/markdown.t
98
t/markdown.t
@ -1,98 +0,0 @@
|
||||
use Mojo::Base -strict;
|
||||
use Test::More;
|
||||
use Test::Mojo;
|
||||
|
||||
my $t = Test::Mojo->new('PostText');
|
||||
|
||||
# For CAPTCHA
|
||||
my %good_captcha = (answer => 1, number => 'Ⅰ');
|
||||
my $bump_thread_url =
|
||||
'/captcha/H4sIAImTzmQAA8soKSmw0tfPyU9OzMnILy6xMjYwMNDPKM1NzNMvyShKTUzRTyrNLdA3BAD5ek7T%0AKQAAAA==%0A';
|
||||
|
||||
my %markdown_thread = (
|
||||
author => 'Anonymous',
|
||||
title => 'hi',
|
||||
body => '# ayy... lmao',
|
||||
preview => 1,
|
||||
markdown => 1
|
||||
);
|
||||
|
||||
my %markdown_remark = (
|
||||
author => 'Anonymous',
|
||||
body => '# ayy... lmao',
|
||||
preview => 1,
|
||||
markdown => 1
|
||||
);
|
||||
|
||||
my %plain_text_thread = (
|
||||
author => 'Anonymous',
|
||||
title => 'hi',
|
||||
body => '# ayy... lmao',
|
||||
preview => 1
|
||||
);
|
||||
|
||||
my %plain_text_remark = (
|
||||
author => 'Anonymous',
|
||||
body => '# ayy... lmao',
|
||||
preview => 1
|
||||
);
|
||||
|
||||
# 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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/thread/bump/1});
|
||||
|
||||
subtest 'Check the form + button', sub {
|
||||
$t->get_ok('/human/remark/post/1')->status_is(200)
|
||||
->element_exists('input[id="markdown"]');
|
||||
|
||||
$t->get_ok('/human/thread/post')->status_is(200)
|
||||
->element_exists('input[id="markdown"]');
|
||||
};
|
||||
|
||||
subtest 'Submit markdown input', sub {
|
||||
$t->get_ok('/human/remark/post/1');
|
||||
|
||||
$markdown_remark{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok('/human/remark/post/1', form => \%markdown_remark)
|
||||
->status_is(200)
|
||||
->text_like('div.form-preview h1', qr/ayy\.\.\. lmao/);
|
||||
|
||||
$t->get_ok('/human/thread/post');
|
||||
|
||||
$markdown_thread{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok('/human/thread/post', form => \%markdown_thread)
|
||||
->status_is(200)
|
||||
->text_like('div.form-preview h1', qr/ayy\.\.\. lmao/);
|
||||
};
|
||||
|
||||
subtest 'Submit plain text input', sub {
|
||||
$t->get_ok('/human/remark/post/1');
|
||||
|
||||
$plain_text_remark{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok('/human/remark/post/1', form => \%plain_text_remark)
|
||||
->status_is(200)
|
||||
->text_like('span.plain-text', qr/# ayy\.\.\. lmao/);
|
||||
|
||||
$t->get_ok('/human/thread/post');
|
||||
|
||||
$plain_text_thread{'csrf_token'} =
|
||||
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||
|
||||
$t->post_ok('/human/thread/post', form => \%plain_text_thread)
|
||||
->status_is(200)
|
||||
->text_like('span.plain-text', qr/# ayy\.\.\. lmao/);
|
||||
};
|
||||
|
||||
done_testing;
|
@ -19,26 +19,14 @@ subtest Login => sub {
|
||||
->status_is(200)
|
||||
->element_exists('form input[name="email"]')
|
||||
->element_exists('form input[name="password"]')
|
||||
->element_exists('form input[name="csrf_token"]')
|
||||
->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)
|
||||
->status_is(403)
|
||||
->element_exists('form input[name="email"]')
|
||||
->element_exists('form input[name="password"]')
|
||||
->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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{moderator/flagged});
|
||||
@ -87,13 +75,13 @@ subtest Login => sub {
|
||||
};
|
||||
|
||||
subtest 'Buttons for mods', sub {
|
||||
$t->get_ok('/moderator/thread/single/1')
|
||||
$t->get_ok('/thread/single/1')
|
||||
->status_is(200)
|
||||
->element_exists('a[href*="/hide/1"]' )
|
||||
->element_exists('a[href*="/unhide/1"]')
|
||||
->element_exists('a[href*="/unflag/1"]');
|
||||
|
||||
$t->get_ok('/moderator/remark/single/1')
|
||||
$t->get_ok('/remark/single/1')
|
||||
->status_is(200)
|
||||
->element_exists('a[href*="/hide/1"]' )
|
||||
->element_exists('a[href*="/unhide/1"]')
|
||||
|
35
t/post.t
35
t/post.t
@ -44,11 +44,6 @@ $t->get_ok('/human/remark/post/1')->status_is(302)
|
||||
->header_like(Location => qr/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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/thread/bump/1});
|
||||
@ -62,7 +57,6 @@ subtest 'Post new thread', sub {
|
||||
->element_exists('form input[name="title"]' )
|
||||
->element_exists('form textarea[name="body"]')
|
||||
->element_exists('form button[type="submit"]' )
|
||||
->element_exists('form input[name="csrf_token"]')
|
||||
->text_like(h2 => qr/New Thread/);
|
||||
|
||||
# POST
|
||||
@ -73,28 +67,14 @@ subtest 'Post new thread', sub {
|
||||
->element_exists('form button[type="submit"]' )
|
||||
->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)
|
||||
->status_is(400)
|
||||
->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)
|
||||
->status_is(400)
|
||||
->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)
|
||||
->status_is(200)
|
||||
->text_like(h2 => qr/Thread #\d+/);
|
||||
@ -124,25 +104,10 @@ subtest 'Post new remark', sub {
|
||||
->element_exists('form button[type="submit"]' )
|
||||
->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)
|
||||
->status_is(200)
|
||||
->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)
|
||||
->status_is(400)
|
||||
->text_like(p => qr/Must be between/);
|
||||
|
21
t/preview.t
21
t/preview.t
@ -13,23 +13,16 @@ my %preview_thread = (
|
||||
author => 'Anonymous',
|
||||
title => 'hi',
|
||||
body => 'ayy... lmao',
|
||||
preview => 1,
|
||||
markdown => 1
|
||||
preview => 1
|
||||
);
|
||||
|
||||
my %preview_remark = (
|
||||
author => 'Anonymous',
|
||||
body => 'ayy... lmao',
|
||||
preview => 1,
|
||||
markdown => 1
|
||||
preview => 1
|
||||
);
|
||||
|
||||
# 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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/thread/bump/1});
|
||||
@ -43,20 +36,10 @@ subtest 'Check the form + button', 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)
|
||||
->status_is(200)
|
||||
->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)
|
||||
->status_is(200)
|
||||
->text_like(p => qr/ayy\.\.\. lmao/);
|
||||
|
@ -1,10 +0,0 @@
|
||||
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;
|
11
t/search.t
11
t/search.t
@ -8,23 +8,12 @@ my %good_human = (answer => 1, number => 'Ⅰ');
|
||||
my $search_url =
|
||||
'/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 {
|
||||
$t->get_ok('/human/search')->status_is(302)
|
||||
->header_like(Location => qr/captcha/);
|
||||
};
|
||||
|
||||
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)
|
||||
->status_is(302)
|
||||
->header_like(Location => qr{human/search});
|
||||
|
@ -93,9 +93,6 @@
|
||||
<%= content =%>
|
||||
<footer class="site-footer">
|
||||
<p>In UTF-8 we trust. 🫡</p>
|
||||
<p><%= link_to new_session => begin %>
|
||||
New Session/Identity
|
||||
<% end %></p>
|
||||
<p><%= link_to javascript_page =>
|
||||
('data-jslicense', 1),
|
||||
begin %>JavaScript License Information<% end %></p>
|
||||
|
@ -18,6 +18,5 @@
|
||||
<%= label_for password => 'Password' %>
|
||||
<%= password_field password => (id => 'password') %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Reset</button>
|
||||
</form>
|
||||
|
@ -26,6 +26,5 @@
|
||||
<%= label_for password => 'Password' %>
|
||||
<%= password_field password => (id => 'password') %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Create</button>
|
||||
</form>
|
||||
|
@ -10,6 +10,5 @@
|
||||
<%= label_for email => 'Email' %>
|
||||
<%= email_field email => (id => 'email', autofocus => undef) %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Demote</button>
|
||||
</form>
|
||||
|
@ -10,6 +10,5 @@
|
||||
<%= label_for email => 'Email' %>
|
||||
<%= email_field email => (id => 'email', autofocus => undef) %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Lock</button>
|
||||
</form>
|
||||
|
@ -12,12 +12,11 @@
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<% if (my $error = validation->error('password')) { =%>
|
||||
<p class="field-with-error">Must be atleast <%= $error->[2] %>
|
||||
characters.</p>
|
||||
<p class="field-with-error">Must be between <%= $error->[2] %>
|
||||
and <%= $error->[3] %> characters.</p>
|
||||
<% } =%>
|
||||
<%= label_for password => 'Password' %>
|
||||
<%= password_field password => (id => 'password') %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Login</button>
|
||||
</form>
|
||||
|
@ -10,7 +10,6 @@
|
||||
<%= label_for password => 'Password' %>
|
||||
<%= password_field password => (id => 'password', autofocus => undef) %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Reset</button>
|
||||
</form>
|
||||
|
||||
|
@ -10,6 +10,5 @@
|
||||
<%= label_for email => 'Email' %>
|
||||
<%= email_field email => (id => 'email', autofocus => undef) %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Promote</button>
|
||||
</form>
|
||||
|
@ -10,12 +10,17 @@
|
||||
</h4>
|
||||
<h5 class="post__author"><%= $remark->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($remark->{'markdown'}) { =%>
|
||||
<%== markdown $remark->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $remark->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Thread => single_thread =>
|
||||
{thread_id => $remark->{'thread_id'}}, (class => 'click') %>
|
||||
<%= link_to Remark => post_remark =>
|
||||
{thread_id => $remark->{'thread_id'}}, (class => 'click') %>
|
||||
<%= link_to Flag => flag_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% if (is_mod) { =%>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Hide => hide_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
@ -24,6 +29,7 @@
|
||||
<%= link_to Unflag => unflag_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% } =%>
|
||||
</article>
|
||||
</main>
|
||||
<% } =%>
|
||||
|
@ -11,12 +11,21 @@
|
||||
<h4 class="post__date"><%= $thread->{'date'} %></h4>
|
||||
<h5 class="post__author"><%= $thread->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($thread->{'markdown'}) { =%>
|
||||
<%== markdown $thread->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $thread->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to post_remark => {thread_id => $thread->{'id'}},
|
||||
(class => 'click'), begin %>
|
||||
Remark (<%= $thread->{'remark_tally'} %>)
|
||||
<% end %>
|
||||
<%= link_to bump_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click'), begin %>
|
||||
Bump (<%= $thread->{'bump_tally'} %>)
|
||||
<% end %>
|
||||
<%= link_to Flag => flag_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% if (is_mod) { =%>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Hide => hide_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
@ -25,6 +34,7 @@
|
||||
<%= link_to Unflag => unflag_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% } =%>
|
||||
</article>
|
||||
</main>
|
||||
<% } =%>
|
||||
|
@ -10,6 +10,5 @@
|
||||
<%= label_for email => 'Email' %>
|
||||
<%= email_field email => (id => 'email', autofocus => undef) %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Unlock</button>
|
||||
</form>
|
||||
|
@ -26,6 +26,5 @@
|
||||
) %>
|
||||
</div>
|
||||
<%= hidden_field number => $roman_numeral, id => 'number' %>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Answer</button>
|
||||
</form>
|
||||
|
@ -25,11 +25,7 @@
|
||||
</h4>
|
||||
<h5 class="post__author"><%= $remark->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($remark->{'markdown'}) { =%>
|
||||
<%== markdown $remark->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $remark->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Thread => single_thread =>
|
||||
@ -40,6 +36,16 @@
|
||||
<%= link_to Flag => flag_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% if (is_mod) { =%>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Hide => hide_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unhide => unhide_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unflag => unflag_remark => {remark_id => $remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% } =%>
|
||||
</article>
|
||||
</main>
|
||||
<% } =%>
|
||||
|
@ -14,13 +14,9 @@
|
||||
content="Remark on thread #<%= $thread->{'id'} %>.">
|
||||
<% end %>
|
||||
<form method="post" class="form-body">
|
||||
<% if (keys %{$draft}) { =%>
|
||||
<% if ($draft) { =%>
|
||||
<div class="form-preview">
|
||||
<% if ($draft->{'markdown'}) { =%>
|
||||
<%== markdown $draft->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $draft->{'body'} =%></span>
|
||||
<% } =%>
|
||||
<%== markdown $draft =%>
|
||||
</div>
|
||||
<% } =%>
|
||||
<div class="form-field">
|
||||
@ -55,15 +51,10 @@
|
||||
<%= check_box bump => 1, id => 'bump', checked => undef %>
|
||||
<%= label_for bump => 'Bump' %>
|
||||
</div>
|
||||
<div class="form-checkbox">
|
||||
<%= check_box markdown => 1, id => 'markdown' %>
|
||||
<%= label_for markdown => 'Markdown' %>
|
||||
</div>
|
||||
<div class="form-checkbox">
|
||||
<%= check_box preview => 1, id => 'preview' %>
|
||||
<%= label_for preview => 'Preview' %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Post</button>
|
||||
</form>
|
||||
<%# Putting this first above the thread body (nested if, yucky sry) %>
|
||||
@ -80,11 +71,7 @@
|
||||
</h4>
|
||||
<h5 class="post__author"><%= $last_remark->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($last_remark->{'markdown'}) { =%>
|
||||
<%== markdown $last_remark->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $last_remark->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Thread => single_thread =>
|
||||
@ -94,6 +81,16 @@
|
||||
<%= link_to Flag => flag_remark => {remark_id => $last_remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% if (is_mod) { =%>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Hide => hide_remark => {remark_id => $last_remark->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unhide => unhide_remark => {remark_id =>
|
||||
$last_remark->{'id'}}, (class => 'click') %>
|
||||
<%= link_to Unflag => unflag_remark => {remark_id =>
|
||||
$last_remark->{'id'}}, (class => 'click') %>
|
||||
</nav>
|
||||
<% } =%>
|
||||
</article>
|
||||
</section>
|
||||
<% } =%><%# Close the last_remark 'if' %>
|
||||
@ -110,11 +107,7 @@
|
||||
<h4 class="post__date"><%= $thread->{'date'} %></h4>
|
||||
<h5 class="post__author"><%= $thread->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($thread->{'markdown'}) { =%>
|
||||
<%== markdown $thread->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $thread->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to post_remark => {thread_id => $thread->{'id'}},
|
||||
@ -128,6 +121,16 @@
|
||||
<%= link_to Flag => flag_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% if (is_mod) { =%>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Hide => hide_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unhide => unhide_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unflag => unflag_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% } =%>
|
||||
</article>
|
||||
</section>
|
||||
<% } =%><%# Close the thread 'if' %>
|
||||
|
@ -24,11 +24,7 @@
|
||||
<h4 class="post__date"><%= $thread->{'date'} %></h4>
|
||||
<h5 class="post__author"><%= $thread->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($thread->{'markdown'}) { =%>
|
||||
<%== markdown $thread->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $thread->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to post_remark => {thread_id => $thread->{'id'}},
|
||||
@ -42,6 +38,16 @@
|
||||
<%= link_to Flag => flag_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% if (is_mod) { =%>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Hide => hide_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unhide => unhide_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
<%= link_to Unflag => unflag_thread => {thread_id => $thread->{'id'}},
|
||||
(class => 'click') %>
|
||||
</nav>
|
||||
<% } =%>
|
||||
</article>
|
||||
</main>
|
||||
<% } =%>
|
||||
@ -59,11 +65,7 @@
|
||||
</h4>
|
||||
<h5 class="post__author"><%= $remark->{'author'} %></h5>
|
||||
<div class="post__body">
|
||||
<% if ($remark->{'markdown'}) { =%>
|
||||
<%== markdown $remark->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $remark->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<nav class="post__nav">
|
||||
<%= link_to Remark => post_remark =>
|
||||
|
@ -28,19 +28,11 @@
|
||||
<summary>
|
||||
<%= truncate_text $thread->{'body'} %>
|
||||
</summary>
|
||||
<% if ($thread->{'markdown'}) { =%>
|
||||
<%== markdown $thread->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $thread->{'body'} %></span>
|
||||
<% } =%>
|
||||
</details>
|
||||
<% } else { =%>
|
||||
<div class="post__body">
|
||||
<% if ($thread->{'markdown'}) { =%>
|
||||
<%== markdown $thread->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text"><%= $thread->{'body'} %></span>
|
||||
<% } =%>
|
||||
</div>
|
||||
<% } =%>
|
||||
<nav class="post__nav">
|
||||
|
@ -11,15 +11,9 @@
|
||||
% end
|
||||
<h2 class="page-title"><%= title %></h2>
|
||||
<form method="post" class="form-body">
|
||||
<% if (keys %{$draft}) { =%>
|
||||
<% if ($draft) { =%>
|
||||
<div class="form-preview">
|
||||
<% if ($draft->{'markdown'}) { =%>
|
||||
<%== markdown $draft->{'body'} =%>
|
||||
<% } else { =%>
|
||||
<span class="plain-text">
|
||||
<%= $draft->{'body'} =%>
|
||||
</span>
|
||||
<% } =%>
|
||||
<%== markdown $draft =%>
|
||||
</div>
|
||||
<% } =%>
|
||||
<div class="form-field">
|
||||
@ -63,14 +57,9 @@
|
||||
rows => 6
|
||||
) %>
|
||||
</div>
|
||||
<div class="form-checkbox">
|
||||
<%= check_box markdown => 1, id => 'markdown' %>
|
||||
<%= label_for markdown => 'Markdown' %>
|
||||
</div>
|
||||
<div class="form-checkbox">
|
||||
<%= check_box preview => 1, id => 'preview' %>
|
||||
<%= label_for preview => 'Preview' %>
|
||||
</div>
|
||||
<%= csrf_field %>
|
||||
<button type="submit" class="form-button">Post</button>
|
||||
</form>
|
||||
|
Loading…
x
Reference in New Issue
Block a user