Version Description
- Security panel reorganized
- Added Akismet spam check
Download this release
Release Info
Developer | satollo |
Plugin | Newsletter |
Version | 5.3.2 |
Comparing to | |
See all releases |
Code changes from version 5.2.8 to 5.3.2
- includes/controls.php +4 -1
- includes/module.php +51 -9
- plugin.php +2 -2
- readme.txt +26 -2
- statistics/statistics.php +1 -2
- subscription/antibot.php +181 -0
- subscription/languages/en_US.php +5 -0
- subscription/options.php +3 -33
- subscription/subscription.php +134 -24
- tnp-header.php +3 -1
- users/edit.php +3 -0
includes/controls.php
CHANGED
@@ -814,6 +814,9 @@ class NewsletterControls {
|
|
814 |
|
815 |
function textarea($name, $width = '100%', $height = '50') {
|
816 |
$value = $this->get_value($name);
|
|
|
|
|
|
|
817 |
echo '<textarea id="options-' . esc_attr($name) . '" class="dynamic" name="options[' . esc_attr($name) . ']" wrap="off" style="width:' . esc_attr($width) . ';height:' . esc_attr($height) . '">';
|
818 |
echo esc_html($value);
|
819 |
echo '</textarea>';
|
@@ -1186,7 +1189,7 @@ class NewsletterControls {
|
|
1186 |
}
|
1187 |
echo '<script type="text/javascript">
|
1188 |
jQuery(document).ready(function(){
|
1189 |
-
|
1190 |
jQuery("textarea.dynamic").focus(function() {
|
1191 |
jQuery("textarea.dynamic").css("height", "50px");
|
1192 |
jQuery(this).css("height", "400px");
|
814 |
|
815 |
function textarea($name, $width = '100%', $height = '50') {
|
816 |
$value = $this->get_value($name);
|
817 |
+
if (is_array($value)) {
|
818 |
+
$value = implode("\n", $value);
|
819 |
+
}
|
820 |
echo '<textarea id="options-' . esc_attr($name) . '" class="dynamic" name="options[' . esc_attr($name) . ']" wrap="off" style="width:' . esc_attr($width) . ';height:' . esc_attr($height) . '">';
|
821 |
echo esc_html($value);
|
822 |
echo '</textarea>';
|
1189 |
}
|
1190 |
echo '<script type="text/javascript">
|
1191 |
jQuery(document).ready(function(){
|
1192 |
+
jQuery(".tnp-controls-color").wpColorPicker();
|
1193 |
jQuery("textarea.dynamic").focus(function() {
|
1194 |
jQuery("textarea.dynamic").css("height", "50px");
|
1195 |
jQuery(this).css("height", "400px");
|
includes/module.php
CHANGED
@@ -1132,17 +1132,45 @@ class NewsletterModule {
|
|
1132 |
return $text;
|
1133 |
}
|
1134 |
|
1135 |
-
public static function antibot_form_check() {
|
1136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1137 |
}
|
1138 |
|
1139 |
-
public static function request_to_antibot_form($submit_label = 'Continue...') {
|
1140 |
header('Content-Type: text/html;charset=UTF-8');
|
1141 |
header('X-Robots-Tag: noindex,nofollow,noarchive');
|
1142 |
header('Cache-Control: no-cache,no-store,private');
|
1143 |
echo "<!DOCTYPE html>\n";
|
1144 |
-
echo '<html><head
|
1145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1146 |
foreach ($_REQUEST as $name => $value) {
|
1147 |
if ($name == 'submit')
|
1148 |
continue;
|
@@ -1167,12 +1195,25 @@ class NewsletterModule {
|
|
1167 |
echo '<input type="hidden" name="nhr" value="' . esc_attr($_SERVER['HTTP_REFERER']) . '">';
|
1168 |
}
|
1169 |
echo '<input type="hidden" name="ts" value="' . time() . '">';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1170 |
echo '<noscript><input type="submit" value="';
|
1171 |
echo esc_attr($submit_label);
|
1172 |
echo '"></noscript></form>';
|
1173 |
echo '<script>';
|
1174 |
echo 'document.getElementById("form").action="' . home_url('/') . '";';
|
1175 |
-
|
|
|
|
|
|
|
1176 |
echo '</body></html>';
|
1177 |
die();
|
1178 |
}
|
@@ -1211,12 +1252,13 @@ class NewsletterModule {
|
|
1211 |
}
|
1212 |
return (int) $var;
|
1213 |
}
|
1214 |
-
|
1215 |
static function sanitize_ip($ip) {
|
1216 |
-
if (empty($ip))
|
|
|
1217 |
return preg_replace('/[^0-9a-fA-F:., ]/', '', $ip);
|
1218 |
}
|
1219 |
-
|
1220 |
static function get_remote_ip() {
|
1221 |
return self::sanitize_ip($_SERVER['REMOTE_ADDR']);
|
1222 |
}
|
1132 |
return $text;
|
1133 |
}
|
1134 |
|
1135 |
+
public static function antibot_form_check($captcha = false) {
|
1136 |
+
if (strtolower($_SERVER['REQUEST_METHOD']) != 'post') return false;
|
1137 |
+
|
1138 |
+
if (!isset($_POST['ts']) || time() - $_POST['ts'] > 60) {
|
1139 |
+
return false;
|
1140 |
+
}
|
1141 |
+
if ($captcha) {
|
1142 |
+
$n1 = (int) $_POST['n1'];
|
1143 |
+
if (empty($n1)) {
|
1144 |
+
return false;
|
1145 |
+
}
|
1146 |
+
$n2 = (int) $_POST['n2'];
|
1147 |
+
if (empty($n2)) {
|
1148 |
+
return false;
|
1149 |
+
}
|
1150 |
+
$n3 = (int) $_POST['n3'];
|
1151 |
+
if ($n1 + $n2 != $n3) {
|
1152 |
+
return false;
|
1153 |
+
}
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
return true;
|
1157 |
}
|
1158 |
|
1159 |
+
public static function request_to_antibot_form($submit_label = 'Continue...', $captcha = false) {
|
1160 |
header('Content-Type: text/html;charset=UTF-8');
|
1161 |
header('X-Robots-Tag: noindex,nofollow,noarchive');
|
1162 |
header('Cache-Control: no-cache,no-store,private');
|
1163 |
echo "<!DOCTYPE html>\n";
|
1164 |
+
echo '<html><head>'
|
1165 |
+
. '<style type="text/css">'
|
1166 |
+
. 'form {margin: 200px auto 0 auto !important; width: 350px !important; padding: 10px !important; font-family: "Open Sans", sans-serif; background: #ECF0F1; border-radius: 5px; padding: 50px !important; border: none !important;}'
|
1167 |
+
. 'p {text-align: center; padding: 10px; color: #7F8C8D;}'
|
1168 |
+
. 'input[type=text] {width: 50px; padding: 10px 10px; border: none; border-radius: 2px; margin: 0px 5px;}'
|
1169 |
+
. 'input[type=submit] {text-align: center; border: none; padding: 10px 15px; font-family: "Open Sans", sans-serif; background-color: #27AE60; color: white; cursor: pointer;}'
|
1170 |
+
. '</style>'
|
1171 |
+
. '</head><body>';
|
1172 |
+
echo '<form method="post" action="https://www.domain.tld" id="form">';
|
1173 |
+
echo '<div style="width: 1px; height: 1px; overflow: hidden">';
|
1174 |
foreach ($_REQUEST as $name => $value) {
|
1175 |
if ($name == 'submit')
|
1176 |
continue;
|
1195 |
echo '<input type="hidden" name="nhr" value="' . esc_attr($_SERVER['HTTP_REFERER']) . '">';
|
1196 |
}
|
1197 |
echo '<input type="hidden" name="ts" value="' . time() . '">';
|
1198 |
+
echo '</div>';
|
1199 |
+
if ($captcha) {
|
1200 |
+
echo '<p>Math question</p>';
|
1201 |
+
echo '<input type="text" name="n1" value="' . rand(1, 9) . '" readonly style="width: 50px">';
|
1202 |
+
echo '+';
|
1203 |
+
echo '<input type="text" name="n2" value="' . rand(1, 9) . '" readonly style="width: 50px">';
|
1204 |
+
echo '=';
|
1205 |
+
echo '<input type="text" name="n3" value="?" style="width: 50px">';
|
1206 |
+
echo ' <input type="submit" value="', esc_attr($submit_label), '">';
|
1207 |
+
}
|
1208 |
echo '<noscript><input type="submit" value="';
|
1209 |
echo esc_attr($submit_label);
|
1210 |
echo '"></noscript></form>';
|
1211 |
echo '<script>';
|
1212 |
echo 'document.getElementById("form").action="' . home_url('/') . '";';
|
1213 |
+
if (!$captcha) {
|
1214 |
+
echo 'document.getElementById("form").submit();';
|
1215 |
+
}
|
1216 |
+
echo '</script>';
|
1217 |
echo '</body></html>';
|
1218 |
die();
|
1219 |
}
|
1252 |
}
|
1253 |
return (int) $var;
|
1254 |
}
|
1255 |
+
|
1256 |
static function sanitize_ip($ip) {
|
1257 |
+
if (empty($ip))
|
1258 |
+
return $ip;
|
1259 |
return preg_replace('/[^0-9a-fA-F:., ]/', '', $ip);
|
1260 |
}
|
1261 |
+
|
1262 |
static function get_remote_ip() {
|
1263 |
return self::sanitize_ip($_SERVER['REMOTE_ADDR']);
|
1264 |
}
|
plugin.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
Plugin Name: Newsletter
|
5 |
Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
|
6 |
Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
|
7 |
-
Version: 5.2
|
8 |
Author: Stefano Lissa & The Newsletter Team
|
9 |
Author URI: https://www.thenewsletterplugin.com
|
10 |
Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
|
@@ -14,7 +14,7 @@
|
|
14 |
*/
|
15 |
|
16 |
// Used as dummy parameter on css and js links
|
17 |
-
define('NEWSLETTER_VERSION', '5.2
|
18 |
|
19 |
global $wpdb, $newsletter;
|
20 |
|
4 |
Plugin Name: Newsletter
|
5 |
Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
|
6 |
Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
|
7 |
+
Version: 5.3.2
|
8 |
Author: Stefano Lissa & The Newsletter Team
|
9 |
Author URI: https://www.thenewsletterplugin.com
|
10 |
Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
|
14 |
*/
|
15 |
|
16 |
// Used as dummy parameter on css and js links
|
17 |
+
define('NEWSLETTER_VERSION', '5.3.2');
|
18 |
|
19 |
global $wpdb, $newsletter;
|
20 |
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
|
3 |
Requires at least: 3.4.0
|
4 |
Tested up to: 4.9.4
|
5 |
-
Stable tag: 5.2
|
6 |
Contributors: satollo,webagile,michael-travan
|
7 |
|
8 |
Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
|
@@ -14,6 +14,7 @@ send and track e-mails, headache-free. It just works out of box!
|
|
14 |
|
15 |
= Main Features =
|
16 |
|
|
|
17 |
* **Responsive email Drag & Drop composer**
|
18 |
* **Unlimited subscribers** with statistics
|
19 |
* **Unlimited newsletter** with tracking
|
@@ -88,7 +89,30 @@ Thank you, The Newsletter Team
|
|
88 |
|
89 |
== Changelog ==
|
90 |
|
91 |
-
=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
* Improved block layout
|
94 |
* Added filter on profile url
|
2 |
Tags: newsletter,email,subscription,mass mail,list build,email marketing,direct mailing,automation,automated
|
3 |
Requires at least: 3.4.0
|
4 |
Tested up to: 4.9.4
|
5 |
+
Stable tag: 5.3.2
|
6 |
Contributors: satollo,webagile,michael-travan
|
7 |
|
8 |
Add a real newsletter system to your blog. For free. With unlimited newsletters and subscribers.
|
14 |
|
15 |
= Main Features =
|
16 |
|
17 |
+
* Subscription spam check with domain/ip black lists, Akismet, captcha
|
18 |
* **Responsive email Drag & Drop composer**
|
19 |
* **Unlimited subscribers** with statistics
|
20 |
* **Unlimited newsletter** with tracking
|
89 |
|
90 |
== Changelog ==
|
91 |
|
92 |
+
= 5.3.2 =
|
93 |
+
|
94 |
+
* Security panel reorganized
|
95 |
+
* Added Akismet spam check
|
96 |
+
|
97 |
+
= 5.3.1 =
|
98 |
+
|
99 |
+
* Name and last name check for spam
|
100 |
+
* 404 responses on error condition
|
101 |
+
* jQuery fix
|
102 |
+
* Email cleanup on admin edit panel
|
103 |
+
* Name check for spam on subscription
|
104 |
+
|
105 |
+
= 5.3.0 =
|
106 |
+
|
107 |
+
* CAPTCHA system
|
108 |
+
* IP black list
|
109 |
+
* Email address black list
|
110 |
+
|
111 |
+
= 5.2.8 =
|
112 |
+
|
113 |
+
* Redirect fix
|
114 |
+
|
115 |
+
= 5.2.7 =
|
116 |
|
117 |
* Improved block layout
|
118 |
* Added filter on profile url
|
statistics/statistics.php
CHANGED
@@ -119,8 +119,7 @@ class NewsletterStatistics extends NewsletterModule {
|
|
119 |
|
120 |
$wpdb->query($wpdb->prepare("update " . NEWSLETTER_SENT_TABLE . " set open=2, ip=%s where email_id=%d and user_id=%d limit 1", $ip, $email_id, $user_id));
|
121 |
|
122 |
-
|
123 |
-
|
124 |
die();
|
125 |
}
|
126 |
|
119 |
|
120 |
$wpdb->query($wpdb->prepare("update " . NEWSLETTER_SENT_TABLE . " set open=2, ip=%s where email_id=%d and user_id=%d limit 1", $ip, $email_id, $user_id));
|
121 |
|
122 |
+
header('Location: ' . apply_filters('newsletter_redirect_url', $url, $email, $user));
|
|
|
123 |
die();
|
124 |
}
|
125 |
|
subscription/antibot.php
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if (!defined('ABSPATH'))
|
3 |
+
exit;
|
4 |
+
|
5 |
+
@include_once NEWSLETTER_INCLUDES_DIR . '/controls.php';
|
6 |
+
$controls = new NewsletterControls();
|
7 |
+
$module = NewsletterSubscription::instance();
|
8 |
+
|
9 |
+
// TODO: Remove and use the $module->options.
|
10 |
+
$options = get_option('newsletter', array());
|
11 |
+
|
12 |
+
if ($controls->is_action()) {
|
13 |
+
|
14 |
+
if ($controls->is_action('save')) {
|
15 |
+
|
16 |
+
$blacklist = trim($controls->data['ip_blacklist']);
|
17 |
+
if (empty($blacklist))
|
18 |
+
$blacklist = array();
|
19 |
+
else {
|
20 |
+
$blacklist = preg_split("/\\r\\n/", $blacklist);
|
21 |
+
$blacklist = array_map('trim', $blacklist);
|
22 |
+
$blacklist = array_map('strtolower', $blacklist);
|
23 |
+
$blacklist = array_filter($blacklist);
|
24 |
+
|
25 |
+
$controls->data['ip_blacklist'] = $blacklist;
|
26 |
+
}
|
27 |
+
|
28 |
+
$blacklist = trim($controls->data['address_blacklist']);
|
29 |
+
if (empty($blacklist))
|
30 |
+
$blacklist = array();
|
31 |
+
else {
|
32 |
+
$blacklist = preg_split("/\\r\\n/", $blacklist);
|
33 |
+
$blacklist = array_map('trim', $blacklist);
|
34 |
+
$blacklist = array_map('strtolower', $blacklist);
|
35 |
+
$blacklist = array_filter($blacklist);
|
36 |
+
|
37 |
+
$controls->data['address_blacklist'] = $blacklist;
|
38 |
+
}
|
39 |
+
|
40 |
+
$module->merge_options($controls->data);
|
41 |
+
$controls->add_message_saved();
|
42 |
+
}
|
43 |
+
} else {
|
44 |
+
$controls->data = get_option('newsletter', array());
|
45 |
+
}
|
46 |
+
?>
|
47 |
+
|
48 |
+
<div class="wrap" id="tnp-wrap">
|
49 |
+
|
50 |
+
<?php include NEWSLETTER_DIR . '/tnp-header.php'; ?>
|
51 |
+
|
52 |
+
<div id="tnp-heading">
|
53 |
+
|
54 |
+
<h2><?php _e('Security', 'newsletter') ?></h2>
|
55 |
+
<?php $controls->page_help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
|
56 |
+
|
57 |
+
</div>
|
58 |
+
|
59 |
+
<div id="tnp-body">
|
60 |
+
|
61 |
+
<form method="post" action="">
|
62 |
+
<?php $controls->init(); ?>
|
63 |
+
|
64 |
+
|
65 |
+
<p>
|
66 |
+
<?php $controls->button_save() ?>
|
67 |
+
</p>
|
68 |
+
|
69 |
+
<div id="tabs">
|
70 |
+
<ul>
|
71 |
+
<li><a href="#tabs-general"><?php _e('Security', 'newsletter') ?></a></li>
|
72 |
+
<li><a href="#tabs-blacklists"><?php _e('Blacklists', 'newsletter') ?></a></li>
|
73 |
+
</ul>
|
74 |
+
|
75 |
+
<div id="tabs-general">
|
76 |
+
|
77 |
+
|
78 |
+
<table class="form-table">
|
79 |
+
<tr>
|
80 |
+
<th><?php _e('Disable antibot/antispam?', 'newsletter') ?></th>
|
81 |
+
<td>
|
82 |
+
<?php $controls->yesno('antibot_disable'); ?>
|
83 |
+
<p class="description">
|
84 |
+
<?php _e('Disable for ajax form submission', 'newsletter'); ?>
|
85 |
+
</p>
|
86 |
+
</td>
|
87 |
+
</tr>
|
88 |
+
|
89 |
+
<tr>
|
90 |
+
<th>Akismet</th>
|
91 |
+
<td>
|
92 |
+
<?php
|
93 |
+
$controls->select('akismet', array(
|
94 |
+
0 => __('Disabled', 'newsletter'),
|
95 |
+
1 => __('Enabled', 'newsletter')
|
96 |
+
));
|
97 |
+
?>
|
98 |
+
<?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
|
99 |
+
</td>
|
100 |
+
</tr>
|
101 |
+
|
102 |
+
<tr>
|
103 |
+
<th><?php _e('Antiflood', 'newsletter') ?></th>
|
104 |
+
<td>
|
105 |
+
<?php
|
106 |
+
$controls->select('antiflood', array(
|
107 |
+
0 => __('Disabled', 'newsletter'),
|
108 |
+
5 => '5 ' . __('seconds', 'newsletter'),
|
109 |
+
10 => '10 ' . __('seconds', 'newsletter'),
|
110 |
+
15 => '15 ' . __('seconds', 'newsletter'),
|
111 |
+
30 => '30 ' . __('seconds', 'newsletter'),
|
112 |
+
60 => '1 ' . __('minute', 'newsletter'),
|
113 |
+
120 => '2 ' . __('minutes', 'newsletter'),
|
114 |
+
300 => '5 ' . __('minutes', 'newsletter'),
|
115 |
+
600 => '10 ' . __('minutes', 'newsletter'),
|
116 |
+
900 => '15 ' . __('minutes', 'newsletter'),
|
117 |
+
1800 => '30 ' . __('minutes', 'newsletter')
|
118 |
+
));
|
119 |
+
?>
|
120 |
+
<?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
|
121 |
+
</td>
|
122 |
+
</tr>
|
123 |
+
<tr>
|
124 |
+
<th><?php _e('Captcha', 'newsletter') ?></th>
|
125 |
+
<td>
|
126 |
+
<?php
|
127 |
+
$controls->enabled('captcha');
|
128 |
+
?>
|
129 |
+
</td>
|
130 |
+
</tr>
|
131 |
+
<?php /*
|
132 |
+
<tr>
|
133 |
+
<th><?php _e('Domain check', 'newsletter') ?></th>
|
134 |
+
<td>
|
135 |
+
<?php
|
136 |
+
$controls->yesno('domain_check');
|
137 |
+
?>
|
138 |
+
</td>
|
139 |
+
</tr>
|
140 |
+
*/ ?>
|
141 |
+
|
142 |
+
</table>
|
143 |
+
|
144 |
+
|
145 |
+
</div>
|
146 |
+
|
147 |
+
<div id="tabs-blacklists">
|
148 |
+
<table class="form-table">
|
149 |
+
<tr>
|
150 |
+
<th><?php _e('IP black list', 'newsletter') ?></th>
|
151 |
+
<td>
|
152 |
+
<?php
|
153 |
+
$controls->textarea('ip_blacklist');
|
154 |
+
?>
|
155 |
+
<?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
|
156 |
+
</td>
|
157 |
+
</tr>
|
158 |
+
<tr>
|
159 |
+
<th><?php _e('Address black list', 'newsletter') ?></th>
|
160 |
+
<td>
|
161 |
+
<?php
|
162 |
+
$controls->textarea('address_blacklist');
|
163 |
+
?>
|
164 |
+
<?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
|
165 |
+
</td>
|
166 |
+
</tr>
|
167 |
+
</table>
|
168 |
+
</div>
|
169 |
+
|
170 |
+
</div>
|
171 |
+
|
172 |
+
<p>
|
173 |
+
<?php $controls->button_save() ?>
|
174 |
+
</p>
|
175 |
+
|
176 |
+
</form>
|
177 |
+
</div>
|
178 |
+
|
179 |
+
<?php include NEWSLETTER_DIR . '/tnp-footer.php'; ?>
|
180 |
+
|
181 |
+
</div>
|
subscription/languages/en_US.php
CHANGED
@@ -14,6 +14,11 @@ $options = array();
|
|
14 |
|
15 |
$options['noconfirmation'] = 0;
|
16 |
$options['antiflood'] = 10;
|
|
|
|
|
|
|
|
|
|
|
17 |
$options['notify_email'] = get_option('admin_email');
|
18 |
|
19 |
// Profile page
|
14 |
|
15 |
$options['noconfirmation'] = 0;
|
16 |
$options['antiflood'] = 10;
|
17 |
+
$options['ip_blacklist'] = array();
|
18 |
+
$options['address_blacklist'] = array();
|
19 |
+
$options['domain_check'] = 0;
|
20 |
+
$options['akismet'] = 0;
|
21 |
+
$options['captcha'] = 0;
|
22 |
$options['notify_email'] = get_option('admin_email');
|
23 |
|
24 |
// Profile page
|
subscription/options.php
CHANGED
@@ -253,36 +253,6 @@ if (empty($controls->data['page'])) {
|
|
253 |
<?php $controls->preferences(); ?>
|
254 |
</td>
|
255 |
</tr>
|
256 |
-
<tr>
|
257 |
-
<th><?php _e('Disable antibot/antispam?', 'newsletter') ?></th>
|
258 |
-
<td>
|
259 |
-
<?php $controls->yesno('antibot_disable'); ?>
|
260 |
-
<p class="description">
|
261 |
-
<?php _e ('Disable for ajax form submission', 'newsletter'); ?>
|
262 |
-
</p>
|
263 |
-
</td>
|
264 |
-
</tr>
|
265 |
-
<tr>
|
266 |
-
<th><?php _e('Antiflood', 'newsletter') ?></th>
|
267 |
-
<td>
|
268 |
-
<?php
|
269 |
-
$controls->select('antiflood', array(
|
270 |
-
0 => __('Disabled', 'newsletter'),
|
271 |
-
5 => '5 ' . __('seconds', 'newsletter'),
|
272 |
-
10 => '10 ' . __('seconds', 'newsletter'),
|
273 |
-
15 => '15 ' . __('seconds', 'newsletter'),
|
274 |
-
30 => '30 ' . __('seconds', 'newsletter'),
|
275 |
-
60 => '1 ' . __('minute', 'newsletter'),
|
276 |
-
120 => '2 ' . __('minutes', 'newsletter'),
|
277 |
-
300 => '5 ' . __('minutes', 'newsletter'),
|
278 |
-
600 => '10 ' . __('minutes', 'newsletter'),
|
279 |
-
900 => '15 ' . __('minutes', 'newsletter'),
|
280 |
-
1800 => '30 ' . __('minutes', 'newsletter')
|
281 |
-
));
|
282 |
-
?>
|
283 |
-
<?php $controls->help('https://www.thenewsletterplugin.com/documentation/antiflood') ?>
|
284 |
-
</td>
|
285 |
-
</tr>
|
286 |
</table>
|
287 |
|
288 |
<h3>Special cases</h3>
|
@@ -313,10 +283,10 @@ if (empty($controls->data['page'])) {
|
|
313 |
|
314 |
|
315 |
<div id="tabs-3">
|
316 |
-
|
317 |
<p><?php _e('Only for double opt-in mode.', 'newsletter') ?></p>
|
318 |
<?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/subscription#activation') ?>
|
319 |
-
|
320 |
<table class="form-table">
|
321 |
<tr>
|
322 |
<th><?php _e('Activation message', 'newsletter') ?></th>
|
@@ -367,7 +337,7 @@ if (empty($controls->data['page'])) {
|
|
367 |
|
368 |
<tr>
|
369 |
<th><?php _e('Conversion tracking code', 'newsletter') ?>
|
370 |
-
|
371 |
<td>
|
372 |
<?php $controls->textarea('confirmed_tracking'); ?>
|
373 |
</td>
|
253 |
<?php $controls->preferences(); ?>
|
254 |
</td>
|
255 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
</table>
|
257 |
|
258 |
<h3>Special cases</h3>
|
283 |
|
284 |
|
285 |
<div id="tabs-3">
|
286 |
+
|
287 |
<p><?php _e('Only for double opt-in mode.', 'newsletter') ?></p>
|
288 |
<?php $controls->panel_help('https://www.thenewsletterplugin.com/documentation/subscription#activation') ?>
|
289 |
+
|
290 |
<table class="form-table">
|
291 |
<tr>
|
292 |
<th><?php _e('Activation message', 'newsletter') ?></th>
|
337 |
|
338 |
<tr>
|
339 |
<th><?php _e('Conversion tracking code', 'newsletter') ?>
|
340 |
+
<?php $controls->help('https://www.thenewsletterplugin.com/documentation/subscription#conversion') ?></th>
|
341 |
<td>
|
342 |
<?php $controls->textarea('confirmed_tracking'); ?>
|
343 |
</td>
|
subscription/subscription.php
CHANGED
@@ -23,7 +23,7 @@ class NewsletterSubscription extends NewsletterModule {
|
|
23 |
|
24 |
function __construct() {
|
25 |
|
26 |
-
parent::__construct('subscription', '2.0.
|
27 |
|
28 |
// Must be called after the Newsletter::hook_init, since some constants are defined
|
29 |
// there.
|
@@ -80,6 +80,19 @@ class NewsletterSubscription extends NewsletterModule {
|
|
80 |
wp_localize_script('newsletter-subscription', 'newsletter', $data);
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
function hook_wp_loaded() {
|
84 |
global $newsletter, $wpdb;
|
85 |
|
@@ -90,7 +103,7 @@ class NewsletterSubscription extends NewsletterModule {
|
|
90 |
if (!$user || $user->status != 'C') {
|
91 |
die('Subscriber not found or not active.');
|
92 |
}
|
93 |
-
|
94 |
$email = $this->get_email_from_request();
|
95 |
if (!$email) {
|
96 |
die('Newsletter not found');
|
@@ -104,9 +117,9 @@ class NewsletterSubscription extends NewsletterModule {
|
|
104 |
if (!$list || $list['status'] == 0) {
|
105 |
die('Private list.');
|
106 |
}
|
107 |
-
|
108 |
$url = $_REQUEST['redirect'];
|
109 |
-
|
110 |
$this->set_user_list($user, $list_id, $_REQUEST['value']);
|
111 |
NewsletterStatistics::instance()->add_click(wp_sanitize_redirect($url), $user->id, $email->id);
|
112 |
wp_safe_redirect($url);
|
@@ -125,30 +138,126 @@ class NewsletterSubscription extends NewsletterModule {
|
|
125 |
// normal subscription
|
126 |
case 's':
|
127 |
case 'subscribe':
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
}
|
138 |
|
139 |
-
|
140 |
-
$user = $this->subscribe();
|
141 |
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
} else {
|
151 |
-
|
|
|
|
|
|
|
|
|
152 |
}
|
153 |
die();
|
154 |
|
@@ -299,6 +408,7 @@ class NewsletterSubscription extends NewsletterModule {
|
|
299 |
|
300 |
function admin_menu() {
|
301 |
$this->add_menu_page('options', 'List building');
|
|
|
302 |
$this->add_admin_page('profile', 'Subscription Form');
|
303 |
$this->add_admin_page('forms', 'Forms');
|
304 |
$this->add_admin_page('lists', 'Lists');
|
23 |
|
24 |
function __construct() {
|
25 |
|
26 |
+
parent::__construct('subscription', '2.0.4');
|
27 |
|
28 |
// Must be called after the Newsletter::hook_init, since some constants are defined
|
29 |
// there.
|
80 |
wp_localize_script('newsletter-subscription', 'newsletter', $data);
|
81 |
}
|
82 |
|
83 |
+
function ip_match($ip, $range) {
|
84 |
+
if (strpos($range, '/')) {
|
85 |
+
list ($subnet, $bits) = explode('/', $range);
|
86 |
+
$ip = ip2long($ip);
|
87 |
+
$subnet = ip2long($subnet);
|
88 |
+
$mask = -1 << (32 - $bits);
|
89 |
+
$subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
|
90 |
+
return ($ip & $mask) == $subnet;
|
91 |
+
} else {
|
92 |
+
return strpos($range, $ip) === 0;
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
function hook_wp_loaded() {
|
97 |
global $newsletter, $wpdb;
|
98 |
|
103 |
if (!$user || $user->status != 'C') {
|
104 |
die('Subscriber not found or not active.');
|
105 |
}
|
106 |
+
|
107 |
$email = $this->get_email_from_request();
|
108 |
if (!$email) {
|
109 |
die('Newsletter not found');
|
117 |
if (!$list || $list['status'] == 0) {
|
118 |
die('Private list.');
|
119 |
}
|
120 |
+
|
121 |
$url = $_REQUEST['redirect'];
|
122 |
+
|
123 |
$this->set_user_list($user, $list_id, $_REQUEST['value']);
|
124 |
NewsletterStatistics::instance()->add_click(wp_sanitize_redirect($url), $user->id, $email->id);
|
125 |
wp_safe_redirect($url);
|
138 |
// normal subscription
|
139 |
case 's':
|
140 |
case 'subscribe':
|
141 |
+
|
142 |
+
$ip = $this->get_remote_ip();
|
143 |
+
$email = $this->normalize_email($_REQUEST['ne']);
|
144 |
+
$first_name = '';
|
145 |
+
if (isset($_REQUEST['nn'])) $first_name = $this->normalize_name($_REQUEST['nn']);
|
146 |
+
|
147 |
+
$last_name = '';
|
148 |
+
if (isset($_REQUEST['ns'])) $last_name = $this->normalize_name($_REQUEST['ns']);
|
149 |
+
|
150 |
+
$full_name = trim($first_name . ' ' . $last_name);
|
151 |
+
|
152 |
+
$antibot_logger = new NewsletterLogger('antibot');
|
153 |
+
|
154 |
+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
155 |
+
$antibot_logger->fatal($email . ' - ' . $ip . ' - HTTP method invalid');
|
156 |
+
die('Invalid');
|
157 |
}
|
158 |
|
159 |
+
$captcha = !empty($this->options['captcha']);
|
|
|
160 |
|
161 |
+
if (!empty($this->options['antibot_disable']) || $this->antibot_form_check($captcha)) {
|
162 |
+
|
163 |
+
|
164 |
+
if (stripos($full_name, 'http://') !== false || stripos($full_name, 'https://') !== false) {
|
165 |
+
$antibot_logger->fatal($email . ' - ' . $ip . ' - Name with http: ' . $full_name);
|
166 |
+
header("HTTP/1.0 404 Not Found");
|
167 |
+
die();
|
168 |
+
}
|
169 |
+
|
170 |
+
|
171 |
+
|
172 |
+
// Cannot check for administrator here, too early.
|
173 |
+
if (true) {
|
174 |
+
|
175 |
+
$this->logger->debug('Subscription of: ' . $email);
|
176 |
+
// if ($this->options['domain_check']) {
|
177 |
+
// $this->logger->debug('Domain checking');
|
178 |
+
// list($local, $domain) = explode('@', $email);
|
179 |
+
//
|
180 |
+
// $hosts = array();
|
181 |
+
// if (!getmxrr($domain, $hosts)) {
|
182 |
+
// $antibot_logger->fatal($email . ' - ' . $ip . ' - MX check failed');
|
183 |
+
// die('Blocked 0');
|
184 |
+
// }
|
185 |
+
// }
|
186 |
+
|
187 |
+
if (!empty($this->options['ip_blacklist'])) {
|
188 |
+
$this->logger->debug('IP blacklist check');
|
189 |
+
foreach ($this->options['ip_blacklist'] as $item) {
|
190 |
+
if ($this->ip_match($ip, $item)) {
|
191 |
+
$antibot_logger->fatal($email . ' - ' . $ip . ' - IP blacklisted');
|
192 |
+
header("HTTP/1.0 404 Not Found");
|
193 |
+
die();
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
if (!empty($this->options['address_blacklist'])) {
|
199 |
+
$this->logger->debug('Address blacklist check');
|
200 |
+
$rev_email = strrev($email);
|
201 |
+
foreach ($this->options['address_blacklist'] as $item) {
|
202 |
+
if (strpos($rev_email, strrev($item)) === 0) {
|
203 |
+
$antibot_logger->fatal($email . ' - ' . $ip . ' - Address blacklisted');
|
204 |
+
header("HTTP/1.0 404 Not Found");
|
205 |
+
die();
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
// Akismet check
|
211 |
+
if (!empty($this->options['akismet']) && class_exists('Akismet')) {
|
212 |
+
$this->logger->debug('Akismet check');
|
213 |
+
$request = 'blog=' . urlencode(home_url()) . '&referrer=' . urlencode($_SERVER['HTTP_REFERER']) .
|
214 |
+
'&user_agent=' . urlencode($_SERVER['HTTP_USER_AGENT']) .
|
215 |
+
'&comment_type=signup' .
|
216 |
+
'&comment_author_email=' . urlencode($email) .
|
217 |
+
'&user_ip=' . urlencode($_SERVER['REMOTE_ADDR']);
|
218 |
+
if (!empty($full_name)) {
|
219 |
+
$request .= '&comment_author=' . urlencode($full_name);
|
220 |
+
}
|
221 |
+
|
222 |
+
$response = Akismet::http_post($request, 'comment-check');
|
223 |
+
|
224 |
+
if ($response && $response[1] == 'true') {
|
225 |
+
$antibot_logger->fatal($email . ' - ' . $ip . ' - Akismet blocked');
|
226 |
+
header("HTTP/1.0 404 Not Found");
|
227 |
+
die();
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
// Flood check
|
232 |
+
if (!empty($this->options['antiflood'])) {
|
233 |
+
$this->logger->debug('Antiflood check');
|
234 |
+
$email = $this->is_email($_REQUEST['ne']);
|
235 |
+
$updated = $wpdb->get_var($wpdb->prepare("select updated from " . NEWSLETTER_USERS_TABLE . " where ip=%s or email=%s order by updated desc limit 1", $ip, $email));
|
236 |
+
|
237 |
+
if ($updated && time() - $updated < $this->options['antiflood']) {
|
238 |
+
$antibot_logger->fatal($email . ' - ' . $ip . ' - Antiflood triggered');
|
239 |
+
header("HTTP/1.0 404 Not Found");
|
240 |
+
die('Too quick');
|
241 |
+
}
|
242 |
+
}
|
243 |
+
|
244 |
+
$user = $this->subscribe();
|
245 |
+
|
246 |
+
if ($user->status == 'E')
|
247 |
+
$this->show_message('error', $user->id);
|
248 |
+
if ($user->status == 'C')
|
249 |
+
$this->show_message('confirmed', $user->id);
|
250 |
+
if ($user->status == 'A')
|
251 |
+
$this->show_message('already_confirmed', $user->id);
|
252 |
+
if ($user->status == 'S')
|
253 |
+
$this->show_message('confirmation', $user->id);
|
254 |
+
}
|
255 |
} else {
|
256 |
+
// Temporary store data
|
257 |
+
//$data_key = wp_generate_password(16, false, false);
|
258 |
+
//set_transient('newsletter_' . $data_key, $_REQUEST, 60);
|
259 |
+
//$this->antibot_redirect($data_key);
|
260 |
+
$this->request_to_antibot_form('Subscribe', $captcha);
|
261 |
}
|
262 |
die();
|
263 |
|
408 |
|
409 |
function admin_menu() {
|
410 |
$this->add_menu_page('options', 'List building');
|
411 |
+
$this->add_menu_page('antibot', 'Security');
|
412 |
$this->add_admin_page('profile', 'Subscription Form');
|
413 |
$this->add_admin_page('forms', 'Forms');
|
414 |
$this->add_admin_page('lists', 'Lists');
|
tnp-header.php
CHANGED
@@ -58,7 +58,9 @@ $warning |= empty($status_options['mail']);
|
|
58 |
<ul>
|
59 |
<li><a href="?page=newsletter_subscription_options"><i class="fa fa-sign-in"></i> <?php _e('Subscription', 'newsletter') ?>
|
60 |
<small><?php _e('The subscription process in detail', 'newsletter') ?></small></a></li>
|
61 |
-
|
|
|
|
|
62 |
|
63 |
<li>
|
64 |
<a href="?page=newsletter_subscription_profile"><i class="fa fa-check-square-o"></i> <?php _e('Subscription Form Fields, Buttons, Labels', 'newsletter') ?>
|
58 |
<ul>
|
59 |
<li><a href="?page=newsletter_subscription_options"><i class="fa fa-sign-in"></i> <?php _e('Subscription', 'newsletter') ?>
|
60 |
<small><?php _e('The subscription process in detail', 'newsletter') ?></small></a></li>
|
61 |
+
|
62 |
+
<li><a href="?page=newsletter_subscription_antibot"><i class="fa fa-lock"></i> <?php _e('Security', 'newsletter') ?>
|
63 |
+
<small><?php _e('Spam subscriptions control', 'newsletter') ?></small></a></li>
|
64 |
|
65 |
<li>
|
66 |
<a href="?page=newsletter_subscription_profile"><i class="fa fa-check-square-o"></i> <?php _e('Subscription Form Fields, Buttons, Labels', 'newsletter') ?>
|
users/edit.php
CHANGED
@@ -13,7 +13,10 @@ if ($controls->is_action('save')) {
|
|
13 |
$email = $module->normalize_email($controls->data['email']);
|
14 |
if (empty($email)) {
|
15 |
$controls->errors = __('Wrong email address', 'newsletter');
|
|
|
|
|
16 |
}
|
|
|
17 |
|
18 |
if (empty($controls->errors)) {
|
19 |
$user = $module->get_user($controls->data['email']);
|
13 |
$email = $module->normalize_email($controls->data['email']);
|
14 |
if (empty($email)) {
|
15 |
$controls->errors = __('Wrong email address', 'newsletter');
|
16 |
+
} else {
|
17 |
+
$controls->data['email'] = $email;
|
18 |
}
|
19 |
+
|
20 |
|
21 |
if (empty($controls->errors)) {
|
22 |
$user = $module->get_user($controls->data['email']);
|