#!/usr/bin/perl # # DW::Controller::Manage::EmailPost # # This code is based on code originally created by the LiveJournal project # owned and operated by Live Journal, Inc. The code has been modified and # expanded by Dreamwidth Studios, LLC. These files were originally licensed # under the terms of the license supplied by Live Journal, Inc, which made # its code repository private in 2014. That license is archived here: # # https://github.com/apparentlymart/livejournal/blob/master/LICENSE-LiveJournal.txt # # In accordance with the original license, this code and all its # modifications are provided under the GNU General Public License. # A copy of that license can be found in the LICENSE file included as # part of this distribution. # # Authors: # Jen Griffin # # Copyright (c) 2023 by Dreamwidth Studios, LLC. # package DW::Controller::Manage::EmailPost; use strict; use DW::Controller; use DW::Routing; use DW::Template; use DW::FormErrors; use LJ::Emailpost::Web; DW::Routing->register_string( "/manage/emailpost", \&emailpost_handler, app => 1 ); sub emailpost_handler { my $ml_scope = "/manage/emailpost.tt"; return error_ml("$ml_scope.error.sitenotconfigured") unless $LJ::EMAIL_POST_DOMAIN; my ( $ok, $rv ) = controller( anonymous => 0, form_auth => 1 ); return $rv unless $ok; my $u = $rv->{u}; return DW::Template->render_template( 'error.tt', { message => $LJ::MSG_READONLY_USER } ) if $u->is_readonly; return error_ml("$ml_scope.error.acct") unless $u->can_emailpost; my @emailpost_props = qw/ emailpost_pin emailpost_allowfrom emailpost_userpic emailpost_security emailpost_comments /; $u->preload_props(@emailpost_props); $rv->{u} = $u; my $r = $rv->{r}; my $form_args = $r->did_post ? $r->post_args : $r->get_args; my ( $mode, $type ) = ( $form_args->{mode}, $form_args->{type} ); if ( $mode && $mode eq 'help' ) { $rv->{type} = $type; $rv->{format_to} = sub { sprintf "%s@%s", $_[0], $LJ::EMAIL_POST_DOMAIN }; if ( my @addr = split /\s*,\s*/, ( $u->{emailpost_allowfrom} || '' ) ) { my $email = $addr[0]; $email =~ s/\(\w\)$//; $rv->{example} = $email; } return DW::Template->render_template( 'manage/emailpost_help.tt', $rv ); } # this was 4 on mobile settings - should be consistent # FIXME: dynamically create form fields based on number of existing addresses? $rv->{addr_max} = 4; $rv->{addrlist} = LJ::Emailpost::Web::get_allowed_senders($u); if ( $r->did_post ) { my $success_links = [ { text => LJ::Lang::ml("$ml_scope.success.back"), url => '/manage/emailpost' }, { text => LJ::Lang::ml("$ml_scope.success.info"), url => '/manage/emailpost?mode=help' }, { text => LJ::Lang::ml("$ml_scope.success.settings"), url => '/manage/settings/?cat=mobile' }, ]; my $errors = DW::FormErrors->new; if ( $form_args->{save} ) { my $pin = $form_args->{pin}; $pin =~ s/\s+//g if defined $pin; $errors->add( 'pin', "$ml_scope.error.invalidpin", { num => 4 } ) if $pin && $pin !~ /^([a-z0-9]){4,20}$/i; $errors->add( 'pin', "$ml_scope.error.invalidpinuser" ) if $pin && $pin eq $u->user; # Check email, add flags if needed. my %allowed; my @send_helpmessage; foreach my $count ( 0 .. $rv->{addr_max} ) { my $a = $form_args->{"addresses_$count"} or next; $a =~ s/\s+//g; next unless $a; next if length $a > 80; $a = lc $a; my @email_errors; LJ::check_email( $a, \@email_errors, { force_spelling => 1 } ); $errors->add( "addresses_$count", "$ml_scope.error.invalidemail", { email => LJ::ehtml($a), error => $email_errors[0] } ) if @email_errors; $allowed{$a} = {}; $allowed{$a}->{get_errors} = 1 if $form_args->{"check_$count"}; push @send_helpmessage, $a if $form_args->{"help_$count"}; } if ( $errors->exist ) { $rv->{errors} = $errors; $rv->{formdata} = $r->post_args; return DW::Template->render_template( 'manage/emailpost.tt', $rv ); } $u->set_prop( "emailpost_pin", $pin ); foreach my $prop (@emailpost_props) { next if $prop =~ /emailpost_(allowfrom|pin)/; next if ( $u->{$prop} // '' ) eq ( $form_args->{$prop} // '' ); if ( $form_args->{$prop} && $form_args->{$prop} ne 'default' ) { $u->set_prop( $prop, $form_args->{$prop} ); } else { $u->set_prop( $prop, undef ); } } LJ::Emailpost::Web::set_allowed_senders( $u, \%allowed ); email_helpmessage( $u, $_ ) foreach @send_helpmessage; return success_ml( "$ml_scope.success.message", undef, $success_links ); } } return DW::Template->render_template( 'manage/emailpost.tt', $rv ); } sub email_helpmessage { my ( $u, $address ) = @_; return unless $u && $address; my $user = LJ::isu($u) ? $u->user : $u; # allow object or string my $format_to = sub { sprintf "%s@%s", $_[0], $LJ::EMAIL_POST_DOMAIN }; LJ::send_mail( { to => $address, from => $LJ::BOGUS_EMAIL, fromname => $LJ::SITENAME, subject => LJ::Lang::ml( 'setting.emailposting.helpmessage.subject', { sitenameshort => $LJ::SITENAMESHORT } ), body => LJ::Lang::ml( 'setting.emailposting.helpmessage.body', { email => $format_to->("$user+PIN"), comm => $format_to->("$user.communityname"), url => "$LJ::SITEROOT/manage/emailpost" } ), } ); } 1;