From f2cf883f349b7b14c092d3b81b2211257f3806b5 Mon Sep 17 00:00:00 2001 From: sergiotarxz Date: Sun, 24 Apr 2022 00:04:39 +0200 Subject: [PATCH] Adding a module to send multipart/alternative mails. --- Build.PL | 1 + bin/peace | 59 +++++++++++++++++++++--------- lib/Peace/DB.pm | 2 +- lib/Peace/Email.pm | 89 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 17 deletions(-) create mode 100644 lib/Peace/Email.pm diff --git a/Build.PL b/Build.PL index 6b7645f..75da056 100644 --- a/Build.PL +++ b/Build.PL @@ -23,6 +23,7 @@ my $build = Module::Build->new( 'Capture::Tiny' => 0, 'Email::Valid' => 0, 'Crypt::Bcrypt' => 0, + 'Email::Sender' => 0, }, install_path => { 'templates' => "$HOME/.local/share/peace/template", diff --git a/bin/peace b/bin/peace index 9a94ce1..fdfcf9c 100755 --- a/bin/peace +++ b/bin/peace @@ -19,11 +19,16 @@ use Peace::DB; my ( $opt, $usage ) = describe_options( 'peace %o', - [ 'dbname|d=s', 'The database name for config generation.' ], - [ 'host|H=s', 'The database host for config generation.' ], - [ 'username|u=s', 'The database username for config generation.' ], - [ 'password|P=s', 'The database password for config generation.' ], - [ 'port|p=i', 'The database port for config generation.' ], + [ 'dbname|d=s', 'The database name for config generation.' ], + [ 'host|H=s', 'The database host for config generation.' ], + [ 'username|u=s', 'The database username for config generation.' ], + [ 'password|P=s', 'The database password for config generation.' ], + [ 'port|p=i', 'The database port for config generation.' ], + [ 'url|U=s', 'The installation url' ], + [ 'smtp_host=s', 'Name of the smtp host to use.', ], + [ 'smtp_port=s', 'Number of smpt port to use.', ], + [ 'sasl_username=s', 'Name of the smtp user.' ], + [ 'sasl_password=s', 'Password of the smtp user.' ], [ 'disable-readline-ask', 'Disable the readline questions for undefined fields.' @@ -32,18 +37,23 @@ my ( $opt, $usage ) = describe_options( ); print( $usage->text ), exit if $opt->help; -my $home = $ENV{HOME}; +my $home = $ENV{HOME}; my $config_path = "$home/.config/peace/peace.conf"; -if ( !-e $config_path) { +if ( !-e $config_path ) { my $secret = unpack 'H*', urandom(128); say $secret; - my $prompt = '> '; - my $dbname = $opt->dbname; - my $host = $opt->host; - my $username = $opt->username; - my $password = $opt->password; - my $port = $opt->port; + my $prompt = '> '; + my $dbname = $opt->dbname; + my $host = $opt->host; + my $username = $opt->username; + my $password = $opt->password; + my $port = $opt->port; + my $url = $opt->url; + my $smtp_host = $opt->smtp_host; + my $smtp_port = $opt->smtp_port; + my $sasl_username = $opt->sasl_username; + my $sasl_password = $opt->sasl_password; if ( !$opt->disable_readline_ask ) { $dbname = ask_readline_question( $dbname, 'Introduce the dbname:' ); @@ -53,9 +63,25 @@ if ( !-e $config_path) { $password = ask_readline_question( $password, 'Introduce the password:' ); $port = ask_readline_question( $port, 'Introduce the port:' ); + $url = ask_readline_question( $url, 'Intraduce the final url.' ); + $smtp_host = + ask_readline_question( $smtp_host, 'Intraduce the smtp host.' ); + $smtp_port = + ask_readline_question( $smtp_port, 'Intraduce the smtp port.' ); + $sasl_username = + ask_readline_question( $sasl_username, 'Intraduce the smtp user.' ); + $sasl_password = ask_readline_question( $sasl_password, + 'Intraduce the smtp password.' ); } my $config = { - secret => $secret, + secret => $secret, + url => $url, + smtp => { + smtp_host => $smtp_host, + smtp_port => $smtp_port, + sasl_username => $sasl_username, + sasl_password => $sasl_password, + }, db_config => { ( username => $username ) x ( 0 + !!( defined $username ) ), ( dbname => $dbname ) x ( 0 + !!( defined $dbname ) ), @@ -64,9 +90,10 @@ if ( !-e $config_path) { ( port => $port ) x ( 0 + !!( defined $port ) ), } }; - path ($config_path)->parent->mkpath; + path($config_path)->parent->mkpath; print Data::Dumper::Dumper $config; - path ($config_path)->spew_utf8(encode_json $config); + my $json = JSON->new->utf8->pretty(1); + path($config_path)->spew_utf8( $json->encode($config)); } Peace::DB->dbh( config => Peace->new->peace_config ); diff --git a/lib/Peace/DB.pm b/lib/Peace/DB.pm index b4fad9a..65d9974 100644 --- a/lib/Peace/DB.pm +++ b/lib/Peace/DB.pm @@ -96,7 +96,7 @@ my @migrations = ( my $dbname = $db_config->{dbname} or die 'No dbname in db_config'; my $host = $db_config->{host} or die 'No host in db_config'; my $username = $db_config->{username} or die 'No username in db_config'; - my $password = $db_config->{password} or die 'No password in db_config'; + my $password = $db_config->{password}; my $port = $db_config->{port}; my $dsn = "dbi:Pg:" diff --git a/lib/Peace/Email.pm b/lib/Peace/Email.pm new file mode 100644 index 0000000..c6b6309 --- /dev/null +++ b/lib/Peace/Email.pm @@ -0,0 +1,89 @@ +package Peace::Email; + +use v5.30.0; + +use strict; +use warnings; + +use Peace; + +use Params::ValidationCompiler qw/validation_for/; +use Types::Standard qw/Str/; + +use Email::MIME; +use Email::Sender::Simple; +use Email::Sender::Transport::SMTP; + +sub new { + my $class = shift; + return bless {}, $class; +} + +{ + my $validator = validation_for( + params => { + text => { type => Str }, + html => { type => Str }, + to => { type => Str }, + } + ); + + sub sendmail { + my $self = shift; + my %params = $validator->(@_); + my ( $text, $html, $to ) = @params{qw/text html to/}; + my @parts = ( + Email::MIME->create( + attributes => { + content_type => 'multipart/alternative', + }, + parts => [ + Email::MIME->create( + attributes => { + charset => 'UTF-8', + content_type => 'text/plain', + encoding => "quoted-printable", + disposition => 'inline', + }, + body_str => $text, + ), + Email::MIME->create( + attributes => { + charset => 'UTF-8', + content_type => 'text/html', + encoding => "quoted-printable", + disposition => 'inline', + }, + body_str => $html, + ) + ] + ) + ); + my $email = Email::MIME->create( + header_str => [ + From => Peace->new->peace_config->{smtp}{sasl_username}, + To => $to, + ], + attributes => { + encoding => 'base64', + content_type => 'multipart/mixed' + }, + parts => [@parts], + ); + Email::Sender::Simple::send( 'Email::Sender::Simple', $email, + { transport => $self->generate_transport } ); + } +} + +sub generate_transport { + my $peace_config = Peace->new->peace_config; + my $transport = Email::Sender::Transport::SMTP->new( + hosts => [ $peace_config->{smtp}{smtp_host} ], + ssl => 1, + port => $peace_config->{smtp}{smtp_port}, + sasl_username => $peace_config->{smtp}{sasl_username}, + sasl_password => $peace_config->{smtp}{sasl_password}, + ); + return $transport; +} +1;