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