diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Mail2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Mail2F.pm index 63275acca3918a161f99e1efb834b73b54f8be7c..479a20630e9368b7b3192a342516d11bc27611f0 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Mail2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Mail2F.pm @@ -100,48 +100,33 @@ sub sendCode { return 0; } - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{mail2fSubject}; + # Template engine expects $req->sessionInfo to be populated + # which is not the case during a resend + $req->sessionInfo($sessionInfo); - unless ($subject) { - $subject = 'mail2fSubject'; - $tr->( \$subject ); - } - my ( $body, $html ); - if ( $self->conf->{mail2fBody} ) { - - # We use a specific text message, no html - $body = $self->conf->{mail2fBody}; - - # Replace variables in body - $body =~ s/\$code/$code/g; - $body =~ s/\$(\w+)/$sessionInfo->{$1} || ''/ge; + # Send mail + if ( + $self->sendEmail( + $req, + subject => $self->conf->{mail2fSubject}, + subject_trmsg => 'mail2fSubject', + body => $self->conf->{mail2fBody}, + body_template => 'mail_2fcode', + dest => $dest, + params => { + code => $code, + } + ) + ) + { + return 1; } else { - - # Template engine expects $req->sessionInfo to be populated - # which is not the case during a resend - $req->sessionInfo($sessionInfo); - - # Use HTML template - $body = $self->loadMailTemplate( - $req, - 'mail_2fcode', - filter => $tr, - params => { code => $code } - ); - $html = 1; - } - - # Send mail - unless ( $self->send_mail( $dest, $subject, $body, $html ) ) { $self->logger->error( $self->prefix . "2f: unable to send code to $dest" ); return 0; } - return 1; } sub verify_external { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm index 443850bae15d71e8d728cf5e9eeea912cfa6381e..664e47d0ba515500854b3d2f3d8fa6f8a4e5ffd1 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/SMTP.pm @@ -107,7 +107,7 @@ sub gen_password { return $self->random->randregex($regexp); } -# Send mail +# Send mail (legacy API, using sendEmail is recommended instead) # @param mail recipient address # @param subject mail subject # @param body mail body @@ -293,4 +293,80 @@ sub getRegisterSession { return ""; } +## @method string sendEmail(string mail) +# High-level method for sending a templated email +# Takes a hash of parameters +# @param dest the destination email address +# @param subject the plaintext subject, will not be translated +# @param subject_trmsg the translation key that will be used as subject +# @param body the plaintext body, may contain $variable placeholders +# @param body_template the name of the template file to render as body +# @param params a hashref of parameters +# @return success status as a boolean +sub sendEmail { + my ( $self, $req, %params ) = @_; + + my $subject_trmsg = $params{subject_trmsg}; + my $subject = $params{subject}; + my $body = $params{body}; + my $body_template = $params{body_template}; + my %variables = %{ $params{params} || {} }; + my $dest = $params{dest}; + + # Build mail content + my $tr = $self->translate($req); + unless ($subject) { + $subject = $subject_trmsg; + $tr->( \$subject ); + } + my $html; + if ($body) { + + # Replace supplied variables in body, and also handle session variables + while ( my ( $k, $v ) = each %variables ) { + $body =~ s/\$\Q$k\E\b/$v/g; + } + $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; + } + else { + + # Use HTML template + $body = $self->loadMailTemplate( + $req, + $body_template, + filter => $tr, + params => \%variables + ); + $html = 1; + } + if ( $dest && $subject && $body ) { + if ( $self->send_mail( $dest, $subject, $body, $html ) ) { + $self->auditLog( + $req, + message => "Email ($body_template) sent " + . "to $dest with subject '$subject'", + code => "EMAIL_SENT", + body_template => $body_template, + subject => $subject, + subject_trmsg => $subject_trmsg, + dest => $dest, + ); + return 1; + } + else { + return 0; + } + } + else { + my $message = "Could not send email:"; + $message .= " missing destination," unless $dest; + $message .= " missing subject," unless $subject; + $message .= " missing body," unless $body; + chop($message); + $message .= "."; + $self->logger->warn($message); + return 0; + } +} + 1; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Password/Base.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Password/Base.pm index c433666467a36a8084b5c5d9d3ed1c52755370ce..c357e042bc4eca6aac48750267f59f4c7e315958 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Password/Base.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Password/Base.pm @@ -137,47 +137,20 @@ sub _modifyPassword { $self->p->getFirstValue( $req->{sessionInfo}->{ $self->conf->{mailSessionKey} } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{mailSubject}; - unless ($subject) { - $subject = 'mailSubject'; - $tr->( \$subject ); - } - my $body; - my $html; my $password = $req->data->{newpassword}; - if ( $self->conf->{mailBody} ) { - - # We use a specific text message, no html - $body = $self->conf->{mailBody}; - - # Replace variables in body - $body =~ s/\$password/$password/g; - $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; - - } - - else { - - # Use HTML template - $body = $self->loadMailTemplate( - $req, - 'mail_password', - filter => $tr, - params => { - password => $password, - }, - ); - $html = 1; - } - # Send mail unless ( - $self->send_mail( - $req->data->{mailAddress}, - $subject, $body, $html + $self->sendEmail( + $req, + subject => $self->conf->{mailSubject}, + subject_trmsg => 'mailSubject', + body => $self->conf->{mailBody}, + body_template => 'mail_password', + dest => $req->data->{mailAddress}, + params => { + password => $password, + } ) ) { diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm index 52375d00dee7b0008c58aa7d3225870ee012b531..a1f1b6e2862af83fad0f64157654062296402cfa 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm @@ -338,48 +338,19 @@ sub _certificateReset { } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{certificateResetByMailStep1Subject}; - unless ($subject) { - $subject = 'certificateResetByMailStep1Subject'; - $tr->( \$subject ); - } - my $body; - my $html; - if ( $self->conf->{certificateResetByMailStep1Body} ) { - - # We use a specific text message, no html - $body = $self->conf->{certificateResetByMailStep1Body}; - - # Replace variables in body - $body =~ s/\$expMailDate/$req->data->{expMailDate}/ge; - $body =~ s/\$expMailTime/$req->data->{expMailTime}/ge; - $body =~ s/\$url/$url/g; - $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; - - } - else { - - # Use HTML template - $body = $self->loadMailTemplate( + unless ( + $self->sendEmail( $req, - 'mail_certificateConfirm', - filter => $tr, - params => { + subject => $self->conf->{certificateResetByMailStep1Subject}, + subject_trmsg => 'certificateResetByMailStep1Subject', + body => $self->conf->{certificateResetByMailStep1Body}, + body_template => 'mail_certificateConfirm', + dest => $req->data->{mailAddress}, + params => { expMailDate => $req->data->{expMailDate}, expMailTime => $req->data->{expMailTime}, url => $url, - }, - ); - $html = 1; - } - - # Send mail - unless ( - $self->send_mail( - $req->data->{mailAddress}, - $subject, $body, $html + } ) ) { @@ -521,40 +492,16 @@ sub modifyCertificate { $self->p->getFirstValue( $req->{sessionInfo}->{ $self->conf->{mailSessionKey} } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{certificateResetByMailStep2Subject}; - unless ($subject) { - $subject = 'certificateResetByMailStep2Subject'; - $tr->( \$subject ); - } - my $body; - my $html; - if ( $self->conf->{certificateResetByMailStep2Body} ) { - - # We use a specific text message, no html - $body = $self->conf->{certificateResetByMailStep2Body}; - - # Replace variables in body - $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; - - } - else { - - # Use HTML template - $body = $self->loadMailTemplate( - $req, - 'mail_certificateReset', - filter => $tr, - params => {}, - ); - $html = 1; - } - # Send mail return PE_MAILERROR - unless $self->send_mail( $req->data->{mailAddress}, $subject, $body, - $html ); + unless $self->sendEmail( + $req, + subject => $self->conf->{certificateResetByMailStep2Subject}, + subject_trmsg => 'certificateResetByMailStep2Subject', + body => $self->conf->{certificateResetByMailStep2Body}, + body_template => 'mail_certificateReset', + dest => $req->data->{mailAddress}, + ); return PE_MAILOK; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm index 5ffe8731b2b41cfe9a834aacf677d51e43b58fd0..588a10985ccc48a9c5283ab9183e4644ed113815 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/MailPasswordReset.pm @@ -341,42 +341,6 @@ sub _reset { } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{mailConfirmSubject}; - unless ($subject) { - $subject = 'mailConfirmSubject'; - $tr->( \$subject ); - } - my ( $body, $html ); - if ( $self->conf->{mailConfirmBody} ) { - - # We use a specific text message, no html - $body = $self->conf->{mailConfirmBody}; - - # Replace variables in body - $body =~ s/\$expMailDate/$req->data->{expMailDate}/ge; - $body =~ s/\$expMailTime/$req->data->{expMailTime}/ge; - $body =~ s/\$url/$url/g; - $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; - - } - else { - - # Use HTML template - $body = $self->loadMailTemplate( - $req, - 'mail_confirm', - filter => $tr, - params => { - expMailDate => $req->data->{expMailDate}, - expMailTime => $req->data->{expMailTime}, - url => $url, - }, - ); - $html = 1; - } - $self->logger->info( "User " . $req->data->{mailAddress} . " is trying to reset his/her password" ); @@ -384,9 +348,18 @@ sub _reset { # Send mail $self->logger->debug('Unable to send reset mail') unless ( - $self->send_mail( - $req->data->{mailAddress}, - $subject, $body, $html + $self->sendEmail( + $req, + subject => $self->conf->{mailConfirmSubject}, + subject_trmsg => 'mailConfirmSubject', + body => $self->conf->{mailConfirmBody}, + body_template => 'mail_confirm', + dest => $req->data->{mailAddress}, + params => { + expMailDate => $req->data->{expMailDate}, + expMailTime => $req->data->{expMailTime}, + url => $url, + }, ) ); @@ -545,43 +518,20 @@ sub changePwd { $self->p->getFirstValue( $req->{sessionInfo}->{ $self->conf->{mailSessionKey} } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{mailSubject}; - unless ($subject) { - $subject = 'mailSubject'; - $tr->( \$subject ); - } - my $body; - my $html; my $password = $req->data->{newpassword}; - if ( $self->conf->{mailBody} ) { - - # We use a specific text message, no html - $body = $self->conf->{mailBody}; - - # Replace variables in body - $body =~ s/\$password/$password/g; - $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; - - } - else { - - # Use HTML template - $body = $self->loadMailTemplate( - $req, - 'mail_password', - filter => $tr, - params => { - %tplPrms, password => $password, - }, - ); - $html = 1; - } - # Send mail - return $self->send_mail( $req->data->{mailAddress}, $subject, $body, $html ) + return $self->sendEmail( + $req, + subject => $self->conf->{mailSubject}, + subject_trmsg => 'mailSubject', + body => $self->conf->{mailBody}, + body_template => 'mail_password', + dest => $req->data->{mailAddress}, + params => { + %tplPrms, password => $password, + }, + ) ? PE_MAILOK : PE_MAILERROR; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm index 695e21a15214a3ca8bb1fb92ef4fbb44cb7434ea..d17928bfce94c313cbd3e2927d25b08c105eccbb 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm @@ -101,66 +101,44 @@ sub checkNewLocation { sub sendWarningEmail { my ( $self, $req ) = @_; - return $self->_sendMail($req) - if $req->sessionInfo->{_riskDetails}->{newLocation}; + + if ( $req->sessionInfo->{_riskDetails}->{newLocation} ) { + my $mail = $req->sessionInfo->{ $self->mailSessionKey }; + my $user = $req->sessionInfo->{ $self->conf->{whatToTrace} }; + if ($mail) { + $self->userLogger->info( + "User $user is signing in from a new location"); + return $self->_sendMail( $req, $mail ); + } + else { + $self->logger->warn( "User $user is signing in from a new location" + . " but has no configured email" ); + } + } return PE_OK; } sub _sendMail { - my ( $self, $req ) = @_; + my ( $self, $req, $mail ) = @_; my $date = strftime( '%F %X (UTC%z)', localtime ); my $location = $req->sessionInfo->{_riskDetails}->{newLocation}; my $ua = $req->env->{HTTP_USER_AGENT}; - my $mail = $req->sessionInfo->{ $self->mailSessionKey }; - - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{newLocationWarningMailSubject}; - unless ($subject) { - $self->logger->debug('Use default warning subject'); - $subject = 'newLocationWarningMailSubject'; - $tr->( \$subject ); - } - my ( $body, $html ); - if ( $self->conf->{newLocationWarningMailBody} ) { - - # We use a specific text message, no html - $self->logger->debug('Use specific warning body message'); - $body = $self->conf->{newLocationWarningMailBody}; - - # Replace variables in body - $body =~ s/\$ua\b/$ua/ge; - $body =~ s/\$location\b/$location/ge; - $body =~ s/\$date\b/$date/ge; - $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge; - } - else { - # Use HTML template - $body = $self->loadMailTemplate( - $req, - 'mail_new_location_warning', - filter => $tr, - params => { - location => $location, - date => $date, - ua => $ua - }, - ); - $html = 1; - } - if ( $mail && $subject && $body ) { - $self->logger->warn("User $mail is signing in from a new location"); + $self->sendEmail( + $req, + subject => $self->conf->{newLocationWarningMailSubject}, + subject_trmsg => 'newLocationWarningMailSubject', + body => $self->conf->{newLocationWarningMailBody}, + body_template => 'mail_new_location_warning', + dest => $mail, + params => { + location => $location, + date => $date, + ua => $ua + }, + ); - # Send mail - $self->logger->debug('Unable to send new location warning mail') - unless ( $self->send_mail( $mail, $subject, $body, $html ) ); - } - else { - $self->logger->error( - 'Unable to send new location warning mail: missing parameter(s)'); - } return PE_OK; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm index fa310149f27082f5b55d47f655d3275c1502f990..03e98be8295bb1e55078542525484e9f1b8c8a8b 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/Register.pm @@ -277,49 +277,22 @@ sub _register { } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{registerConfirmSubject}; - unless ($subject) { - $self->logger->debug('Use default confirm subject'); - $subject = 'registerConfirmSubject'; - $tr->( \$subject ); - } - my ( $body, $html ); - if ( $self->conf->{registerConfirmBody} ) { - - # We use a specific text message, no html - $self->logger->debug('Use specific confirm body message'); - $body = $self->conf->{registerConfirmBody}; - - # Replace variables in body - $body =~ s/\$url/$url/g; - $body =~ s/\$expMailDate/$req->{data}->{expMailDate}/g; - $body =~ s/\$expMailTime/$req->{data}->{expMailTime}/g; - $body =~ s/\$(\w+)/$req->{data}->{registerInfo}->{$1} || ''/ge; - } - else { - - # Use HTML template - $self->logger->debug('Use default confirm HTML template body'); - $body = $self->loadMailTemplate( - $req, - 'mail_register_confirm', - filter => $tr, - params => { - expMailDate => $req->data->{expMailDate}, - expMailTime => $req->data->{expMailTime}, - url => $url, - %{ $req->data->{registerInfo} || {} }, - }, - ); - $html = 1; - } - # Send mail return PE_MAILERROR - unless $self->send_mail( $req->data->{registerInfo}->{mail}, - $subject, $body, $html ); + unless $self->sendEmail( + $req, + subject => $self->conf->{registerConfirmSubject}, + subject_trmsg => 'registerConfirmSubject', + body => $self->conf->{registerConfirmBody}, + body_template => 'mail_register_confirm', + dest => $req->data->{registerInfo}->{mail}, + params => { + expMailDate => $req->data->{expMailDate}, + expMailTime => $req->data->{expMailTime}, + url => $url, + %{ $req->data->{registerInfo} || {} }, + }, + ); $self->logger->debug('Register message sent'); return PE_MAILCONFIRMOK; @@ -362,45 +335,20 @@ sub _register { } ); - # Build mail content - my $tr = $self->translate($req); - my $subject = $self->conf->{registerDoneSubject}; - unless ($subject) { - $self->logger->debug('Use default done subject'); - $subject = 'registerDoneSubject'; - $tr->( \$subject ); - } - my ( $body, $html ); - if ( $self->conf->{registerDoneBody} ) { - - # We use a specific text message, no html - $self->logger->debug('Use specific done body message'); - $body = $self->conf->{registerDoneBody}; - - # Replace variables in body - $body =~ s/\$url/$url/g; - $body =~ s/\$(\w+)/$req->{data}->{registerInfo}->{$1} || ''/ge; - } - else { - - # Use HTML template - $self->logger->debug('Use default done HTML template body'); - $body = $self->loadMailTemplate( - $req, - 'mail_register_done', - filter => $tr, - params => { - url => $url, - %{ $req->data->{registerInfo} || {} }, - }, - ); - $html = 1; - } - # Send mail return PE_MAILERROR - unless $self->send_mail( $req->data->{registerInfo}->{mail}, - $subject, $body, $html ); + unless $self->sendEmail( + $req, + subject => $self->conf->{registerDoneSubject}, + subject_trmsg => 'registerDoneSubject', + body => $self->conf->{registerDoneBody}, + body_template => 'mail_register_done', + dest => $req->data->{registerInfo}->{mail}, + params => { + url => $url, + %{ $req->data->{registerInfo} || {} }, + } + ); return PE_MAILOK; } diff --git a/lemonldap-ng-portal/t/01-Mail-Tpl.t b/lemonldap-ng-portal/t/01-Mail-Tpl.t index a4eca76aadb084f3e3357e127e71032d8396e720..198ffb5b3ff13bda787e1f2bc0bb31f33c764c25 100644 --- a/lemonldap-ng-portal/t/01-Mail-Tpl.t +++ b/lemonldap-ng-portal/t/01-Mail-Tpl.t @@ -1,5 +1,6 @@ use warnings; use Test::More; +use Lemonldap::NG::Portal::Main::Request; use strict; require 't/test-lib.pm'; @@ -12,87 +13,137 @@ my $client = LLNG::Manager::Test->new( { portal => 'https://auth.example.com/', customPlugins => "t::TestMail", skinTemplateDir => 't/templates', + msg_xxx => "Translated subject", } } ); -# Default skin -subtest "Default skin, default language" => sub { - clear_mail(); - ok( $res = $client->_get('/testmail'), 'request ok' ); - - like( mail(), qr/Your login code/ ); - unlike( - mail(), - qr,Content-Type: image/png; name="logo_llng_400px\.png",, - "Logo not attached" - ); -}; +subtest "Skin and language resolution" => sub { -subtest "Default skin, custom language" => sub { - clear_mail(); - ok( $res = $client->_get( '/testmail', cookie => "llnglanguage=fr" ), - 'request ok' ); - - like( mail(), qr/Votre code de connexion est/ ); - unlike( - mail(), - qr,Content-Type: image/png; name="logo_llng_400px\.png",, - "Logo not attached" - ); -}; + # Default skin + subtest "Default skin, default language" => sub { + clear_mail(); + ok( $res = $client->_get('/testmail'), 'request ok' ); -subtest "custom skin, default language" => sub { - clear_mail(); - ok( $res = $client->_get( '/testmail', query => "skin=mailtplskin" ), - 'Request ok' ); - - like( mail(), qr/Your 2FA code/ ); - like( - mail(), - qr,Content-Type: image/png; name="logo_llng_400px\.png",, - "Logo attached" - ); -}; + like( mail(), qr/Your login code/ ); + unlike( + mail(), + qr,Content-Type: image/png; name="logo_llng_400px\.png",, + "Logo not attached" + ); + }; + + subtest "Default skin, custom language" => sub { + clear_mail(); + ok( $res = $client->_get( '/testmail', cookie => "llnglanguage=fr" ), + 'request ok' ); + + like( mail(), qr/Votre code de connexion est/ ); + unlike( + mail(), + qr,Content-Type: image/png; name="logo_llng_400px\.png",, + "Logo not attached" + ); + }; + + subtest "custom skin, default language" => sub { + clear_mail(); + ok( $res = $client->_get( '/testmail', query => "skin=mailtplskin" ), + 'Request ok' ); + + like( mail(), qr/Your 2FA code/ ); + like( + mail(), + qr,Content-Type: image/png; name="logo_llng_400px\.png",, + "Logo attached" + ); + }; -subtest "custom skin, custom language (cookie)" => sub { - clear_mail(); - ok( - $res = $client->_get( - '/testmail', - query => "skin=mailtplskin", - cookie => "llnglanguage=fr" - ), - 'Request ok' - ); - - like( mail(), qr/Votre code 2FA/ ); - like( - mail(), - qr,Content-Type: image/png; name="logo_llng_400px\.png",, - "Logo attached" - ); + subtest "custom skin, custom language (cookie)" => sub { + clear_mail(); + ok( + $res = $client->_get( + '/testmail', + query => "skin=mailtplskin", + cookie => "llnglanguage=fr" + ), + 'Request ok' + ); + + like( mail(), qr/Votre code 2FA/ ); + like( + mail(), + qr,Content-Type: image/png; name="logo_llng_400px\.png",, + "Logo attached" + ); + }; + + subtest "custom skin, custom language (header)" => sub { + clear_mail(); + ok( + $res = $client->_get( + '/testmail', + query => "skin=mailtplskin", + custom => { + 'HTTP_ACCEPT_LANGUAGE' => 'fr-FR;q=0.7,en;q=0.3', + }, + ), + 'Request ok' + ); + + like( mail(), qr/Votre code 2FA/ ); + like( + mail(), + qr,Content-Type: image/png; name="logo_llng_400px\.png",, + "Logo attached" + ); + }; }; -subtest "custom skin, custom language (header)" => sub { - clear_mail(); - ok( - $res = $client->_get( - '/testmail', - query => "skin=mailtplskin", - custom => { - 'HTTP_ACCEPT_LANGUAGE' => 'fr-FR;q=0.7,en;q=0.3', - }, - ), - 'Request ok' - ); - - like( mail(), qr/Votre code 2FA/ ); - like( - mail(), - qr,Content-Type: image/png; name="logo_llng_400px\.png",, - "Logo attached" - ); +subtest "Test sendEmail method" => sub { + + my $smtp = $client->p->loadedModules->{"t::TestMail"}; + my $req = Lemonldap::NG::Portal::Main::Request->new( + { PATH_INFO => "", REQUEST_URI => "/" } ); + $req->sessionInfo( {} ); + $req->sessionInfo->{uid} = "dwho"; + + subtest "Use templated body and subject" => sub { + clear_mail(); + $smtp->sendEmail( + $req, + dest => 'dwho@example.com', + subject_trmsg => "xxx", + body_template => "test_mail", + params => { custom => "aa" }, + ); + like( mail(), qr/custom=aa/, "Found variable in templated body" ); + like( mail(), qr/uid=dwho/, + "Found session variable in templated body" ); + is( subject(), "Translated subject", "Found subject" ); + is( envelope()->{to}->[0], 'dwho@example.com', "Correct destination" ); + }; + + subtest "Use explicit body and subject" => sub { + clear_mail(); + $smtp->sendEmail( + $req, + dest => 'dwho@example.com', + subject => "hardcoded subject", + subject_trmsg => "xxx", + body => 'hardcodedbody $custom $uid', + body_template => "test_mail", + params => { custom => "aa" }, + ); + like( + mail(), + qr,hardcodedbody aa dwho,, + "Found expected hardcoded body" + ); + is( subject(), "hardcoded subject", "Expected hardcoded subject" ); + is( envelope()->{to}->[0], 'dwho@example.com', "Correct destination" ); + }; + }; done_testing(); diff --git a/lemonldap-ng-portal/t/templates/bootstrap/test_mail.tpl b/lemonldap-ng-portal/t/templates/bootstrap/test_mail.tpl new file mode 100644 index 0000000000000000000000000000000000000000..a323b92d38949a228d78c8375d635a70b4f0499e --- /dev/null +++ b/lemonldap-ng-portal/t/templates/bootstrap/test_mail.tpl @@ -0,0 +1,4 @@ + +[custom=]
+[uid=]
+