Remove SPF notice
[MAILPOET-2867]
This commit is contained in:
@ -1,23 +0,0 @@
|
|||||||
import MailPoet from 'mailpoet';
|
|
||||||
import _ from 'underscore';
|
|
||||||
|
|
||||||
const getErrorMessage = (senderAddress) => `<h3>${MailPoet.I18n.t('spfCheckTitle')}</h3>
|
|
||||||
<p>${MailPoet.I18n.t('spfCheckMsgWhy').replace('%s', _.escape(senderAddress))}</p>
|
|
||||||
<p>${MailPoet.I18n.t('spfCheckMsgEdit').replace('%s', '<em>include:spf.sendingservice.net</em>')}</p>
|
|
||||||
<p><a class="button button-primary" href="https://kb.mailpoet.com/article/151-email-authentication-spf-and-dkim" target="_blank">${MailPoet.I18n.t('spfCheckReadMore')}</a></p>`;
|
|
||||||
|
|
||||||
const checkSPFRecord = () => MailPoet.Ajax.post({
|
|
||||||
api_version: window.mailpoet_api_version,
|
|
||||||
endpoint: 'services',
|
|
||||||
action: 'checkSPFRecord',
|
|
||||||
data: {},
|
|
||||||
}).fail((response) => {
|
|
||||||
if (response.meta.sender_address) {
|
|
||||||
MailPoet.Notice.system(
|
|
||||||
getErrorMessage(response.meta.sender_address),
|
|
||||||
{ static: true, scroll: true, id: 'spf_check_error' }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default checkSPFRecord;
|
|
@ -7,7 +7,6 @@ import Marionette from 'backbone.marionette';
|
|||||||
import SuperModel from 'backbone.supermodel';
|
import SuperModel from 'backbone.supermodel';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
import jQuery from 'jquery';
|
import jQuery from 'jquery';
|
||||||
import checkSPFRecord from 'common/check_spf_record.jsx';
|
|
||||||
|
|
||||||
var Module = {};
|
var Module = {};
|
||||||
var SidebarView;
|
var SidebarView;
|
||||||
@ -348,9 +347,6 @@ Module.SidebarPreviewView = Marionette.View.extend({
|
|||||||
'MailPoet Free version': window.mailpoet_version,
|
'MailPoet Free version': window.mailpoet_version,
|
||||||
'Domain name': data.subscriber.substring(data.subscriber.indexOf('@') + 1),
|
'Domain name': data.subscriber.substring(data.subscriber.indexOf('@') + 1),
|
||||||
});
|
});
|
||||||
if (App.getConfig().get('validation.validateSPFRecord')) {
|
|
||||||
checkSPFRecord();
|
|
||||||
}
|
|
||||||
}).fail(function (response) {
|
}).fail(function (response) {
|
||||||
if (response.errors.length > 0) {
|
if (response.errors.length > 0) {
|
||||||
MailPoet.Notice.error(
|
MailPoet.Notice.error(
|
||||||
|
@ -6,7 +6,6 @@ import { useSelector, useAction, useSetting } from 'settings/store/hooks';
|
|||||||
import { MssStatus } from 'settings/store/types';
|
import { MssStatus } from 'settings/store/types';
|
||||||
import { t } from 'common/functions';
|
import { t } from 'common/functions';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import checkSPFRecord from 'common/check_spf_record';
|
|
||||||
|
|
||||||
export default function SendWith() {
|
export default function SendWith() {
|
||||||
const isNewUser = useSelector('isNewUser')();
|
const isNewUser = useSelector('isNewUser')();
|
||||||
@ -23,8 +22,7 @@ export default function SendWith() {
|
|||||||
await setSetting(['mta', 'method'], 'MailPoet');
|
await setSetting(['mta', 'method'], 'MailPoet');
|
||||||
await setSetting(['mta', 'mailpoet_api_key'], key);
|
await setSetting(['mta', 'mailpoet_api_key'], key);
|
||||||
await setSetting(['signup_confirmation', 'enabled'], '1');
|
await setSetting(['signup_confirmation', 'enabled'], '1');
|
||||||
await saveSettings();
|
return saveSettings();
|
||||||
return checkSPFRecord();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -14,7 +14,6 @@ use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck;
|
|||||||
use MailPoet\Mailer\MailerLog;
|
use MailPoet\Mailer\MailerLog;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Services\CongratulatoryMssEmailController;
|
use MailPoet\Services\CongratulatoryMssEmailController;
|
||||||
use MailPoet\Services\SPFCheck;
|
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\WP\DateTime;
|
use MailPoet\WP\DateTime;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
@ -29,9 +28,6 @@ class Services extends APIEndpoint {
|
|||||||
/** @var AnalyticsHelper */
|
/** @var AnalyticsHelper */
|
||||||
private $analytics;
|
private $analytics;
|
||||||
|
|
||||||
/** @var SPFCheck */
|
|
||||||
private $spfCheck;
|
|
||||||
|
|
||||||
/** @var DateTime */
|
/** @var DateTime */
|
||||||
public $dateTime;
|
public $dateTime;
|
||||||
|
|
||||||
@ -58,7 +54,6 @@ class Services extends APIEndpoint {
|
|||||||
Bridge $bridge,
|
Bridge $bridge,
|
||||||
SettingsController $settings,
|
SettingsController $settings,
|
||||||
AnalyticsHelper $analytics,
|
AnalyticsHelper $analytics,
|
||||||
SPFCheck $spfCheck,
|
|
||||||
SendingServiceKeyCheck $mssWorker,
|
SendingServiceKeyCheck $mssWorker,
|
||||||
PremiumKeyCheck $premiumWorker,
|
PremiumKeyCheck $premiumWorker,
|
||||||
ServicesChecker $servicesChecker,
|
ServicesChecker $servicesChecker,
|
||||||
@ -68,7 +63,6 @@ class Services extends APIEndpoint {
|
|||||||
$this->bridge = $bridge;
|
$this->bridge = $bridge;
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
$this->analytics = $analytics;
|
$this->analytics = $analytics;
|
||||||
$this->spfCheck = $spfCheck;
|
|
||||||
$this->mssWorker = $mssWorker;
|
$this->mssWorker = $mssWorker;
|
||||||
$this->premiumWorker = $premiumWorker;
|
$this->premiumWorker = $premiumWorker;
|
||||||
$this->dateTime = new DateTime();
|
$this->dateTime = new DateTime();
|
||||||
@ -77,22 +71,6 @@ class Services extends APIEndpoint {
|
|||||||
$this->wp = $wp;
|
$this->wp = $wp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkSPFRecord($data = []) {
|
|
||||||
$senderAddress = $this->settings->get('sender.address');
|
|
||||||
$domainName = mb_substr($senderAddress, mb_strpos($senderAddress, '@') + 1);
|
|
||||||
|
|
||||||
$result = $this->spfCheck->checkSPFRecord($domainName);
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
return $this->errorResponse(
|
|
||||||
[APIError::BAD_REQUEST => $this->wp->__('SPF check has failed.', 'mailpoet')],
|
|
||||||
['sender_address' => $senderAddress]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->successResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkMSSKey($data = []) {
|
public function checkMSSKey($data = []) {
|
||||||
$key = isset($data['key']) ? trim($data['key']) : null;
|
$key = isset($data['key']) ? trim($data['key']) : null;
|
||||||
|
|
||||||
|
@ -239,7 +239,6 @@ class ContainerConfigurator implements IContainerConfigurator {
|
|||||||
$container->autowire(\MailPoet\Services\Bridge::class)->setPublic(true);
|
$container->autowire(\MailPoet\Services\Bridge::class)->setPublic(true);
|
||||||
$container->autowire(\MailPoet\Services\AuthorizedEmailsController::class);
|
$container->autowire(\MailPoet\Services\AuthorizedEmailsController::class);
|
||||||
$container->autowire(\MailPoet\Services\CongratulatoryMssEmailController::class);
|
$container->autowire(\MailPoet\Services\CongratulatoryMssEmailController::class);
|
||||||
$container->autowire(\MailPoet\Services\SPFCheck::class)->setPublic(true);
|
|
||||||
// Tasks
|
// Tasks
|
||||||
$container->autowire(\MailPoet\Tasks\State::class);
|
$container->autowire(\MailPoet\Tasks\State::class);
|
||||||
// Settings
|
// Settings
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace MailPoet\Services;
|
|
||||||
|
|
||||||
class SPFCheck {
|
|
||||||
public function checkSPFRecord($domain) {
|
|
||||||
$record = $this->getSPFRecord($domain);
|
|
||||||
if (empty($record)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return strpos($record, 'include:spf.sendingservice.net') !== false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getSPFRecord($domain) {
|
|
||||||
$records = $this->dnsGetRecord($domain, DNS_TXT);
|
|
||||||
if (empty($records[0])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
foreach ($records as $record) {
|
|
||||||
if (empty($record['txt']) || !preg_match('/^v=spf1/', trim($record['txt']))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return $record['txt'];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function dnsGetRecord($domain, $type) {
|
|
||||||
return dns_get_record($domain, $type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,7 +14,6 @@ use MailPoet\Mailer\Mailer;
|
|||||||
use MailPoet\Mailer\MailerLog;
|
use MailPoet\Mailer\MailerLog;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Services\CongratulatoryMssEmailController;
|
use MailPoet\Services\CongratulatoryMssEmailController;
|
||||||
use MailPoet\Services\SPFCheck;
|
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Settings\SettingsRepository;
|
use MailPoet\Settings\SettingsRepository;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
@ -32,32 +31,6 @@ class ServicesTest extends \MailPoetTest {
|
|||||||
$this->settings = SettingsController::getInstance();
|
$this->settings = SettingsController::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItRespondsWithErrorIfSPFCheckFails() {
|
|
||||||
$email = 'spf_test@example.com';
|
|
||||||
$this->settings->set('sender.address', $email);
|
|
||||||
|
|
||||||
$spfCheck = $this->make(
|
|
||||||
SPFCheck::class,
|
|
||||||
['checkSPFRecord' => false]
|
|
||||||
);
|
|
||||||
|
|
||||||
$servicesEndpoint = $this->createServicesEndpointWithMocks(['spfCheck' => $spfCheck]);
|
|
||||||
$response = $servicesEndpoint->checkSPFRecord([]);
|
|
||||||
expect($response->status)->equals(APIResponse::STATUS_NOT_FOUND);
|
|
||||||
expect($response->meta['sender_address'])->equals($email);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testItRespondsWithSuccessIfSPFCheckPasses() {
|
|
||||||
$spfCheck = $this->make(
|
|
||||||
SPFCheck::class,
|
|
||||||
['checkSPFRecord' => true]
|
|
||||||
);
|
|
||||||
|
|
||||||
$servicesEndpoint = $this->createServicesEndpointWithMocks(['spfCheck' => $spfCheck]);
|
|
||||||
$response = $servicesEndpoint->checkSPFRecord([]);
|
|
||||||
expect($response->status)->equals(APIResponse::STATUS_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testItRespondsWithErrorIfNoMSSKeyIsGiven() {
|
public function testItRespondsWithErrorIfNoMSSKeyIsGiven() {
|
||||||
$response = $this->diContainer->get(Services::class)->checkMSSKey(['key' => '']);
|
$response = $this->diContainer->get(Services::class)->checkMSSKey(['key' => '']);
|
||||||
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
||||||
@ -572,7 +545,6 @@ class ServicesTest extends \MailPoetTest {
|
|||||||
$mocks['bridge'] ?? $this->diContainer->get(Bridge::class),
|
$mocks['bridge'] ?? $this->diContainer->get(Bridge::class),
|
||||||
$this->diContainer->get(SettingsController::class),
|
$this->diContainer->get(SettingsController::class),
|
||||||
$this->diContainer->get(Analytics::class),
|
$this->diContainer->get(Analytics::class),
|
||||||
$mocks['spfCheck'] ?? $this->diContainer->get(SPFCheck::class),
|
|
||||||
$this->diContainer->get(SendingServiceKeyCheck::class),
|
$this->diContainer->get(SendingServiceKeyCheck::class),
|
||||||
$this->diContainer->get(PremiumKeyCheck::class),
|
$this->diContainer->get(PremiumKeyCheck::class),
|
||||||
$this->diContainer->get(ServicesChecker::class),
|
$this->diContainer->get(ServicesChecker::class),
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace MailPoet\Services;
|
|
||||||
|
|
||||||
class SPFCheckTest extends \MailPoetUnitTest {
|
|
||||||
public function testItChecksSPFRecord() {
|
|
||||||
$domain = 'example.com';
|
|
||||||
// Failed to get DNS records
|
|
||||||
$response = false;
|
|
||||||
$check = $this->make(SPFCheck::class, ['dnsGetRecord' => $response]);
|
|
||||||
expect($check->checkSPFRecord($domain))->equals(true);
|
|
||||||
// No SPF record
|
|
||||||
$response = [['txt' => '123'], ['txt' => 'abc']];
|
|
||||||
$check = $this->make(SPFCheck::class, ['dnsGetRecord' => $response]);
|
|
||||||
expect($check->checkSPFRecord($domain))->equals(true);
|
|
||||||
// Good SPF record
|
|
||||||
$response = [['txt' => 'v=spf1 include:spf.protection.outlook.com include:sendgrid.net include:spf.sendingservice.net -all']];
|
|
||||||
$check = $this->make(SPFCheck::class, ['dnsGetRecord' => $response]);
|
|
||||||
expect($check->checkSPFRecord($domain))->equals(true);
|
|
||||||
// Bad SPF record
|
|
||||||
$response = [['txt' => 'v=spf1 include:spf.protection.outlook.com include:sendgrid.net -all']];
|
|
||||||
$check = $this->make(SPFCheck::class, ['dnsGetRecord' => $response]);
|
|
||||||
expect($check->checkSPFRecord($domain))->equals(false);
|
|
||||||
}
|
|
||||||
}
|
|
@ -81,11 +81,6 @@ jQuery('.toplevel_page_mailpoet-newsletters.menu-top-last')
|
|||||||
'mailerSendingResumedNotice': __('Sending has been resumed.'),
|
'mailerSendingResumedNotice': __('Sending has been resumed.'),
|
||||||
'dismissNotice': __('Dismiss this notice.'),
|
'dismissNotice': __('Dismiss this notice.'),
|
||||||
|
|
||||||
'spfCheckTitle': _x('Improve your deliverability!', 'DNS SPF Record check'),
|
|
||||||
'spfCheckMsgWhy': _x("Your email is set to be sent from %s and we noticed that you have an SPF record for this domain. It means some subscribers may not receive your emails.", 'DNS SPF Record check'),
|
|
||||||
'spfCheckMsgEdit': _x("Since you're sending with the MailPoet Sending Service, you need to add %s to the existing SPF entry in your DNS records. This will allow MailPoet to send on your behalf for optimal deliverability.", 'DNS SPF Record check'),
|
|
||||||
'spfCheckReadMore': _x('Read the Guide', 'DNS SPF Record check'),
|
|
||||||
|
|
||||||
'subscribersLimitNoticeTitle': __('Congratulations, you now have more than [subscribersLimit] subscribers!'),
|
'subscribersLimitNoticeTitle': __('Congratulations, you now have more than [subscribersLimit] subscribers!'),
|
||||||
'freeVersionLimit': __('Our free version is limited to [subscribersLimit] subscribers.'),
|
'freeVersionLimit': __('Our free version is limited to [subscribersLimit] subscribers.'),
|
||||||
'yourPlanLimit': __('Your plan is limited to [subscribersLimit] subscribers.'),
|
'yourPlanLimit': __('Your plan is limited to [subscribersLimit] subscribers.'),
|
||||||
|
@ -1463,7 +1463,6 @@
|
|||||||
},
|
},
|
||||||
validation: {
|
validation: {
|
||||||
validateUnsubscribeLinkPresent: <%= mss_active and is_wc_transactional_email != true ? 'true' : 'false' %>,
|
validateUnsubscribeLinkPresent: <%= mss_active and is_wc_transactional_email != true ? 'true' : 'false' %>,
|
||||||
validateSPFRecord: <%= mss_active ? 'true' : 'false' %>,
|
|
||||||
},
|
},
|
||||||
urls: {
|
urls: {
|
||||||
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ (params('id') | intval)) %>',
|
send: '<%= admin_url('admin.php?page=mailpoet-newsletters#/send/' ~ (params('id') | intval)) %>',
|
||||||
|
@ -110,11 +110,6 @@ const baseConfig = {
|
|||||||
include: path.resolve(__dirname, 'assets/js/src/hooks.js'),
|
include: path.resolve(__dirname, 'assets/js/src/hooks.js'),
|
||||||
use: 'expose-loader?' + globalPrefix + '.Hooks',
|
use: 'expose-loader?' + globalPrefix + '.Hooks',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
// Expose for usage in the settings view inline JS
|
|
||||||
include: path.resolve(__dirname, 'assets/js/src/common/check_spf_record.jsx'),
|
|
||||||
use: 'expose-loader?' + globalPrefix + '.checkSPFRecord',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
test: /listing.jsx/i,
|
test: /listing.jsx/i,
|
||||||
use: [
|
use: [
|
||||||
@ -203,7 +198,6 @@ const adminConfig = {
|
|||||||
'help-tooltip.jsx',
|
'help-tooltip.jsx',
|
||||||
'listing/listing.jsx',
|
'listing/listing.jsx',
|
||||||
'newsletters/badges/stats.jsx',
|
'newsletters/badges/stats.jsx',
|
||||||
'common/check_spf_record.jsx',
|
|
||||||
],
|
],
|
||||||
admin: 'webpack_admin_index.jsx',
|
admin: 'webpack_admin_index.jsx',
|
||||||
newsletter_editor: 'newsletter_editor/webpack_index.jsx',
|
newsletter_editor: 'newsletter_editor/webpack_index.jsx',
|
||||||
|
Reference in New Issue
Block a user