Commit 3d4397a7 authored by Matt Glaman's avatar Matt Glaman Committed by Jakob P
Browse files

Issue #3308653 by japerry, mglaman, rivimey: SMTP From address meta issue

parent 8d8e11db
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -423,6 +423,12 @@ class SMTPMailSystem implements MailInterface, ContainerFactoryPluginInterface {
          $mailer->Sender = $value;
          break;

        case 'from':
          // The Drupal mail system specifies the 'From' header, and we do not
          // it to be added again, after our processing above.
          // @todo refactor above "From" handling to here.
          break;

        case 'mime-version':
        case 'x-mailer':
          // Let PHPMailer specify these.
+1 −1
Original line number Diff line number Diff line
@@ -21,6 +21,6 @@ class ValidateD7MigrationStateTest extends MigrateDrupal7TestBase {
  /**
   * {@inheritdoc}
   */
  public static $modules = ['smtp'];
  protected static $modules = ['smtp'];

}
+103 −2
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace Drupal\Tests\smtp\Unit\Plugin\Mail;

use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Prophecy\PhpUnit\ProphecyTrait;
use Drupal\Component\Utility\EmailValidator;
use Drupal\Component\Utility\EmailValidatorInterface;
@@ -18,6 +20,7 @@ use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as PHPMailerException;
use Prophecy\Argument;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Mime\MimeTypeGuesserInterface;

/**
 * Validate requirements for SMTPMailSystem.
@@ -164,7 +167,7 @@ class SMTPMailSystemTest extends UnitTestCase {
      'cc' => 'xyz@example.com',
      'bcc' => 'ttt@example.com',
    ];
    list($new_to, $new_headers) = $mailSystemRerouted->publicApplyRerouting($to, $headers);
    [$new_to, $new_headers] = $mailSystemRerouted->publicApplyRerouting($to, $headers);
    $this->assertEquals($new_to, 'blackhole@galaxy.com', 'to address is set to the reroute address.');
    $this->assertEquals($new_headers, ['some' => 'header'], 'bcc and cc headers are unset when rerouting.');

@@ -175,7 +178,7 @@ class SMTPMailSystemTest extends UnitTestCase {
      'cc' => 'xyz@example.com',
      'bcc' => 'ttt@example.com',
    ];
    list($new_to, $new_headers) = $mailSystemNotRerouted->publicApplyRerouting($to, $headers);
    [$new_to, $new_headers] = $mailSystemNotRerouted->publicApplyRerouting($to, $headers);
    $this->assertEquals($new_to, $to, 'original to address is preserved when not rerouting.');
    $this->assertEquals($new_headers, $headers, 'bcc and cc headers are preserved when not rerouting.');
  }
@@ -316,6 +319,104 @@ class SMTPMailSystemTest extends UnitTestCase {
    self::assertTrue($result);
  }

  /**
   * Tests #3308653 and duplicated headers.
   */
  public function testFromHeaders_3308653() {
    $mailer = new class (
      [],
      'SMTPMailSystem',
      [],
      $this->createMock(LoggerChannelFactoryInterface::class),
      $this->createMock(MessengerInterface::class),
      new EmailValidator(),
      $this->getConfigFactoryStub([
        'smtp.settings' => [
          'smtp_timeout' => 30,
          'smtp_reroute_address' => '',
        ],
        'system.site' => ['name' => 'Mock site name', 'mail' => 'noreply@testmock.mock'],
      ]),
      $this->createMock(AccountProxyInterface::class),
      $this->createMock(FileSystemInterface::class),
      $this->createMock(MimeTypeGuesserInterface::class)
    ) extends SMTPMailSystem {

      /**
       * {@inheritdoc}
       */
      public function smtpMailerSend(array $mailerArr) {
        return $mailerArr;
      }

      /**
       * {@inheritdoc}
       */
      protected function getMailer() {
        return new class (TRUE) extends PHPMailer {

          /**
           * Return the MIME header for testing.
           *
           * @return array
           *   The MIMEHeader as an array.
           */
          public function getMIMEHeaders() {
            return array_filter(explode(static::$LE, $this->MIMEHeader));
          }

        };
      }

    };

    // Message as prepared by \Drupal\Core\Mail\MailManager::doMail().
    $message = [
      'id' => 'smtp_test',
      'module' => 'smtp',
      'key' => 'test',
      'to' => 'test@drupal.org',
      'from' => 'phpunit@localhost.com',
      'reply-to' => 'phpunit@localhost.com',
      'langcode' => 'en',
      'params' => [],
      'send' => TRUE,
      'subject' => 'testMailHeaderDrupal',
      'body' => ['Some test content for testMailHeaderDrupal'],
    ];
    $headers = [
      'MIME-Version' => '1.0',
      'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
      'Content-Transfer-Encoding' => '8Bit',
      'X-Mailer' => 'Drupal',
    ];
    $headers['From'] = $headers['Sender'] = $headers['Return-Path'] = $message['from'];
    $message['headers'] = $headers;

    // Prevent passing `null` to preg_quote in
    // \Drupal\Core\Mail\MailFormatHelper::htmlToMailUrls().
    $GLOBALS['base_path'] = '/';
    $message = $mailer->format($message);
    $result = $mailer->mail($message);

    self::assertArrayHasKey('to', $result);
    self::assertEquals($message['to'], $result['to']);
    self::assertArrayHasKey('from', $result);
    self::assertEquals($message['from'], $result['from']);
    self::assertArrayHasKey('mailer', $result);
    $phpmailer = $result['mailer'];
    self::assertInstanceOf(PHPMailer::class, $phpmailer);
    // Pre-send constructs the email message.
    self::assertTrue($phpmailer->preSend());

    $mime_headers = [];
    foreach ($phpmailer->getMIMEHeaders() as $header) {
      [$name, $value] = explode(': ', $header, 2);
      self::assertArrayNotHasKey(strtolower($name), $mime_headers);
      $mime_headers[strtolower($name)] = $value;
    }
  }

}

/**