Add an endpoint to set new authorized FROM email address
[MAILPOET-2804]
This commit is contained in:
@ -75,6 +75,25 @@ class Settings extends APIEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
public function setAuthorizedFromAddress($data = []) {
|
||||
$address = $data['address'] ?? null;
|
||||
if (!$address) {
|
||||
return $this->badRequest([
|
||||
APIError::BAD_REQUEST => WPFunctions::get()->__('No email address specified.', 'mailpoet'),
|
||||
]);
|
||||
}
|
||||
$address = trim($address);
|
||||
|
||||
try {
|
||||
$this->authorizedEmailsController->setFromEmailAddress($address);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->badRequest([
|
||||
APIError::UNAUTHORIZED => WPFunctions::get()->__('Can’t use this email yet! Please authorize it first.', 'mailpoet'),
|
||||
]);
|
||||
}
|
||||
return $this->successResponse();
|
||||
}
|
||||
|
||||
private function onSettingsChange($oldSettings, $newSettings) {
|
||||
// Recalculate inactive subscribers
|
||||
$oldInactivationInterval = $oldSettings['deactivate_subscriber_after_inactive_days'];
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace MailPoet\Mailer;
|
||||
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoet\Mailer\Methods\AmazonSES;
|
||||
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||
use MailPoet\Mailer\Methods\ErrorMappers\MailPoetMapper;
|
||||
@ -13,7 +14,6 @@ use MailPoet\Mailer\Methods\PHPMail;
|
||||
use MailPoet\Mailer\Methods\SendGrid;
|
||||
use MailPoet\Mailer\Methods\SMTP;
|
||||
use MailPoet\Services\AuthorizedEmailsController;
|
||||
use MailPoet\Services\Bridge;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
|
||||
class Mailer {
|
||||
@ -74,7 +74,7 @@ class Mailer {
|
||||
$this->sender,
|
||||
$this->replyTo,
|
||||
new MailPoetMapper(),
|
||||
new AuthorizedEmailsController($this->settings, new Bridge)
|
||||
ContainerWrapper::getInstance()->get(AuthorizedEmailsController::class)
|
||||
);
|
||||
break;
|
||||
case self::METHOD_SENDGRID:
|
||||
|
@ -2,9 +2,11 @@
|
||||
|
||||
namespace MailPoet\Services;
|
||||
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Mailer\MailerError;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
|
||||
class AuthorizedEmailsController {
|
||||
@ -16,15 +18,43 @@ class AuthorizedEmailsController {
|
||||
/** @var SettingsController */
|
||||
private $settings;
|
||||
|
||||
/** @var NewslettersRepository */
|
||||
private $newslettersRepository;
|
||||
|
||||
private $automaticEmailTypes = [
|
||||
Newsletter::TYPE_WELCOME,
|
||||
Newsletter::TYPE_NOTIFICATION,
|
||||
Newsletter::TYPE_AUTOMATIC,
|
||||
];
|
||||
|
||||
public function __construct(SettingsController $settingsController, Bridge $bridge) {
|
||||
public function __construct(
|
||||
SettingsController $settingsController,
|
||||
Bridge $bridge,
|
||||
NewslettersRepository $newslettersRepository
|
||||
) {
|
||||
$this->settings = $settingsController;
|
||||
$this->bridge = $bridge;
|
||||
$this->newslettersRepository = $newslettersRepository;
|
||||
}
|
||||
|
||||
public function setFromEmailAddress(string $address) {
|
||||
$authorizedEmails = array_map('strtolower', $this->bridge->getAuthorizedEmailAddresses() ?: []);
|
||||
$isAuthorized = $this->validateAuthorizedEmail($authorizedEmails, $address);
|
||||
if (!$isAuthorized) {
|
||||
throw new \InvalidArgumentException("Email address '$address' is not authorized");
|
||||
}
|
||||
|
||||
// update FROM address in settings & all scheduled and active emails
|
||||
$this->settings->set('sender.address', $address);
|
||||
$result = $this->validateAddressesInScheduledAndAutomaticEmails($authorizedEmails);
|
||||
foreach ($result['invalid_senders_in_newsletters'] ?? [] as $item) {
|
||||
$newsletter = $this->newslettersRepository->findOneById((int)$item['newsletter_id']);
|
||||
if ($newsletter) {
|
||||
$newsletter->setSenderAddress($address);
|
||||
}
|
||||
}
|
||||
$this->newslettersRepository->flush();
|
||||
$this->settings->set(self::AUTHORIZED_EMAIL_ADDRESSES_ERROR_SETTING, null);
|
||||
}
|
||||
|
||||
public function checkAuthorizedEmailAddresses() {
|
||||
|
@ -3,10 +3,13 @@
|
||||
namespace MailPoet\Test\Services;
|
||||
|
||||
use Codeception\Stub\Expected;
|
||||
use InvalidArgumentException;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Mailer\MailerError;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\Services\AuthorizedEmailsController;
|
||||
use MailPoet\Services\Bridge;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
@ -155,6 +158,77 @@ class AuthorizedEmailsControllerTest extends \MailPoetTest {
|
||||
expect($error['invalid_senders_in_newsletters'][0]['subject'])->equals('Subject');
|
||||
}
|
||||
|
||||
public function testItSetsFromAddressInSettings() {
|
||||
$this->settings->set('sender.address', '');
|
||||
$controller = $this->getController(['authorized@email.com']);
|
||||
$controller->setFromEmailAddress('authorized@email.com');
|
||||
expect($this->settings->get('sender.address'))->same('authorized@email.com');
|
||||
}
|
||||
|
||||
public function testItSetsFromAddressInScheduledEmails() {
|
||||
$newsletter = new NewsletterEntity();
|
||||
$newsletter->setSubject('Subject');
|
||||
$newsletter->setType(NewsletterEntity::TYPE_STANDARD);
|
||||
$newsletter->setStatus(NewsletterEntity::STATUS_SCHEDULED);
|
||||
$newsletter->setSenderAddress('invalid@email.com');
|
||||
$this->entityManager->persist($newsletter);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->settings->set('sender.address', '');
|
||||
$controller = $this->getController(['authorized@email.com']);
|
||||
$controller->setFromEmailAddress('authorized@email.com');
|
||||
expect($newsletter->getSenderAddress())->same('authorized@email.com');
|
||||
|
||||
// refresh from DB and check again
|
||||
$this->entityManager->refresh($newsletter);
|
||||
expect($newsletter->getSenderAddress())->same('authorized@email.com');
|
||||
}
|
||||
|
||||
public function testItSetsFromAddressInAutomaticEmails() {
|
||||
$newsletter = new NewsletterEntity();
|
||||
$newsletter->setSubject('Subject');
|
||||
$newsletter->setType(NewsletterEntity::TYPE_AUTOMATIC);
|
||||
$newsletter->setStatus(NewsletterEntity::STATUS_ACTIVE);
|
||||
$newsletter->setSenderAddress('invalid@email.com');
|
||||
$this->entityManager->persist($newsletter);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->settings->set('sender.address', '');
|
||||
$controller = $this->getController(['authorized@email.com']);
|
||||
$controller->setFromEmailAddress('authorized@email.com');
|
||||
expect($newsletter->getSenderAddress())->same('authorized@email.com');
|
||||
|
||||
// refresh from DB and check again
|
||||
$this->entityManager->refresh($newsletter);
|
||||
expect($newsletter->getSenderAddress())->same('authorized@email.com');
|
||||
}
|
||||
|
||||
public function testItDoesntSetFromAddressForSentEmails() {
|
||||
$newsletter = new NewsletterEntity();
|
||||
$newsletter->setSubject('Subject');
|
||||
$newsletter->setType(NewsletterEntity::TYPE_STANDARD);
|
||||
$newsletter->setStatus(NewsletterEntity::STATUS_SENT);
|
||||
$newsletter->setSenderAddress('invalid@email.com');
|
||||
$this->entityManager->persist($newsletter);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->settings->set('sender.address', '');
|
||||
$controller = $this->getController(['authorized@email.com']);
|
||||
$controller->setFromEmailAddress('authorized@email.com');
|
||||
expect($newsletter->getSenderAddress())->same('invalid@email.com');
|
||||
|
||||
// refresh from DB and check again
|
||||
$this->entityManager->refresh($newsletter);
|
||||
expect($newsletter->getSenderAddress())->same('invalid@email.com');
|
||||
}
|
||||
|
||||
public function testSetsFromAddressThrowsForUnauthorizedEmail() {
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage("Email address 'invalid@email.com' is not authorized");
|
||||
$controller = $this->getController(['authorized@email.com']);
|
||||
$controller->setFromEmailAddress('invalid@email.com');
|
||||
}
|
||||
|
||||
private function setMailPoetSendingMethod() {
|
||||
$this->settings->set(
|
||||
Mailer::MAILER_CONFIG_SETTING_NAME,
|
||||
@ -172,7 +246,8 @@ class AuthorizedEmailsControllerTest extends \MailPoetTest {
|
||||
$getEmailsExpectaton = Expected::once($authorizedEmails);
|
||||
}
|
||||
$bridgeMock = $this->make(Bridge::class, ['getAuthorizedEmailAddresses' => $getEmailsExpectaton]);
|
||||
return new AuthorizedEmailsController($this->settings, $bridgeMock);
|
||||
$newslettersRepository = $this->diContainer->get(NewslettersRepository::class);
|
||||
return new AuthorizedEmailsController($this->settings, $bridgeMock, $newslettersRepository);
|
||||
}
|
||||
|
||||
public function _after() {
|
||||
|
Reference in New Issue
Block a user