PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | WpInit/Router.php +65 -27 10.2.2 → 11.1.0 View file →
@@ -1,21 +1,24 @@
1 1 <?php
2 2
3 3 namespace AcyMailing\WpInit;
4 4
5 +defined('ABSPATH') || die('Restricted Access');
6 +
5 7 use AcyMailing\Classes\PluginClass;
6 8
7 9 class Router
8 10 {
9 - var $activation;
10 -
11 11 public function __construct()
12 12 {
13 + // Back router
13 14 add_action('wp_ajax_acymailing_router', [$this, 'router']);
15 + // Front router
14 16 if (!acym_isAdmin()) {
15 17 add_action('wp_loaded', [$this, 'frontRouter']);
16 18 }
17 19
20 + // Make sure we can redirect / download / modify headers if needed after some checks
18 21 $pages = [
19 22 'automation',
20 23 'bounces',
21 24 'campaigns',
@@ -53,10 +56,12 @@
53 56 'users',
54 57 ];
55 58 foreach ($pages as $page) {
56 59 if (in_array($page, $headerPages)) {
60 + // Ensure we can set headers in the plugin
57 61 add_action('load-acymailing_page_acymailing_'.$page, [$this, 'waitHeaders']);
58 62 }
63 + // Disable WP emojis in AcyMailing only
59 64 add_action('admin_print_scripts-acymailing_page_acymailing_'.$page, [$this, 'disableJsBreakingPages']);
60 65 add_action('admin_print_styles-acymailing_page_acymailing_'.$page, [$this, 'removeCssBreakingPages']);
61 66 }
62 67 add_action('admin_print_scripts-toplevel_page_acymailing_dashboard', [$this, 'disableJsBreakingPages']);
@@ -66,14 +71,18 @@
66 71 }
67 72
68 73 public function protectAcyMailingPages()
69 74 {
75 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Make sure we're on an AcyMailing page.
70 76 $page = isset($_REQUEST['page']) ? sanitize_text_field(wp_unslash($_REQUEST['page'])) : '';
71 - if (empty($page) || strpos($page, 'acymailing_') === false) return;
77 + if (empty($page) || strpos($page, 'acymailing_') === false) {
78 + return;
79 + }
72 80
73 81 wp_dequeue_script('responsive-lightbox-admin-select2');
74 82 wp_dequeue_style('responsive-lightbox-admin-select2');
75 83
84 + // Remove theme loading select2 from Supreme module pro for divi
76 85 wp_dequeue_script('dsm-select-two');
77 86 wp_dequeue_style('dsm-select-two');
78 87 }
79 88
@@ -83,20 +92,27 @@
83 92 }
84 93
85 94 public function disableJsBreakingPages()
86 95 {
96 + // Show normal emojis on AcyMailing pages
87 97 remove_action('admin_print_scripts', 'print_emoji_detection_script');
88 98
99 + // Slideshow ck breaks the editor
89 100 remove_action('wp_enqueue_media', '\\Slideshowck\\Tinymce\\register_scripts_styles');
90 101
102 + // Skaut Google Drive gallery breaks the editor
91 103 remove_action('wp_enqueue_media', '\\Sgdg\\Admin\\TinyMCE\\register_scripts_styles');
92 104
105 + // Remove theme loading select2 which breaks select2 in vueJS
93 106 wp_dequeue_script('select2.js');
94 107
108 + // The "Checkout Field Manager for WooCommerce" plugin breaks the js on every pages
95 109 wp_dequeue_script('checkout_fields_js');
96 110
111 + // Fixed editor incompatibility
97 112 wp_dequeue_script('wp-optimize-minify-admin-purge');
98 113
114 + // Remove Happy Elementor Addons select2 which breaks our select2
99 115 wp_dequeue_script('happy-elementor-addons-select2');
100 116 wp_dequeue_script('select2');
101 117 }
102 118
@@ -106,11 +122,13 @@
106 122 wp_dequeue_style('WP REST API Controller');
107 123 wp_dequeue_style('wpml-select-2');
108 124 wp_dequeue_style('swcfpc_admin_css');
109 125
126 + // Remove Happy Elementor Addons select2 which breaks our select2
110 127 wp_dequeue_style('happy-elementor-addons-select2');
111 128 wp_dequeue_style('select2');
112 129
130 + // Messes with the tooltips, the schedule date in emails for example
113 131 wp_dequeue_style('qlwapp-admin-menu');
114 132 }
115 133
116 134 public function frontRouter()
@@ -120,20 +138,27 @@
120 138
121 139 $this->router(true);
122 140 }
123 141
124 - public function router($front = false)
142 + public function router(bool $front = false): void
125 143 {
126 - displayFreeTrialMessage();
144 + acym_displayFreeTrialMessage();
127 145
128 146
129 - if (!$front) auth_redirect();
147 + if (!$front) {
148 + auth_redirect();
130 149
150 + // The router only enforces auth_redirect() and the 'dashboard' controller is exempt from call()'s ACL, so mirror Menu.php's back-office access gate (wp_access groups) to keep arbitrary logged-in users out.
151 + if (!acym_hasBackofficeAccess()) {
152 + wp_die(esc_html(acym_translation('ACYM_ACCESS_DENIED')), '', ['response' => 403]);
153 + }
154 + }
155 +
131 156 if (file_exists(ACYM_FOLDER.'update.php')) {
132 157 $acyActivation = new Activation();
133 158 if (is_multisite()) {
134 159 $currentBlog = get_current_blog_id();
135 - $sites = function_exists('get_sites') ? get_sites() : wp_get_sites();
160 + $sites = get_sites();
136 161
137 162 foreach ($sites as $site) {
138 163 if (is_object($site)) {
139 164 $site = get_object_vars($site);
@@ -147,17 +172,18 @@
147 172 } else {
148 173 $acyActivation->updateAcym();
149 174 }
150 175
151 - unlink(ACYM_FOLDER.'update.php');
176 + acym_deleteFile(ACYM_FOLDER.'update.php');
152 177 }
153 178
154 179 $config = acym_config(true);
155 180
181 + // Get controller. If not found, take it from the page
156 182 $ctrl = acym_getVar('cmd', 'ctrl', '');
157 183 $task = acym_getVar('cmd', 'task', '');
158 184
159 - if (!$front && acym_isAdmin() && file_exists(ACYM_NEW_FEATURES_SPLASHSCREEN_JSON) && is_writable(ACYM_NEW_FEATURES_SPLASHSCREEN_JSON)) {
185 + if (!$front && acym_isAdmin() && file_exists(ACYM_NEW_FEATURES_SPLASHSCREEN_JSON) && acym_isWritable(ACYM_NEW_FEATURES_SPLASHSCREEN_JSON)) {
160 186 $ctrl = 'dashboard';
161 187 $task = 'features';
162 188 acym_setVar('ctrl', $ctrl);
163 189 acym_setVar('task', $task);
@@ -173,10 +199,11 @@
173 199 if (empty($ctrl)) {
174 200 $ctrl = str_replace(ACYM_COMPONENT.'_', '', acym_getVar('cmd', 'page', ''));
175 201
176 202 if (empty($ctrl)) {
177 - echo acym_translation('ACYM_PAGE_NOT_FOUND');
203 + echo esc_html(acym_translation('ACYM_PAGE_NOT_FOUND'));
178 204
205 + // For Google search console in the frontend to prevent from doing 404 errors
179 206 $noCache = acym_getVar('int', 'nocache', 0);
180 207 if (!empty($noCache)) {
181 208 acym_redirect(acym_rootURI());
182 209 }
@@ -191,9 +218,9 @@
191 218 $subNamespace = $front ? 'Front' : '';
192 219 $controllerNamespace = 'AcyMailing\\'.$subNamespace.'Controllers\\'.ucfirst($ctrl).'Controller';
193 220
194 221 if (!class_exists($controllerNamespace)) {
195 - echo acym_translation('ACYM_PAGE_NOT_FOUND').': '.$ctrl;
222 + echo esc_html(acym_translation('ACYM_PAGE_NOT_FOUND').': '.$ctrl);
196 223
197 224 return;
198 225 }
199 226
@@ -199,18 +226,17 @@
199 226
200 227 if (!$front && acym_isAdmin() && $task != 'edit' && !(defined('DOING_AJAX') && DOING_AJAX)) {
201 228 $pluginClass = new PluginClass();
202 229 $installedPlugins = $pluginClass->getAll('title');
203 - $newPlugins = json_decode(ACYM_AVAILABLE_PLUGINS);
204 - foreach ($newPlugins as $onePlugin) {
205 - if (empty($installedPlugins[$onePlugin->name])) continue;
206 - if ($installedPlugins[$onePlugin->name]->type !== 'ADDON') continue;
230 + foreach (ACYM_AVAILABLE_PLUGINS as $onePlugin) {
231 + if (empty($installedPlugins[$onePlugin['name']])) continue;
232 + if ($installedPlugins[$onePlugin['name']]->type !== 'ADDON') continue;
207 233
208 234 acym_enqueueMessage(
209 235 acym_translationSprintf(
210 236 'ACYM_NEW_PLUGIN_FORMAT',
211 - $onePlugin->name,
212 - '<a target="_blank" style="color: #00a5ff;" href="'.$onePlugin->downloadlink.'">'.acym_translation('ACYM_CLICK_HERE').'</a>'
237 + $onePlugin['name'],
238 + '<a target="_blank" style="color: #00a5ff;" href="'.$onePlugin['downloadlink'].'">'.acym_translation('ACYM_CLICK_HERE').'</a>'
213 239 ),
214 240 'error'
215 241 );
216 242 }
@@ -225,17 +251,17 @@
225 251 $task = 'listing';
226 252 acym_setVar('task', $task);
227 253 }
228 254
229 - $controller->call($task);
255 + $controller->call($task, $front);
230 256 }
231 257
232 258 public function autologin()
233 259 {
234 260 $subId = acym_getVar('int', 'autoSubId');
235 - $subKey = acym_getVar('string', 'subKey');
261 + $subToken = acym_getVar('string', 'subKey');
236 262
237 - if (empty($subId) || empty($subKey)) {
263 + if (empty($subId) || empty($subToken)) {
238 264 return;
239 265 }
240 266
241 267 $currentUrl = acym_currentURL();
@@ -245,26 +271,38 @@
245 271 if ($config->get('autologin_urls', 0) == 0) {
246 272 acym_redirect($cleanedUrl);
247 273 }
248 274
249 - $cmsId = acym_loadResult('SELECT `cms_id` FROM #__acym_user WHERE `id` = '.intval($subId).' AND `key` = '.acym_escapeDB($subKey));
250 - if (empty($cmsId) || $cmsId === acym_currentUserId()) {
275 + $subscriber = acym_loadObject('SELECT `cms_id`, `key` FROM #__acym_user WHERE `id` = '.intval($subId));
276 + if (empty($subscriber->cms_id) || $subscriber->cms_id === acym_currentUserId()) {
251 277 acym_redirect($cleanedUrl);
252 278 }
253 279
254 - $user = get_user_by('id', $cmsId);
280 + if (!acym_verifyAutologinToken($subId, $subToken, $subscriber->key)) {
281 + acym_redirect($cleanedUrl);
282 + }
255 283
256 - if (!is_wp_error($user)) {
257 - wp_clear_auth_cookie();
258 - wp_set_current_user($user->ID);
259 - wp_set_auth_cookie($user->ID);
284 + $user = get_user_by('id', $subscriber->cms_id);
260 285
286 + if (is_wp_error($user) || !$user) {
261 287 acym_redirect($cleanedUrl);
262 288 }
289 +
290 + // Never allow autologin for administrator accounts
291 + if ($user->has_cap('manage_options')) {
292 + acym_redirect($cleanedUrl);
293 + }
294 +
295 + wp_clear_auth_cookie();
296 + wp_set_current_user($user->ID);
297 + wp_set_auth_cookie($user->ID);
298 +
299 + acym_redirect($cleanedUrl);
263 300 }
264 301
265 302 private function deactivateHookAdminFooter()
266 303 {
304 + //Remove hook function which break AcyMailing pages
267 305 remove_action('admin_footer', 'Freemius::_enrich_ajax_url');
268 306 remove_action('admin_footer', 'Freemius::_open_support_forum_in_new_page');
269 307 }
270 308 }