Add honeypot field for spambot
[MAILPOET-1014]
This commit is contained in:
@ -66,6 +66,11 @@ class Subscribers extends APIEndpoint {
|
|||||||
APIError::BAD_REQUEST => __('Please specify a valid form ID.', 'mailpoet')
|
APIError::BAD_REQUEST => __('Please specify a valid form ID.', 'mailpoet')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if(!empty($data['email'])) {
|
||||||
|
return $this->badRequest(array(
|
||||||
|
APIError::BAD_REQUEST => __('Please leave the first field empty.', 'mailpoet')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$segment_ids = (!empty($data['segments'])
|
$segment_ids = (!empty($data['segments'])
|
||||||
? (array)$data['segments']
|
? (array)$data['segments']
|
||||||
@ -74,6 +79,8 @@ class Subscribers extends APIEndpoint {
|
|||||||
$segment_ids = $form->filterSegments($segment_ids);
|
$segment_ids = $form->filterSegments($segment_ids);
|
||||||
unset($data['segments']);
|
unset($data['segments']);
|
||||||
|
|
||||||
|
$data = $this->deobfuscateFormPayload($data);
|
||||||
|
|
||||||
if(empty($segment_ids)) {
|
if(empty($segment_ids)) {
|
||||||
return $this->badRequest(array(
|
return $this->badRequest(array(
|
||||||
APIError::BAD_REQUEST => __('Please select a list.', 'mailpoet')
|
APIError::BAD_REQUEST => __('Please select a list.', 'mailpoet')
|
||||||
@ -115,6 +122,18 @@ class Subscribers extends APIEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function deobfuscateFormPayload($data) {
|
||||||
|
$result = array();
|
||||||
|
foreach($data as $key => $value) {
|
||||||
|
if(strpos($key, 'form_field_') === 0) {
|
||||||
|
$result[base64_decode(substr($key, 11))] = $value;
|
||||||
|
} else {
|
||||||
|
$result[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
function save($data = array()) {
|
function save($data = array()) {
|
||||||
if(empty($data['segments'])) {
|
if(empty($data['segments'])) {
|
||||||
$data['segments'] = array();
|
$data['segments'] = array();
|
||||||
|
@ -104,7 +104,7 @@ abstract class Base {
|
|||||||
if((int)$block['id'] > 0) {
|
if((int)$block['id'] > 0) {
|
||||||
return 'cf_'.$block['id'];
|
return 'cf_'.$block['id'];
|
||||||
} else {
|
} else {
|
||||||
return $block['id'];
|
return 'form_field_'.base64_encode($block['id']);//obfuscate field name for spambots
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ class Renderer {
|
|||||||
$styles = new Util\Styles(static::getStyles($form));
|
$styles = new Util\Styles(static::getStyles($form));
|
||||||
|
|
||||||
$html = '<style type="text/css">';
|
$html = '<style type="text/css">';
|
||||||
|
$html .= '.mailpoet_hp_email_label{position: absolute;left: -999em;}';// move honeypot field out of the sight
|
||||||
$html .= $styles->render($prefix);
|
$html .= $styles->render($prefix);
|
||||||
$html .= '</style>';
|
$html .= '</style>';
|
||||||
|
|
||||||
@ -38,7 +39,8 @@ class Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static function renderBlocks($blocks = array()) {
|
static function renderBlocks($blocks = array()) {
|
||||||
$html = '';
|
// this is a honeypot for spambots
|
||||||
|
$html = '<label class="mailpoet_hp_email_label">Please leave this field empty<input type="email" name="data[email]"></label>';
|
||||||
foreach($blocks as $key => $block) {
|
foreach($blocks as $key => $block) {
|
||||||
$html .= static::renderBlock($block)."\n";
|
$html .= static::renderBlock($block)."\n";
|
||||||
}
|
}
|
||||||
|
@ -390,10 +390,22 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
expect($response->errors[0]['message'])->contains('has no method');
|
expect($response->errors[0]['message'])->contains('has no method');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testItFailsWithEmailFilled() {
|
||||||
|
$router = new Subscribers();
|
||||||
|
$response = $router->subscribe(array(
|
||||||
|
'form_id' => $this->form->id,
|
||||||
|
'email' => 'toto@mailpoet.com'
|
||||||
|
// no form ID specified
|
||||||
|
));
|
||||||
|
|
||||||
|
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
||||||
|
expect($response->errors[0]['message'])->equals('Please leave the first field empty.');
|
||||||
|
}
|
||||||
|
|
||||||
function testItCannotSubscribeWithoutFormID() {
|
function testItCannotSubscribeWithoutFormID() {
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com'
|
'form_field_ZW1haWw' => 'toto@mailpoet.com'
|
||||||
// no form ID specified
|
// no form ID specified
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -404,7 +416,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
function testItCannotSubscribeWithoutSegmentsIfTheyAreSelectedByUser() {
|
function testItCannotSubscribeWithoutSegmentsIfTheyAreSelectedByUser() {
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'form_field_ZW1haWw=' => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id
|
'form_id' => $this->form->id
|
||||||
// no segments specified
|
// no segments specified
|
||||||
));
|
));
|
||||||
@ -416,7 +428,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
function testItCanSubscribe() {
|
function testItCanSubscribe() {
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'form_field_ZW1haWw=' => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
@ -431,7 +443,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
|
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'form_field_ZW1haWw=' => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id
|
'form_id' => $this->form->id
|
||||||
// no segments specified
|
// no segments specified
|
||||||
));
|
));
|
||||||
@ -453,7 +465,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
|
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'form_field_ZW1haWw=' => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
@ -465,7 +477,7 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
function testItCanFilterOutNonFormFieldsWhenSubscribing() {
|
function testItCanFilterOutNonFormFieldsWhenSubscribing() {
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'form_field_ZW1haWw=' => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id),
|
'segments' => array($this->segment_1->id, $this->segment_2->id),
|
||||||
// exists in table and in the form
|
// exists in table and in the form
|
||||||
@ -486,14 +498,14 @@ class SubscribersTest extends \MailPoetTest {
|
|||||||
|
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'form_field_ZW1haWw=' => 'toto@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'tata@mailpoet.com',
|
'form_field_ZW1haWw=' => 'tata@mailpoet.com',
|
||||||
'form_id' => $this->form->id,
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
|
@ -11,6 +11,7 @@ use MailPoet\Util\Security;
|
|||||||
|
|
||||||
class FormTest extends \MailPoetTest {
|
class FormTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
|
$this->testEmail = 'test@example.com';
|
||||||
$this->segment = SegmentModel::createOrUpdate(
|
$this->segment = SegmentModel::createOrUpdate(
|
||||||
array(
|
array(
|
||||||
'name' => 'Test segment'
|
'name' => 'Test segment'
|
||||||
@ -34,7 +35,7 @@ class FormTest extends \MailPoetTest {
|
|||||||
'action' => 'mailpoet_subscription_form',
|
'action' => 'mailpoet_subscription_form',
|
||||||
'data' => array(
|
'data' => array(
|
||||||
'form_id' => $this->form->id,
|
'form_id' => $this->form->id,
|
||||||
'email' => 'test@example.com'
|
'form_field_ZW1haWw=' => $this->testEmail
|
||||||
),
|
),
|
||||||
'token' => Security::generateToken(),
|
'token' => Security::generateToken(),
|
||||||
'api_version' => 'v1',
|
'api_version' => 'v1',
|
||||||
@ -58,7 +59,7 @@ class FormTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
$result = Form::onSubmit($this->request_data);
|
$result = Form::onSubmit($this->request_data);
|
||||||
expect(SubscriberModel::findOne($this->request_data['data']['email']))->notEmpty();
|
expect(SubscriberModel::findOne($this->testEmail))->notEmpty();
|
||||||
$mock->verifyInvoked('redirectBack');
|
$mock->verifyInvoked('redirectBack');
|
||||||
expect($result['mailpoet_success'])->equals($this->form->id);
|
expect($result['mailpoet_success'])->equals($this->form->id);
|
||||||
expect($result['mailpoet_error'])->null();
|
expect($result['mailpoet_error'])->null();
|
||||||
@ -78,7 +79,7 @@ class FormTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
$result = Form::onSubmit($this->request_data);
|
$result = Form::onSubmit($this->request_data);
|
||||||
expect(SubscriberModel::findOne($this->request_data['data']['email']))->notEmpty();
|
expect(SubscriberModel::findOne($this->testEmail))->notEmpty();
|
||||||
$mock->verifyInvoked('redirectTo');
|
$mock->verifyInvoked('redirectTo');
|
||||||
expect($result)->regExp('/http.*?sample-post/i');
|
expect($result)->regExp('/http.*?sample-post/i');
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user