Sanitize HTML in body; enforce NOT NULL on body; template clean-up

This commit is contained in:
swagg boi 2023-05-03 21:05:57 -04:00
parent 5e857b9426
commit ab0f53ba26
12 changed files with 68 additions and 24 deletions

View file

@ -58,9 +58,10 @@ Run the tests locally (against development environment):
## TODOs
1. Use something like HTML::Restrict on thread/remark body
1. CSS
1. "All new posts flagged" mode (require approval for new posts)
1. Tests for mod-only user?
1. Check input validation
## Crazy future ideas

View file

@ -9,3 +9,4 @@ requires 'Date::Format';
requires 'XML::RSS';
requires 'CSS::Minifier::XS';
requires 'Text::Markdown';
requires 'HTML::Restrict';

View file

@ -6,6 +6,7 @@ use Mojo::Base 'Mojolicious', -signatures;
use Mojo::Pg;
use Crypt::Passphrase;
use Text::Markdown qw{markdown};
use HTML::Restrict;
# The local libs
use PostText::Model::Thread;
@ -29,12 +30,22 @@ sub startup($self) {
)
});
$self->helper(hr => sub ($c) {
state $hr = HTML::Restrict->new(strip_enclosed_content => [])
});
$self->helper(thread => sub ($c) {
state $thread = PostText::Model::Thread->new(pg => $c->pg)
state $thread = PostText::Model::Thread->new(
pg => $c->pg,
hr => $c->hr
)
});
$self->helper(remark => sub ($c) {
state $remark = PostText::Model::Remark->new(pg => $c->pg)
state $remark = PostText::Model::Remark->new(
pg => $c->pg,
hr => $c->hr
)
});
$self->helper(moderator => sub ($c) {
@ -70,7 +81,7 @@ sub startup($self) {
# Finish configuring some things
$self->secrets($self->config->{'secrets'}) || die $@;
$self->pg->migrations->from_dir('migrations')->migrate(11);
$self->pg->migrations->from_dir('migrations')->migrate(12);
if (my $threads_per_page = $self->config->{'threads_per_page'}) {
$self->thread->per_page($threads_per_page)

View file

@ -2,7 +2,7 @@ package PostText::Model::Remark;
use Mojo::Base -base, -signatures;
has 'pg';
has [qw{pg hr}];
has per_page => 5;
@ -28,7 +28,8 @@ sub by_page_for($self, $thread_id, $this_page = 1) {
}
sub create($self, $thread_id, $author, $body, $hidden = 0, $flagged = 0) {
my @data = ($thread_id, $author, $body, $hidden, $flagged);
my $clean_body = $self->hr->process($body);
my @data = ($thread_id, $author, $clean_body, $hidden, $flagged);
$self->pg->db->query(<<~'END_SQL', @data);
INSERT INTO remarks (

View file

@ -2,14 +2,15 @@ package PostText::Model::Thread;
use Mojo::Base -base, -signatures;
has 'pg';
has [qw{pg hr}];
has per_page => 5;
has date_format => 'Dy, FMDD Mon YYYY HH24:MI:SS TZ';
sub create($self, $author, $title, $body, $hidden = 0, $flagged = 0) {
my @data = ($author, $title, $body, $hidden, $flagged);
my $clean_body = $self->hr->process($body);
my @data = ($author, $title, $clean_body, $hidden, $flagged);
$self->pg->db->query(<<~'END_SQL', @data)->hash->{'thread_id'};
INSERT INTO threads (

7
migrations/12/down.sql Normal file
View file

@ -0,0 +1,7 @@
ALTER TABLE threads
ALTER COLUMN thread_body
DROP NOT NULL;
ALTER TABLE remarks
ALTER COLUMN remark_body
DROP NOT NULL;

9
migrations/12/up.sql Normal file
View file

@ -0,0 +1,9 @@
-- Input validation may fail for body if user submits only an HTML tag
ALTER TABLE threads
ALTER COLUMN thread_body
SET NOT NULL;
ALTER TABLE remarks
ALTER COLUMN remark_body
SET NOT NULL;

View file

@ -3,13 +3,13 @@
<h2><%= title %></h2>
<div class="about body">
<p>Post::Text is a <a href="">textboard</a> a bit like 2channel. You
can post whatever you want anonymously just please mind the
<%= link_to rules => 'rules_page' %>. Markdown is supported for
formatting posts using the
<a href="https://daringfireball.net/projects/markdown/syntax">
original implementation from The Daring Fireball</a>. For
example, back-ticks are for <em>inline code</em> while
indentation should be used if you want an entire code bock:</p>
can post whatever you want anonymously just please mind the <%=
link_to rules => 'rules_page' %>. Markdown is supported for
formatting posts using the <a
href="https://daringfireball.net/projects/markdown/syntax">
original implementation from The Daring Fireball</a>. For example,
back-ticks are for <em>inline code</em> while indentation should
be used if you want an entire code bock:</p>
<pre><code>
This is `inline_code()` and so is ```this()```. This is incorrect:
@ -24,9 +24,10 @@ This is correct for a multi-line code block:
if (true) {
do_stuff();
}
You can use an actual tab character or four spaces to indent.
</code></pre>
<p>You can use an actual tab character or four spaces to indent.
<strong>Only Markdown is supported, HTML will be filtered
out.</strong></p>
<p>There is a button for users to 'flag' a post for review by a
moderator. If you need further assistance you can reach out to the
<a href="mailto:swaggboi@slackware.uk">webmaster</a>. There is

View file

@ -6,7 +6,9 @@
<nav class="id">#<%= $remark->{'id'} %></nav>
<h4 class="date"><%= $remark->{'date'} %></h4>
<h5 class="author"><%= $remark->{'author'} %></h5>
<div class="body"><%== markdown $remark->{'body'} %></div>
<div class="body">
<%== markdown $remark->{'body'} =%>
</div>
</article>
</div>
<nav>

View file

@ -37,7 +37,9 @@
<h3 class="title"><%= $thread->{'title'} %></h3>
<h4 class="date"><%= $thread->{'date'} %></h4>
<h5 class="author"><%= $thread->{'author'} %></h5>
<div class="body"><%== markdown $thread->{'body'} %></div>
<div class="body">
<%== markdown $thread->{'body'} =%>
</div>
</article>
</div>
<% if (my $last_remark_id = $last_remark->{'id'}) { =%>
@ -50,7 +52,9 @@
</nav>
<h4 class="date"><%= $last_remark->{'date'} %></h4>
<h5 class="author"><%= $last_remark->{'author'} %></h5>
<div class="body"><%== markdown $last_remark->{'body'} %></div>
<div class="body">
<%== markdown $last_remark->{'body'} =%>
</div>
</article>
</div>
<% } =%>

View file

@ -6,7 +6,9 @@
<h3 class="title"><%= $thread->{'title'} %></h3>
<h4 class="date"><%= $thread->{'date'} %></h4>
<h5 class="author"><%= $thread->{'author'} %></h5>
<div class="body"><%== markdown $thread->{'body'} %></div>
<div class="body">
<%== markdown $thread->{'body'} =%>
</div>
</article>
</div>
<nav>
@ -32,7 +34,9 @@
</nav>
<h4 class="date"><%= $remark->{'date'} %></h4>
<h5 class="author"><%= $remark->{'author'} %></h5>
<div class="body"><%== markdown $remark->{'body'} %></div>
<div class="body">
<%== markdown $remark->{'body'} =%>
</div>
<nav class="flag">
<%= link_to Flag => flag_remark => {remark_id => $remark->{'id'}} %>
</nav>

View file

@ -15,7 +15,9 @@
</h3>
<h4 class="date"><%= $thread->{'date'} %></h4>
<h5 class="author"><%= $thread->{'author'} %></h5>
<div class="body"><%== markdown truncate_text $thread->{'body'} %></div>
<div class="body">
<%== markdown truncate_text $thread->{'body'} =%>
</div>
<nav>
<%= link_to Remark => post_remark => {thread_id => $thread->{'id'}} %>
<%= link_to url_for(single_thread => {thread_id => $thread->{'id'}})