diff --git a/lib/API/JSON/v1/Subscribers.php b/lib/API/JSON/v1/Subscribers.php
index fc161d0549..028d62213d 100644
--- a/lib/API/JSON/v1/Subscribers.php
+++ b/lib/API/JSON/v1/Subscribers.php
@@ -66,6 +66,11 @@ class Subscribers extends APIEndpoint {
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'])
? (array)$data['segments']
@@ -74,6 +79,8 @@ class Subscribers extends APIEndpoint {
$segment_ids = $form->filterSegments($segment_ids);
unset($data['segments']);
+ $data = $this->deobfuscateFormPayload($data);
+
if(empty($segment_ids)) {
return $this->badRequest(array(
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()) {
if(empty($data['segments'])) {
$data['segments'] = array();
diff --git a/lib/Form/Block/Base.php b/lib/Form/Block/Base.php
index 723433c5ea..39e6c5809d 100644
--- a/lib/Form/Block/Base.php
+++ b/lib/Form/Block/Base.php
@@ -104,7 +104,7 @@ abstract class Base {
if((int)$block['id'] > 0) {
return 'cf_'.$block['id'];
} else {
- return $block['id'];
+ return 'form_field_'.base64_encode($block['id']);//obfuscate field name for spambots
}
}
diff --git a/lib/Form/Renderer.php b/lib/Form/Renderer.php
index 1649520ad4..f301e4f96a 100644
--- a/lib/Form/Renderer.php
+++ b/lib/Form/Renderer.php
@@ -15,6 +15,7 @@ class Renderer {
$styles = new Util\Styles(static::getStyles($form));
$html = '';
@@ -38,7 +39,8 @@ class Renderer {
}
static function renderBlocks($blocks = array()) {
- $html = '';
+ // this is a honeypot for spambots
+ $html = '';
foreach($blocks as $key => $block) {
$html .= static::renderBlock($block)."\n";
}
diff --git a/tests/unit/API/JSON/v1/SubscribersTest.php b/tests/unit/API/JSON/v1/SubscribersTest.php
index d94d345b47..e49061d33e 100644
--- a/tests/unit/API/JSON/v1/SubscribersTest.php
+++ b/tests/unit/API/JSON/v1/SubscribersTest.php
@@ -390,10 +390,22 @@ class SubscribersTest extends \MailPoetTest {
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() {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com'
+ 'form_field_ZW1haWw' => 'toto@mailpoet.com'
// no form ID specified
));
@@ -404,7 +416,7 @@ class SubscribersTest extends \MailPoetTest {
function testItCannotSubscribeWithoutSegmentsIfTheyAreSelectedByUser() {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'toto@mailpoet.com',
'form_id' => $this->form->id
// no segments specified
));
@@ -416,7 +428,7 @@ class SubscribersTest extends \MailPoetTest {
function testItCanSubscribe() {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
));
@@ -431,7 +443,7 @@ class SubscribersTest extends \MailPoetTest {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'toto@mailpoet.com',
'form_id' => $this->form->id
// no segments specified
));
@@ -453,7 +465,7 @@ class SubscribersTest extends \MailPoetTest {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
));
@@ -465,7 +477,7 @@ class SubscribersTest extends \MailPoetTest {
function testItCanFilterOutNonFormFieldsWhenSubscribing() {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id),
// exists in table and in the form
@@ -486,14 +498,14 @@ class SubscribersTest extends \MailPoetTest {
$router = new Subscribers();
$response = $router->subscribe(array(
- 'email' => 'toto@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'toto@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
));
try {
$response = $router->subscribe(array(
- 'email' => 'tata@mailpoet.com',
+ 'form_field_ZW1haWw=' => 'tata@mailpoet.com',
'form_id' => $this->form->id,
'segments' => array($this->segment_1->id, $this->segment_2->id)
));
diff --git a/tests/unit/Subscription/FormTest.php b/tests/unit/Subscription/FormTest.php
index b115de96be..09d7abca88 100644
--- a/tests/unit/Subscription/FormTest.php
+++ b/tests/unit/Subscription/FormTest.php
@@ -11,6 +11,7 @@ use MailPoet\Util\Security;
class FormTest extends \MailPoetTest {
function _before() {
+ $this->testEmail = 'test@example.com';
$this->segment = SegmentModel::createOrUpdate(
array(
'name' => 'Test segment'
@@ -34,7 +35,7 @@ class FormTest extends \MailPoetTest {
'action' => 'mailpoet_subscription_form',
'data' => array(
'form_id' => $this->form->id,
- 'email' => 'test@example.com'
+ 'form_field_ZW1haWw=' => $this->testEmail
),
'token' => Security::generateToken(),
'api_version' => 'v1',
@@ -58,7 +59,7 @@ class FormTest extends \MailPoetTest {
}
]);
$result = Form::onSubmit($this->request_data);
- expect(SubscriberModel::findOne($this->request_data['data']['email']))->notEmpty();
+ expect(SubscriberModel::findOne($this->testEmail))->notEmpty();
$mock->verifyInvoked('redirectBack');
expect($result['mailpoet_success'])->equals($this->form->id);
expect($result['mailpoet_error'])->null();
@@ -78,7 +79,7 @@ class FormTest extends \MailPoetTest {
}
]);
$result = Form::onSubmit($this->request_data);
- expect(SubscriberModel::findOne($this->request_data['data']['email']))->notEmpty();
+ expect(SubscriberModel::findOne($this->testEmail))->notEmpty();
$mock->verifyInvoked('redirectTo');
expect($result)->regExp('/http.*?sample-post/i');
}