# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Controller::Mail;
use Mojo::Base 'Mojolicious::Controller';
use Mojo::JSON qw(decode_json);
use Mojo::URL;
use Email::Valid;
use URI::Find;
use URI::Find::Schemeless;
sub render_mail {
my $c = shift;
my $links = (defined($c->param('links'))) ? decode_json($c->param('links')) : [];
$c->redirect_to('/') unless (scalar(@{$links}));
$c->render(
template => 'mail',
links => $links
);
}
sub send_mail {
my $c = shift;
my $validation = $c->validation;
return $c->render(text => $c->l('Bad CSRF token!'), status => 403) if $validation->csrf_protect->has_error('csrf_token');
my $emails = $c->param('emails');
my $body = $c->param('body');
my $subject = $c->param('subject');
my $msg = '';
my $base_url = $c->req->url->to_abs->path($c->config('prefix').'r/');
my $fixed_url = $base_url;
if ($c->config('fixed_domain')) {
$fixed_url->host($c->config('fixed_domain'));
}
my $at_least_one_instance_url = 0;
my $finder = URI::Find->new(sub {
my ($uri, $orig_uri) = @_;
$uri = Mojo::URL->new($uri);
if ($uri->host ne $base_url->to_abs->host && $uri->host ne $fixed_url->to_abs->host) {
$msg .= $c->l('You can\'t add URLs that are not related to this instance (%1).', $orig_uri).'
';
} elsif (index($orig_uri, $fixed_url->to_abs->to_string) > -1) {
$at_least_one_instance_url = 1;
}
return $orig_uri;
});
$finder->find(\$body);
$finder->find(\$subject);
# Schemeless URI beginning with www, which are interpreted by mailers 🤦
$finder = URI::Find::Schemeless->new(sub {
my ($uri, $orig_uri) = @_;
return $orig_uri if ($uri !~ m/www/);
$uri = Mojo::URL->new($uri);
if ($uri->host ne $base_url->to_abs->host && $uri->host ne $fixed_url->to_abs->host) {
$msg .= $c->l('You can\'t add URLs that are not related to this instance (%1).', $orig_uri).'
';
}
return $orig_uri;
});
$finder->find(\$body);
$finder->find(\$subject);
unless ($at_least_one_instance_url) {
$msg .= $c->l('The body of the mail must contain at least one URL pointing to a file hosted on this instance.').'
';
}
$emails =~ s/ //g;
my @a = split(',', $emails);
my @bad;
my @good;
for my $email (@a) {
if (!Email::Valid->address($email)) {
push @bad, $email;
}
}
if (scalar(@bad)) {
$msg .= $c->l('The following email addresses are not valid: %1', join(', ', @bad)).'
';
}
$msg .= $c->l('You must give email addresses.').'
' unless (scalar(@a));
$msg .= $c->l('The email subject can\'t be empty.').'
' unless ($subject);
$msg .= $c->l('The email body can\'t be empty.').'
' unless ($body);
if ($msg) {
return $c->render(
template => 'mail',
msg => $msg,
links => [],
values => {
emails => $emails,
subject => $subject,
body => $body
}
)
}
$c->mail(
from => $c->config('mail_sender'),
bcc => $emails,
subject => $subject,
data => $body
);
return $c->render(
template => 'msg',
msg_success => $c->l('The mail has been sent.')
);
}
1;