PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.0.0
WP 2FA – Two-factor authentication for WordPress v2.0.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 4 years ago class-settings-page-general.php 4 years ago class-settings-page-policies.php 4 years ago class-settings-page-white-label.php 4 years ago
class-settings-page-email.php
420 lines
1 <?php
2 /**
3 * Email settings class.
4 *
5 * @package wp2fa
6 * @copyright 2021 WP White Security
7 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
8 * @link https://wordpress.org/plugins/wp-2fa/
9 */
10
11 namespace WP2FA\Admin\SettingsPages;
12
13 use WP2FA\EmailTemplate;
14 use \WP2FA\WP2FA as WP2FA;
15 use WP2FA\Admin\Controllers\Settings;
16 use WP2FA\Utils\SettingsUtils as SettingsUtils;
17
18 /**
19 * Settings_Page_Email - Class for handling email settings
20 *
21 * @since 2.0.0
22 */
23 class Settings_Page_Email {
24
25 /**
26 * Render the settings
27 *
28 * @return void
29 *
30 * @since 2.0.0
31 */
32 public function render() {
33 settings_fields( WP_2FA_EMAIL_SETTINGS_NAME );
34 $this->email_from_settings();
35 $this->email_settings();
36 submit_button( esc_html__( 'Save email settings and templates', 'wp-2fa' ) );
37 }
38
39 /**
40 * Handle saving email options to the network main site options.
41 *
42 * @return void
43 *
44 * @since 2.0.0
45 *
46 * @SuppressWarnings(PHPMD.ExitExpressions)
47 */
48 public function update_wp2fa_network_options() {
49 if ( isset( $_POST['email_from_setting'] ) ) { // @codingStandardsIgnoreLine - No nonce verification warning
50 $options = $this->validate_and_sanitize( wp_unslash( $_POST ) ); // @codingStandardsIgnoreLine - No nonce verification warning
51
52 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'] ) ) { // @codingStandardsIgnoreLine - No nonce verification warning
53 // redirect back to our options page.
54 wp_safe_redirect(
55 add_query_arg(
56 array(
57 'page' => 'wp-2fa-settings',
58 'wp_2fa_network_settings_updated' => 'false',
59 'tab' => 'email-settings',
60 ),
61 network_admin_url( 'admin.php' )
62 )
63 );
64 exit;
65 }
66
67 SettingsUtils::update_option( WP_2FA_EMAIL_SETTINGS_NAME, $options );
68 }
69
70 // redirect back to our options page.
71 wp_safe_redirect(
72 add_query_arg(
73 array(
74 'page' => 'wp-2fa-settings',
75 'wp_2fa_network_settings_updated' => 'true',
76 'tab' => 'email-settings',
77 ),
78 network_admin_url( 'admin.php' )
79 )
80 );
81 exit;
82 }
83
84 /**
85 * Email settings
86 *
87 * @return void
88 *
89 * @since 2.0.0
90 */
91 private function email_from_settings() {
92 ?>
93 <h3><?php esc_html_e( 'Which email address should the plugin use as a from address?', 'wp-2fa' ); ?></h3>
94 <p class="description">
95 <?php esc_html_e( 'Use these settings to customize the "from" name and email address for all correspondence sent from our plugin.', 'wp-2fa' ); ?>
96 </p>
97 <table class="form-table">
98 <tbody>
99 <tr>
100 <th><label for="2fa-method"><?php esc_html_e( 'From email & name', 'wp-2fa' ); ?></label>
101 </th>
102 <td>
103 <fieldset class="contains-hidden-inputs">
104 <label for="use-defaults">
105 <input type="radio" name="email_from_setting" id="use-defaults" value="use-defaults"
106 <?php checked( WP2FA::get_wp2fa_email_templates( 'email_from_setting' ), 'use-defaults' ); ?>
107 >
108 <span><?php esc_html_e( 'Use the email address from the WordPress general settings.', 'wp-2fa' ); ?></span>
109 </label>
110
111 <br/>
112 <label for="use-custom-email">
113 <input type="radio" name="email_from_setting" id="use-custom-email" value="use-custom-email"
114 <?php checked( WP2FA::get_wp2fa_email_templates( 'email_from_setting' ), 'use-custom-email' ); ?>
115 data-unhide-when-checked=".custom-from-inputs">
116 <span><?php esc_html_e( 'Use another email address', 'wp-2fa' ); ?></span>
117 </label>
118 <fieldset class="hidden custom-from-inputs">
119 <br/>
120 <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>
121 <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' ) ); ?>">
122 </fieldset>
123
124 </fieldset>
125 </td>
126 </tr>
127 </tbody>
128 </table>
129
130 <br>
131 <hr>
132
133 <h3><?php esc_html_e( 'Email delivery test', 'wp-2fa' ); ?></h3>
134 <p class="description">
135 <?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' ); ?>
136 </p>
137 <p>
138 <button type="button" name="test_email_config_test"
139 class="button js-button-test-email-trigger"
140 data-email-id="config_test"
141 data-nonce="<?php echo esc_attr( wp_create_nonce( 'wp-2fa-email-test-config_test' ) ); ?>">
142 <?php esc_html_e( 'Test email delivery', 'wp-2fa' ); ?>
143 </button>
144 </p>
145
146 <br>
147 <hr>
148
149 <?php
150 }
151
152 /**
153 * Creates the email notification definitions.
154 *
155 * @return EmailTemplate[]
156 *
157 * @since 2.0.0
158 */
159 public function get_email_notification_definitions() {
160 $result = array(
161 new EmailTemplate(
162 'login_code',
163 esc_html__( 'Login code email', 'wp-2fa' ),
164 esc_html__( 'This is the email sent to a user when a login code is required.', 'wp-2fa' )
165 ),
166 new EmailTemplate(
167 'account_locked',
168 esc_html__( 'User account locked email', 'wp-2fa' ),
169 esc_html__( 'This is the email sent to a user upon grace period expiry.', 'wp-2fa' )
170 ),
171 new EmailTemplate(
172 'account_unlocked',
173 esc_html__( 'User account unlocked email', 'wp-2fa' ),
174 esc_html__( 'This is the email sent to a user when the user\'s account has been unlocked.', 'wp-2fa' )
175 ),
176 );
177
178 /**
179 * Add an option for external providers to implement their own email template settings for the settings tab.
180 *
181 * @param array $result - The array with all the email templates.
182 *
183 * @since 2.0.0
184 */
185 $result = apply_filters( 'wp_2fa_email_notification_definitions', $result );
186
187 if ( count( $result ) > 3 ) {
188 $result[0]->setCanBeToggled( false );
189 $result[1]->setCanBeToggled( false );
190 $result[2]->setEmailContentId( 'user_account_locked' );
191 $result[3]->setEmailContentId( 'user_account_unlocked' );
192 } else {
193 $result[0]->setCanBeToggled( false );
194 $result[1]->setEmailContentId( 'user_account_locked' );
195 $result[2]->setEmailContentId( 'user_account_unlocked' );
196 }
197 return $result;
198 }
199
200 /**
201 * Validate email templates before saving
202 *
203 * @since 2.0.0
204 *
205 * @SuppressWarnings(PHPMD.ExitExpressions)
206 */
207 public function validate_and_sanitize() {
208
209 // Bail if user doesn't have permissions to be here.
210 if ( ! current_user_can( 'manage_options' ) ) {
211 return;
212 }
213
214 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' ) ) { // @codingStandardsIgnoreLine - Not unslashed warning
215 die( esc_html__( 'Nonce verification failed.', 'wp-2fa' ) );
216 }
217
218 if ( isset( $_POST['email_from_setting'] ) && 'use-defaults' === $_POST['email_from_setting'] || isset( $_POST['email_from_setting'] ) && 'use-custom-email' === $_POST['email_from_setting'] ) {
219 $output['email_from_setting'] = sanitize_text_field( wp_unslash( $_POST['email_from_setting'] ) );
220 }
221
222 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'] ) ) {
223 add_settings_error(
224 WP_2FA_SETTINGS_NAME,
225 esc_attr( 'email_from_settings_error' ),
226 esc_html__( 'Please provide an email address', 'wp-2fa' ),
227 'error'
228 );
229 $output['custom_from_email_address'] = '';
230 }
231
232 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'] ) ) {
233 add_settings_error(
234 WP_2FA_SETTINGS_NAME,
235 esc_attr( 'display_name_settings_error' ),
236 esc_html__( 'Please provide a display name.', 'wp-2fa' ),
237 'error'
238 );
239 $output['custom_from_email_address'] = '';
240 }
241
242 if ( isset( $_POST['custom_from_email_address'] ) && ! empty( $_POST['custom_from_email_address'] ) ) {
243 if ( ! filter_var( wp_unslash( $_POST['custom_from_email_address'] ), FILTER_VALIDATE_EMAIL ) ) {
244 add_settings_error(
245 WP_2FA_SETTINGS_NAME,
246 esc_attr( 'email_invalid_settings_error' ),
247 esc_html__( 'Please provide a valid email address. Your email address has not been updated.', 'wp-2fa' ),
248 'error'
249 );
250 }
251 $output['custom_from_email_address'] = sanitize_email( wp_unslash( $_POST['custom_from_email_address'] ) );
252 }
253
254 if ( isset( $_POST['custom_from_display_name'] ) && ! empty( $_POST['custom_from_display_name'] ) ) {
255 // Check if the string contains HTML/tags.
256 preg_match( "/<\/?\w+((\s+\w+(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/", sanitize_text_field( wp_unslash( $_POST['custom_from_display_name'] ) ), $matches );
257 if ( count( $matches ) > 0 ) {
258 add_settings_error(
259 WP_2FA_SETTINGS_NAME,
260 esc_attr( 'display_name_invalid_settings_error' ),
261 esc_html__( 'Please only use alphanumeric text. Your display name has not been updated.', 'wp-2fa' ),
262 'error'
263 );
264 } else {
265 $output['custom_from_display_name'] = sanitize_text_field( wp_unslash( $_POST['custom_from_display_name'] ) );
266 }
267 }
268
269 if ( isset( $_POST['login_code_email_subject'] ) ) {
270 $output['login_code_email_subject'] = wp_kses_post( wp_unslash( $_POST['login_code_email_subject'] ) );
271 }
272
273 if ( isset( $_POST['login_code_email_body'] ) ) {
274 $output['login_code_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['login_code_email_body'] ) ) );
275 }
276
277 if ( isset( $_POST['user_account_locked_email_subject'] ) ) {
278 $output['user_account_locked_email_subject'] = wp_kses_post( wp_unslash( $_POST['user_account_locked_email_subject'] ) );
279 }
280
281 if ( isset( $_POST['user_account_locked_email_body'] ) ) {
282 $output['user_account_locked_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['user_account_locked_email_body'] ) ) );
283 }
284
285 if ( isset( $_POST['user_account_unlocked_email_subject'] ) ) {
286 $output['user_account_unlocked_email_subject'] = wp_kses_post( wp_unslash( $_POST['user_account_unlocked_email_subject'] ) );
287 }
288
289 if ( isset( $_POST['user_account_unlocked_email_body'] ) ) {
290 $output['user_account_unlocked_email_body'] = wpautop( wp_kses_post( wp_unslash( $_POST['user_account_unlocked_email_body'] ) ) );
291 }
292
293 if ( isset( $_POST['send_account_locked_email'] ) && 'enable_account_locked_email' === $_POST['send_account_locked_email'] ) {
294 $output['send_account_locked_email'] = sanitize_text_field( wp_unslash( $_POST['send_account_locked_email'] ) );
295 }
296
297 if ( isset( $_POST['send_account_unlocked_email'] ) && 'enable_account_unlocked_email' === $_POST['send_account_unlocked_email'] ) {
298 $output['send_account_unlocked_email'] = sanitize_text_field( wp_unslash( $_POST['send_account_unlocked_email'] ) );
299 }
300
301 /**
302 * Filter the values we are about to store in the plugin settings.
303 *
304 * @param array $output - The output array with all the data we will store in the settings.
305 *
306 * @since 2.0.0
307 */
308 $output = apply_filters( 'wp_2fa_filter_output_email_template_content', $output );
309
310 // 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.
311 global $wp_settings_errors;
312 if ( isset( $wp_settings_errors ) ) {
313 $errors = array_map( 'unserialize', array_unique( array_map( 'serialize', $wp_settings_errors ) ) );
314 $wp_settings_errors = $errors; // @codingStandardsIgnoreLine - Not using WP globals warning
315 }
316
317 if ( isset( $output ) ) {
318 return $output;
319 } else {
320 return;
321 }
322 }
323
324 /**
325 * Email settings
326 *
327 * @return void
328 *
329 * @since 2.0.0
330 */
331 private function email_settings() {
332 $custom_user_page_id = Settings::check_setting_in_all_roles( 'custom-user-page-id' );
333 $email_template_definitions = $this->get_email_notification_definitions();
334 ?>
335 <h1><?php esc_html_e( 'Email Templates', 'wp-2fa' ); ?></h1>
336 <?php foreach ( $email_template_definitions as $email_template ) : ?>
337 <?php $template_id = $email_template->getId(); ?>
338 <h3><?php echo esc_html( $email_template->getTitle() ); ?></h3>
339 <p class="description"><?php echo $email_template->getDescription(); // @codingStandardsIgnoreLine - All output escaped warning ?></p>warning
340 <table class="form-table">
341 <tbody>
342 <?php if ( $email_template->canBeToggled() ) : ?>
343 <tr>
344 <th><label for="send_<?php echo esc_attr( $template_id ); ?>_email"><?php esc_html_e( 'Send this email', 'wp-2fa' ); ?></label></th>
345 <td>
346 <fieldset>
347 <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"
348 <?php checked( 'enable_' . $template_id . '_email', WP2FA::get_wp2fa_email_templates( 'send_' . $template_id . '_email' ) ); ?>
349 >
350 <label for="send_<?php echo esc_attr( $template_id ); ?>_email"><?php esc_html_e( 'Uncheck to disable this message.', 'wp-2fa' ); ?></label>
351 </fieldset>
352 </td>
353 </tr>
354 <?php endif; ?>
355 <?php $template_id = $email_template->getEmailContentId(); ?>
356 <tr>
357 <th><label for="<?php echo esc_attr( $template_id ); ?>_email_subject"><?php esc_html_e( 'Email subject', 'wp-2fa' ); ?></label></th>
358 <td>
359 <fieldset>
360 <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' ) ); ?>">
361 </fieldset>
362 </td>
363 </tr>
364 <tr>
365 <th>
366 <label for="<?php echo esc_attr( $template_id ); ?>_email_body"><?php esc_html_e( 'Email body', 'wp-2fa' ); ?></label>
367 </br>
368 <label for="<?php echo esc_attr( $template_id ); ?>_email_tags" style="font-weight: 400;"><?php esc_html_e( 'Available template tags:', 'wp-2fa' ); ?></label>
369 </br>
370 </br>
371 <span style="font-weight: 400;">
372 {site_url}</br>
373 {site_name}</br>
374 {grace_period}</br>
375 {user_login_name}</br>
376 {user_first_name}</br>
377 {user_last_name}</br>
378 {user_display_name}</br>
379 {login_code}</br>
380 {user_ip_address}
381 <?php
382 if ( ! empty( $custom_user_page_id ) ) {
383 echo '</br>{2fa_settings_page_url}';
384 }
385 ?>
386 </span>
387 </th>
388 <td>
389 <fieldset>
390 <?php
391 $message = WP2FA::get_wp2fa_email_templates( $template_id . '_email_body' );
392 $content = $message;
393 $editor_id = $template_id . '_email_body';
394 $settings = array(
395 'media_buttons' => false,
396 'editor_height' => 200,
397 );
398 wp_editor( $content, $editor_id, $settings );
399 ?>
400 </fieldset>
401 <p>
402 <button type="button" name="test_email_<?php echo esc_attr( $template_id ); ?>"
403 class="button js-button-test-email-trigger"
404 data-email-id="<?php echo esc_attr( $template_id ); ?>"
405 data-nonce="<?php echo esc_attr( wp_create_nonce( 'wp-2fa-email-test-' . $template_id ) ); ?>">
406 <?php esc_html_e( 'Send test email', 'wp-2fa' ); ?>
407 </button>
408 </p>
409 </td>
410 </tr>
411 </tbody>
412 </table>
413
414 <br>
415 <hr>
416 <?php endforeach; ?>
417 <?php
418 }
419 }
420