PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.5.0
WP 2FA – Two-factor authentication for WordPress v2.5.0
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / classes / Admin / SettingsPages / class-settings-page-email.php
wp-2fa / includes / classes / Admin / SettingsPages Last commit date
class-settings-page-email.php 2 years ago class-settings-page-general.php 2 years ago class-settings-page-policies.php 2 years ago class-settings-page-render.php 2 years ago class-settings-page-white-label.php 2 years ago index.php 2 years ago
class-settings-page-email.php
462 lines
1 <?php
2 /**
3 * Email settings class.
4 *
5 * @package wp2fa
6 * @subpackage settings-pages
7 * @copyright %%YEAR%% Melapress
8 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
9 * @link https://wordpress.org/plugins/wp-2fa/
10 */
11
12 namespace WP2FA\Admin\SettingsPages;
13
14 use WP2FA\Email_Template;
15 use \WP2FA\WP2FA as WP2FA;
16 use WP2FA\Utils\Debugging;
17 use WP2FA\Admin\Controllers\Settings;
18 use WP2FA\Utils\Settings_Utils as Settings_Utils;
19
20 /**
21 * Email settings tab
22 */
23 if ( ! class_exists( '\WP2FA\Admin\SettingsPages\Settings_Page_Email' ) ) {
24 /**
25 * Settings_Page_Email - Class for handling email settings
26 *
27 * @since 2.0.0
28 */
29 class Settings_Page_Email {
30
31 /**
32 * Render the settings
33 *
34 * @return void
35 *
36 * @since 2.0.0
37 */
38 public static function render() {
39 settings_fields( WP_2FA_EMAIL_SETTINGS_NAME );
40 self::email_from_settings();
41 self::email_settings();
42 submit_button( esc_html__( 'Save email settings and templates', 'wp-2fa' ) );
43 }
44
45 /**
46 * Handle saving email options to the network main site options.
47 *
48 * @return void
49 *
50 * @since 2.0.0
51 *
52 * @SuppressWarnings(PHPMD.ExitExpressions)
53 */
54 public static function update_wp2fa_network_options() {
55 if ( isset( $_POST['email_from_setting'] ) ) { // phpcs:ignore
56 $options = self::validate_and_sanitize( wp_unslash( $_POST ) ); // phpcs:ignore
57
58 if ( isset( $_POST['email_from_setting'] ) && 'use-custom-email' === $_POST['email_from_setting'] && isset( $_POST['custom_from_display_name'] ) && empty( $_POST['custom_from_display_name'] ) || isset( $_POST['email_from_setting'] ) && 'use-custom-email' === $_POST['email_from_setting'] && isset( $_POST['custom_from_email_address'] ) && empty( $_POST['custom_from_email_address'] ) ) { // phpcs:ignore
59 // redirect back to our options page.
60 wp_safe_redirect(
61 add_query_arg(
62 array(
63 'page' => 'wp-2fa-settings',
64 'wp_2fa_network_settings_updated' => 'false',
65 'tab' => 'email-settings',
66 ),
67 network_admin_url( 'admin.php' )
68 )
69 );
70 exit;
71 }
72
73 Settings_Utils::update_option( WP_2FA_EMAIL_SETTINGS_NAME, $options );
74 }
75
76 // redirect back to our options page.
77 wp_safe_redirect(
78 add_query_arg(
79 array(
80 'page' => 'wp-2fa-settings',
81 'wp_2fa_network_settings_updated' => 'true',
82 'tab' => 'email-settings',
83 ),
84 network_admin_url( 'admin.php' )
85 )
86 );
87 exit;
88 }
89
90 /**
91 * Email settings
92 *
93 * @return void
94 *
95 * @since 2.0.0
96 */
97 private static function email_from_settings() {
98 ?>
99 <h3><?php esc_html_e( 'Which email address should the plugin use as a from address?', 'wp-2fa' ); ?></h3>
100 <p class="description">
101 <?php esc_html_e( 'Use these settings to customize the "from" name and email address for all correspondence sent from our plugin.', 'wp-2fa' ); ?>
102 </p>
103 <table class="form-table">
104 <tbody>
105 <tr>
106 <th><label for="2fa-method"><?php esc_html_e( 'From email & name', 'wp-2fa' ); ?></label>
107 </th>
108 <td>
109 <fieldset class="contains-hidden-inputs">
110 <label for="use-defaults">
111 <input type="radio" name="email_from_setting" id="use-defaults" value="use-defaults"
112 <?php checked( WP2FA::get_wp2fa_email_templates( 'email_from_setting' ), 'use-defaults' ); ?>
113 >
114 <span><?php esc_html_e( 'Use the email address from the WordPress general settings.', 'wp-2fa' ); ?></span>
115 </label>
116
117 <br/>
118 <label for="use-custom-email">
119 <input type="radio" name="email_from_setting" id="use-custom-email" value="use-custom-email"
120 <?php checked( WP2FA::get_wp2fa_email_templates( 'email_from_setting' ), 'use-custom-email' ); ?>
121 data-unhide-when-checked=".custom-from-inputs">
122 <span><?php esc_html_e( 'Use another email address', 'wp-2fa' ); ?></span>
123 </label>
124 <fieldset class="hidden custom-from-inputs">
125 <br/>
126 <span><?php esc_html_e( 'Email Address:', 'wp-2fa' ); ?></span> <input type="text" id="custom_from_email_address" name="custom_from_email_address" value="<?php echo esc_attr( WP2FA::get_wp2fa_email_templates( 'custom_from_email_address' ) ); ?>"><br><br>
127 <span><?php esc_html_e( 'Display Name:', 'wp-2fa' ); ?></span> <input type="text" id="custom_from_display_name" name="custom_from_display_name" value="<?php echo esc_attr( WP2FA::get_wp2fa_email_templates( 'custom_from_display_name' ) ); ?>">
128 </fieldset>
129
130 </fieldset>
131 </td>
132 </tr>
133 </tbody>
134 </table>
135
136 <br>
137 <hr>
138
139 <h3><?php esc_html_e( 'Email delivery test', 'wp-2fa' ); ?></h3>
140 <p class="description">
141 <?php esc_html_e( 'The plugin sends emails with one-time codes, blocked account notifications and more. Use the button below to confirm the plugin can successfully send emails.', 'wp-2fa' ); ?>
142 </p>
143 <p>
144 <button type="button" name="test_email_config_test"
145 class="button js-button-test-email-trigger"
146 data-email-id="config_test"
147 data-nonce="<?php echo esc_attr( wp_create_nonce( 'wp-2fa-email-test-config_test' ) ); ?>">
148 <?php esc_html_e( 'Test email delivery', 'wp-2fa' ); ?>
149 </button>
150 </p>
151
152 <br>
153 <hr>
154
155 <?php
156 }
157
158 /**
159 * Creates the email notification definitions.
160 *
161 * @return Email_Template[]
162 *
163 * @since 2.0.0
164 */
165 public static function get_email_notification_definitions() {
166
167 $backup_codes = new Email_Template(
168 'user_backup_codes',
169 esc_html__( 'User backup codes email', 'wp-2fa' ),
170 esc_html__( 'This email can be sent a user once backup codes are generated.', 'wp-2fa' )
171 );
172 $backup_codes->set_can_be_toggled( false );
173
174 $result = array(
175 new Email_Template(
176 'login_code',
177 esc_html__( 'Login code email', 'wp-2fa' ),
178 esc_html__( 'This is the email sent to a user when a login code is required.', 'wp-2fa' )
179 ),
180 new Email_Template(
181 'account_locked',
182 esc_html__( 'User account locked email', 'wp-2fa' ),
183 esc_html__( 'This is the email sent to a user upon grace period expiry.', 'wp-2fa' )
184 ),
185 new Email_Template(
186 'account_unlocked',
187 esc_html__( 'User account unlocked email', 'wp-2fa' ),
188 esc_html__( 'This is the email sent to a user when the user\'s account has been unlocked.', 'wp-2fa' )
189 ),
190 new Email_Template(
191 'reset_password_code',
192 esc_html__( 'User reset password code email', 'wp-2fa' ),
193 esc_html__( 'This is the email sent to a user when a password reset is requested.', 'wp-2fa' )
194 ),
195 $backup_codes,
196 );
197
198 /**
199 * Add an option for external providers to implement their own email template settings for the settings tab.
200 *
201 * @param array $result - The array with all the email templates.
202 *
203 * @since 2.0.0
204 */
205 $result = apply_filters( WP_2FA_PREFIX . 'email_notification_definitions', $result );
206
207 if ( count( $result ) > 5 ) {
208 $result[0]->set_can_be_toggled( false );
209 $result[1]->set_can_be_toggled( false );
210 $result[2]->set_email_content_id( 'user_account_locked' );
211 $result[3]->set_email_content_id( 'user_account_unlocked' );
212 $result[4]->set_can_be_toggled( false );
213 } else {
214 $result[0]->set_can_be_toggled( false );
215 $result[1]->set_email_content_id( 'user_account_locked' );
216 $result[2]->set_email_content_id( 'user_account_unlocked' );
217 $result[3]->set_can_be_toggled( false );
218 }
219 return $result;
220 }
221
222 /**
223 * Validate email templates before saving
224 *
225 * @since 2.0.0
226 *
227 * @SuppressWarnings(PHPMD.ExitExpressions)
228 */
229 public static function validate_and_sanitize() {
230
231 // Bail if user doesn't have permissions to be here.
232 if ( ! current_user_can( 'manage_options' ) ) {
233 return;
234 }
235
236 Debugging::log( 'The following settings will be processed (E-mail): ' . "\n" . wp_json_encode( $_POST ) ); // phpcs:ignore
237
238 if ( empty( $_POST ) || ! isset( $_POST['_wpnonce'] ) || empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], WP_2FA_PREFIX . 'email_settings-options' ) && ! wp_verify_nonce( $_POST['_wpnonce'], WP_2FA_PREFIX . 'settings-options' ) || ! wp_verify_nonce( $_POST['_wpnonce'], WP_2FA_PREFIX . 'email_settings-options' ) && ! wp_verify_nonce( $_POST['_wpnonce'], WP_2FA_PREFIX . 'settings-options' ) ) { // phpcs:ignore
239 die( esc_html__( 'Nonce verification failed.', 'wp-2fa' ) );
240 }
241
242 $output = array();
243
244 if ( isset( $_POST['email_from_setting'] ) && 'use-defaults' === $_POST['email_from_setting'] || isset( $_POST['email_from_setting'] ) && 'use-custom-email' === $_POST['email_from_setting'] ) {
245 $output['email_from_setting'] = sanitize_text_field( wp_unslash( $_POST['email_from_setting'] ) );
246 }
247
248 if ( isset( $_POST['email_from_setting'] ) && 'use-custom-email' === $_POST['email_from_setting'] && isset( $_POST['custom_from_email_address'] ) && empty( $_POST['custom_from_email_address'] ) ) {
249 add_settings_error(
250 WP_2FA_SETTINGS_NAME,
251 esc_attr( 'email_from_settings_error' ),
252 esc_html__( 'Please provide an email address', 'wp-2fa' ),
253 'error'
254 );
255 $output['custom_from_email_address'] = '';
256 }
257
258 if ( isset( $_POST['email_from_setting'] ) && 'use-custom-email' === $_POST['email_from_setting'] && isset( $_POST['custom_from_display_name'] ) && empty( $_POST['custom_from_display_name'] ) ) {
259 add_settings_error(
260 WP_2FA_SETTINGS_NAME,
261 esc_attr( 'display_name_settings_error' ),
262 esc_html__( 'Please provide a display name.', 'wp-2fa' ),
263 'error'
264 );
265 $output['custom_from_email_address'] = '';
266 }
267
268 if ( isset( $_POST['custom_from_email_address'] ) && ! empty( $_POST['custom_from_email_address'] ) ) {
269 if ( ! filter_var( wp_unslash( $_POST['custom_from_email_address'] ), FILTER_VALIDATE_EMAIL ) ) {
270 add_settings_error(
271 WP_2FA_SETTINGS_NAME,
272 esc_attr( 'email_invalid_settings_error' ),
273 esc_html__( 'Please provide a valid email address. Your email address has not been updated.', 'wp-2fa' ),
274 'error'
275 );
276 }
277 $output['custom_from_email_address'] = sanitize_email( wp_unslash( $_POST['custom_from_email_address'] ) );
278 }
279
280 if ( isset( $_POST['custom_from_display_name'] ) && ! empty( $_POST['custom_from_display_name'] ) ) {
281 // Check if the string contains HTML/tags.
282 preg_match( "/<\/?\w+((\s+\w+(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/", sanitize_text_field( wp_unslash( $_POST['custom_from_display_name'] ) ), $matches );
283 if ( count( $matches ) > 0 ) {
284 add_settings_error(
285 WP_2FA_SETTINGS_NAME,
286 esc_attr( 'display_name_invalid_settings_error' ),
287 esc_html__( 'Please only use alphanumeric text. Your display name has not been updated.', 'wp-2fa' ),
288 'error'
289 );
290 } else {
291 $output['custom_from_display_name'] = sanitize_text_field( wp_unslash( $_POST['custom_from_display_name'] ) );
292 }
293 }
294
295 if ( isset( $_POST['login_code_email_subject'] ) ) {
296 $output['login_code_email_subject'] = wp_kses_post( wp_unslash( $_POST['login_code_email_subject'] ) );
297 }
298
299 if ( isset( $_POST['login_code_email_body'] ) ) {
300 $output['login_code_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['login_code_email_body'] ) ) );
301 }
302
303 if ( isset( $_POST['user_account_locked_email_subject'] ) ) {
304 $output['user_account_locked_email_subject'] = wp_kses_post( wp_unslash( $_POST['user_account_locked_email_subject'] ) );
305 }
306
307 if ( isset( $_POST['user_account_locked_email_body'] ) ) {
308 $output['user_account_locked_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['user_account_locked_email_body'] ) ) );
309 }
310
311 if ( isset( $_POST['user_account_unlocked_email_subject'] ) ) {
312 $output['user_account_unlocked_email_subject'] = wp_kses_post( wp_unslash( $_POST['user_account_unlocked_email_subject'] ) );
313 }
314
315 if ( isset( $_POST['user_account_unlocked_email_body'] ) ) {
316 $output['user_account_unlocked_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['user_account_unlocked_email_body'] ) ) );
317 }
318
319 $output['send_account_locked_email'] = '';
320 if ( isset( $_POST['send_account_locked_email'] ) && 'enable_account_locked_email' === $_POST['send_account_locked_email'] ) {
321 $output['send_account_locked_email'] = sanitize_text_field( wp_unslash( $_POST['send_account_locked_email'] ) );
322 }
323
324 $output['send_account_unlocked_email'] = '';
325 if ( isset( $_POST['send_account_unlocked_email'] ) && 'enable_account_unlocked_email' === $_POST['send_account_unlocked_email'] ) {
326 $output['send_account_unlocked_email'] = sanitize_text_field( wp_unslash( $_POST['send_account_unlocked_email'] ) );
327 }
328
329 if ( isset( $_POST['user_backup_codes_email_subject'] ) ) {
330 $output['user_backup_codes_email_subject'] = wp_kses_post( wp_unslash( $_POST['user_backup_codes_email_subject'] ) );
331 }
332
333 if ( isset( $_POST['user_backup_codes_email_body'] ) ) {
334 $output['user_backup_codes_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['user_backup_codes_email_body'] ) ) );
335 }
336
337 /**
338 * Filter the values we are about to store in the plugin settings.
339 *
340 * @param array $output - The output array with all the data we will store in the settings.
341 *
342 * @since 2.0.0
343 */
344 $output = apply_filters( WP_2FA_PREFIX . 'filter_output_email_template_content', $output );
345
346 Debugging::log( 'The following settings are being saved (E-mail): ' . "\n" . wp_json_encode( $output ) );
347
348 // Remove duplicates from settings errors. We do this as this sanitization callback is actually fired twice, so we end up with duplicates when saving the settings for the FIRST TIME only. The issue is not present once the settings are in the DB as the sanitization wont fire again. For details on this core issue - https://core.trac.wordpress.org/ticket/21989.
349 global $wp_settings_errors;
350 if ( isset( $wp_settings_errors ) ) {
351 $errors = array_map( 'unserialize', array_unique( array_map( 'serialize', $wp_settings_errors ) ) );
352 $wp_settings_errors = $errors; // phpcs:ignore
353 }
354
355 if ( isset( $output ) ) {
356 return $output;
357 } else {
358 return;
359 }
360 }
361
362 /**
363 * Email settings
364 *
365 * @return void
366 *
367 * @since 2.0.0
368 */
369 private static function email_settings() {
370 $custom_user_page_id = Settings::check_setting_in_all_roles( 'custom-user-page-id' );
371 if ( empty( $custom_user_page_id ) ) {
372 $custom_user_page_id = Settings::check_setting_in_all_roles( 'custom-user-page-url' );
373 }
374 $email_template_definitions = self::get_email_notification_definitions();
375 ?>
376 <h1><?php esc_html_e( 'Email Templates', 'wp-2fa' ); ?></h1>
377 <?php foreach ( $email_template_definitions as $email_template ) : ?>
378 <?php $template_id = $email_template->get_id(); ?>
379 <h3><?php echo esc_html( $email_template->get_title() ); ?></h3>
380 <p class="description"><?php echo $email_template->get_description(); // phpcs:ignore ?></p>
381 <table class="form-table">
382 <tbody>
383 <?php if ( $email_template->can_be_toggled() ) : ?>
384 <tr>
385 <th><label for="send_<?php echo esc_attr( $template_id ); ?>_email"><?php esc_html_e( 'Send this email', 'wp-2fa' ); ?></label></th>
386 <td>
387 <fieldset>
388 <input type="checkbox" id="send_<?php echo esc_attr( $template_id ); ?>_email" name="send_<?php echo esc_attr( $template_id ); ?>_email" value="enable_<?php echo esc_attr( $template_id ); ?>_email"
389 <?php checked( 'enable_' . $template_id . '_email', WP2FA::get_wp2fa_email_templates( 'send_' . $template_id . '_email' ) ); ?>
390 >
391 <label for="send_<?php echo esc_attr( $template_id ); ?>_email"><?php esc_html_e( 'Uncheck to disable this message.', 'wp-2fa' ); ?></label>
392 </fieldset>
393 </td>
394 </tr>
395 <?php endif; ?>
396 <?php $template_id = $email_template->get_email_content_id(); ?>
397 <tr>
398 <th><label for="<?php echo esc_attr( $template_id ); ?>_email_subject"><?php esc_html_e( 'Email subject', 'wp-2fa' ); ?></label></th>
399 <td>
400 <fieldset>
401 <input type="text" id="<?php echo esc_attr( $template_id ); ?>_email_subject" name="<?php echo esc_attr( $template_id ); ?>_email_subject" class="large-text" value="<?php echo esc_attr( WP2FA::get_wp2fa_email_templates( $template_id . '_email_subject' ) ); ?>">
402 </fieldset>
403 </td>
404 </tr>
405 <tr>
406 <th>
407 <label for="<?php echo esc_attr( $template_id ); ?>_email_body"><?php esc_html_e( 'Email body', 'wp-2fa' ); ?></label>
408 </br>
409 <label for="<?php echo esc_attr( $template_id ); ?>_email_tags" style="font-weight: 400;"><?php esc_html_e( 'Available template tags:', 'wp-2fa' ); ?></label>
410 </br>
411 </br>
412 <span style="font-weight: 400;">
413 {site_url}</br>
414 {site_name}</br>
415 {grace_period}</br>
416 {user_login_name}</br>
417 {user_first_name}</br>
418 {user_last_name}</br>
419 {user_display_name}</br>
420 {login_code}</br>
421 {user_ip_address}
422 <?php
423 if ( ! empty( $custom_user_page_id ) ) {
424 echo '</br>{2fa_settings_page_url}';
425 }
426 ?>
427 </span>
428 </th>
429 <td>
430 <fieldset>
431 <?php
432 $message = WP2FA::get_wp2fa_email_templates( $template_id . '_email_body' );
433 $content = $message;
434 $editor_id = $template_id . '_email_body';
435 $settings = array(
436 'media_buttons' => false,
437 'editor_height' => 200,
438 );
439 wp_editor( $content, $editor_id, $settings );
440 ?>
441 </fieldset>
442 <p>
443 <button type="button" name="test_email_<?php echo esc_attr( $template_id ); ?>"
444 class="button js-button-test-email-trigger"
445 data-email-id="<?php echo esc_attr( $template_id ); ?>"
446 data-nonce="<?php echo esc_attr( wp_create_nonce( 'wp-2fa-email-test-' . $template_id ) ); ?>">
447 <?php esc_html_e( 'Send test email', 'wp-2fa' ); ?>
448 </button>
449 </p>
450 </td>
451 </tr>
452 </tbody>
453 </table>
454
455 <br>
456 <hr>
457 <?php endforeach; ?>
458 <?php
459 }
460 }
461 }
462