PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.6.2
WP 2FA – Two-factor authentication for WordPress v2.6.2
4.1.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-white-label.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-white-label.php
472 lines
1 <?php
2 /**
3 * White label settings class.
4 *
5 * @package wp2fa
6 * @subpackage settings-pages
7 * @copyright 2024 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\WP2FA;
15 use WP2FA\Utils\Debugging;
16 use WP2FA\Extensions\WhiteLabeling\White_Labeling_Render;
17
18 /**
19 * White labeling settings tab
20 */
21 if ( ! class_exists( '\WP2FA\Admin\SettingsPages\Settings_Page_White_Label' ) ) {
22 /**
23 * Settings_Page_White_Label - Class for handling settings
24 *
25 * @since 2.0.0
26 */
27 class Settings_Page_White_Label {
28
29 /**
30 * Render the settings
31 *
32 * @return void
33 *
34 * @since 2.0.0
35 */
36 public static function render() {
37 settings_fields( WP_2FA_WHITE_LABEL_SETTINGS_NAME );
38 self::white_labelling_tabs_wrapper();
39 submit_button();
40 }
41
42 /**
43 * Validate options before saving
44 *
45 * @param array $input The settings array.
46 *
47 * @return array|void
48 *
49 * @since 2.0.0
50 */
51 public static function validate_and_sanitize( $input ) {
52
53 // Bail if user doesn't have permissions to be here.
54 if ( ! current_user_can( 'manage_options' ) || ! isset( $_POST['action'] ) && ! check_admin_referer( 'wp2fa-step-choose-method' ) ) {
55 return;
56 }
57
58 Debugging::log( 'The following settings will be processed (White Label): ' . "\n" . wp_json_encode( $input ) );
59
60 $output['default-text-code-page'] = WP2FA::get_wp2fa_white_label_setting( 'default-text-code-page', false, false );
61
62 if ( isset( $input['default-text-code-page'] ) && '' !== trim( (string) $input['default-text-code-page'] ) ) {
63 $output['default-text-code-page'] = \wp_kses_post( $input['default-text-code-page'] );
64 }
65
66 $output['default-backup-code-page'] = WP2FA::get_wp2fa_white_label_setting( 'default-backup-code-page', false, false );
67
68 if ( isset( $input['default-backup-code-page'] ) && '' !== trim( (string) $input['default-backup-code-page'] ) ) {
69 $output['default-backup-code-page'] = \wp_strip_all_tags( $input['default-backup-code-page'] );
70 }
71
72 $output['use_custom_2fa_message'] = WP2FA::get_wp2fa_white_label_setting( 'use_custom_2fa_message', false, false );
73
74 if ( isset( $input['use_custom_2fa_message'] ) && '' !== trim( (string) $input['use_custom_2fa_message'] ) ) {
75 $output['use_custom_2fa_message'] = \wp_strip_all_tags( $input['use_custom_2fa_message'] );
76 }
77
78 $output['custom-text-app-code-page'] = WP2FA::get_wp2fa_white_label_setting( 'custom-text-app-code-page', false, false );
79 $output['custom-text-email-code-page'] = WP2FA::get_wp2fa_white_label_setting( 'custom-text-email-code-page', false, false );
80 $output['custom-text-authy-code-page-intro'] = WP2FA::get_wp2fa_white_label_setting( 'custom-text-authy-code-page-intro', false, false );
81 $output['custom-text-authy-code-page-awaiting'] = WP2FA::get_wp2fa_white_label_setting( 'custom-text-authy-code-page-awaiting', false, false );
82 $output['custom-text-authy-code-page'] = WP2FA::get_wp2fa_white_label_setting( 'custom-text-authy-code-page', false, false );
83 $output['custom-text-twilio-code-page'] = WP2FA::get_wp2fa_white_label_setting( 'custom-text-twilio-code-page', false, false );
84
85 if ( isset( $input['custom-text-app-code-page'] ) && '' !== trim( (string) $input['custom-text-app-code-page'] ) ) {
86 $output['custom-text-app-code-page'] = \wp_strip_all_tags( $input['custom-text-app-code-page'] );
87 }
88
89 if ( isset( $input['custom-text-email-code-page'] ) && '' !== trim( (string) $input['custom-text-email-code-page'] ) ) {
90 $output['custom-text-email-code-page'] = \wp_strip_all_tags( $input['custom-text-email-code-page'] );
91 }
92
93 if ( isset( $input['custom-text-authy-code-page'] ) && '' !== trim( (string) $input['custom-text-authy-code-page'] ) ) {
94 $output['custom-text-authy-code-page'] = \wp_strip_all_tags( $input['custom-text-authy-code-page'] );
95 }
96
97 if ( isset( $input['custom-text-authy-code-page-intro'] ) && '' !== trim( (string) $input['custom-text-authy-code-page-intro'] ) ) {
98 $output['custom-text-authy-code-page-intro'] = \wp_strip_all_tags( $input['custom-text-authy-code-page-intro'] );
99 }
100
101 if ( isset( $input['custom-text-authy-code-page-awaiting'] ) && '' !== trim( (string) $input['custom-text-authy-code-page-awaiting'] ) ) {
102 $output['custom-text-authy-code-page-awaiting'] = \wp_strip_all_tags( $input['custom-text-authy-code-page-awaiting'] );
103 }
104
105 if ( isset( $input['custom-text-twilio-code-page'] ) && '' !== trim( (string) $input['custom-text-twilio-code-page'] ) ) {
106 $output['custom-text-twilio-code-page'] = \wp_strip_all_tags( $input['custom-text-twilio-code-page'] );
107 }
108
109 if ( isset( $_REQUEST['_wp_http_referer'] ) ) {
110 $request_area = wp_parse_url( \wp_unslash( $_REQUEST['_wp_http_referer'] ) ); // phpcs:ignore
111 $request_area_path = strpos( $request_area['query'], 'white-label-section' );
112
113 // If we have the input POSTed, we are on the right page so grab it.
114 if ( isset( $input['enable_wizard_styling'] ) && '' !== trim( (string) $input['enable_wizard_styling'] ) ) {
115 $output['enable_wizard_styling'] = \wp_strip_all_tags( $input['enable_wizard_styling'] );
116 } else {
117 // Nothing was POSTed, check where we are in case that means we simple an empty/disabled checkbox.
118 if ( $request_area_path && ! strpos( $request_area['query'], 'custom-css' ) || ! $request_area_path ) {
119 $input['enable_wizard_styling'] = WP2FA::get_wp2fa_white_label_setting( 'enable_wizard_styling', false );
120 $output['enable_wizard_styling'] = WP2FA::get_wp2fa_white_label_setting( 'enable_wizard_styling', false );
121 /* @free:start */
122 // Free edition does have setting, so allow for it to be disabled.
123 $output['enable_wizard_styling'] = '';
124 $input['enable_wizard_styling'] = '';
125 /* @free:end */
126 } else {
127 $output['enable_wizard_styling'] = '';
128 $input['enable_wizard_styling'] = '';
129 }
130 }
131
132 if ( isset( $input['show_help_text'] ) && '' !== trim( (string) $input['show_help_text'] ) ) {
133 $output['show_help_text'] = \wp_strip_all_tags( $input['show_help_text'] );
134 } else {
135 // Nothing was POSTed, check where we are in case that means we simple an empty/disabled checkbox.
136 if ( $request_area_path && ! strpos( $request_area['query'], 'method_selection' ) ) {
137 $input['show_help_text'] = WP2FA::get_wp2fa_white_label_setting( 'show_help_text', false );
138 $output['show_help_text'] = WP2FA::get_wp2fa_white_label_setting( 'show_help_text', false );
139 } else {
140 $output['show_help_text'] = '';
141 $input['show_help_text'] = '';
142 }
143 }
144
145 // Same as above, but for the optional welcome.
146 if ( isset( $input['enable_welcome'] ) && '' !== trim( (string) $input['enable_welcome'] ) ) {
147 $output['enable_welcome'] = \wp_strip_all_tags( $input['enable_welcome'] );
148 } elseif ( strpos( $request_area['query'], 'white-label-sub-section' ) && strpos( $request_area['query'], 'welcome' ) ) {
149 $input['enable_welcome'] = '';
150 $output['enable_welcome'] = '';
151 } else {
152 $input['enable_welcome'] = WP2FA::get_wp2fa_white_label_setting( 'enable_welcome', false );
153 $output['enable_welcome'] = WP2FA::get_wp2fa_white_label_setting( 'enable_welcome', false );
154 }
155
156 if ( isset( $input['enable_wizard_logo'] ) && '' !== trim( (string) $input['enable_wizard_logo'] ) ) {
157 $output['enable_wizard_logo'] = \wp_strip_all_tags( $input['enable_wizard_logo'] );
158 } elseif ( strpos( $request_area['query'], 'white-label-sub-section' ) && strpos( $request_area['query'], 'welcome' ) ) {
159 $input['enable_wizard_logo'] = '';
160 $output['enable_wizard_logo'] = '';
161 } else {
162 $input['enable_wizard_logo'] = WP2FA::get_wp2fa_white_label_setting( 'enable_wizard_logo', false );
163 $output['enable_wizard_logo'] = WP2FA::get_wp2fa_white_label_setting( 'enable_wizard_logo', false );
164 }
165 }
166
167
168 if ( isset( $input['login_custom_css'] ) && ! empty( $input['login_custom_css'] ) ) {
169 if ( preg_match( '#</?\w+#', $input['login_custom_css'] ) ) {
170 add_settings_error(
171 WP_2FA_SETTINGS_NAME,
172 esc_attr( 'markup_invalid_settings_error' ),
173 esc_html__( 'Markup is not allowed in Login area CSS.', 'wp-2fa' ),
174 'error'
175 );
176 $output['login_custom_css'] = WP2FA::get_wp2fa_white_label_setting( 'login_custom_css', false );
177 $input['login_custom_css'] = WP2FA::get_wp2fa_white_label_setting( 'login_custom_css', false );
178 } else {
179 $output['login_custom_css'] = \wp_strip_all_tags( $input['login_custom_css'] );
180 $input['login_custom_css'] = \wp_strip_all_tags( $input['login_custom_css'] );
181 }
182 }
183
184 // 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.
185 global $wp_settings_errors;
186 if ( isset( $wp_settings_errors ) ) {
187 $errors = array_map( 'unserialize', array_unique( array_map( 'serialize', $wp_settings_errors ) ) );
188 $wp_settings_errors = $errors; // phpcs:ignore
189 }
190
191 /**
192 * Filter the values we are about to store in the plugin settings.
193 *
194 * @param array $output - The output array with all the data we will store in the settings.
195 * @param array $input - The input array with all the data we received from the user.
196 *
197 * @since 2.0.0
198 */
199 $output = apply_filters( WP_2FA_PREFIX . 'filter_output_content', $output, $input );
200
201 Debugging::log( 'The following settings are being saved (White Label): ' . "\n" . wp_json_encode( $output ) );
202
203 return $output;
204 }
205
206 /**
207 * Updates global white label network options
208 *
209 * @return void
210 *
211 * @since 2.0.0
212 *
213 * @SuppressWarnings(PHPMD.ExitExpressions)
214 */
215 public static function update_wp2fa_network_options() {
216
217 if ( isset( $_POST[ WP_2FA_WHITE_LABEL_SETTINGS_NAME ] ) ) {
218 check_admin_referer( 'wp_2fa_white_label-options' );
219 $options = self::validate_and_sanitize( wp_unslash( $_POST[ WP_2FA_WHITE_LABEL_SETTINGS_NAME ] ) ); // phpcs:ignore
220 $settings_errors = get_settings_errors( WP_2FA_WHITE_LABEL_SETTINGS_NAME );
221 if ( ! empty( $settings_errors ) ) {
222
223 // redirect back to our options page.
224 wp_safe_redirect(
225 add_query_arg(
226 array(
227 'page' => 'wp-2fa-settings',
228 'wp_2fa_network_settings_error' => urlencode_deep( $settings_errors[0]['message'] ),
229 ),
230 network_admin_url( 'settings.php' )
231 )
232 );
233 exit;
234
235 }
236 WP2FA::update_plugin_settings( $options, false, WP_2FA_WHITE_LABEL_SETTINGS_NAME );
237
238 // redirect back to our options page.
239 wp_safe_redirect(
240 add_query_arg(
241 array(
242 'page' => 'wp-2fa-settings',
243 'tab' => 'white-label-settings',
244 'wp_2fa_network_settings_updated' => 'true',
245 ),
246 network_admin_url( 'admin.php' )
247 )
248 );
249 exit;
250 }
251 }
252
253 /**
254 * Wrapper which adds special tabbed navigation and content
255 *
256 * @return void
257 *
258 * @since 2.3.0
259 */
260 private static function white_labelling_tabs_wrapper() {
261 /**
262 * Fires right before the white label settings tab HTML, handles tabbed nav.
263 *
264 * @since 2.3.0
265 */
266 do_action( WP_2FA_PREFIX . 'white_labeling_tabbed_navigation' );
267 self::change_default_text_area();
268 }
269
270 /**
271 * Shows default settings input to the user
272 *
273 * @return void
274 *
275 * @since 2.0.0
276 */
277 private static function change_default_text_area() {
278 /**
279 * Fires right before the white label settings tab HTML rendering.
280 *
281 * @since 2.0.0
282 */
283 do_action( WP_2FA_PREFIX . 'white_labeling_settings_page_before_default_text' );
284 ?>
285
286 <?php if ( class_exists( 'WP2FA\Extensions\WhiteLabeling\White_Labeling_Render' ) ) { ?>
287 <h3><?php esc_html_e( '2FA code page text', 'wp-2fa' ); ?></h3>
288 <p class="description">
289 <?php esc_html_e( 'Use these settings to customize message shown to users upon login when a 2FA verification code is requested.', 'wp-2fa' ); ?>
290 </p>
291 <table class="form-table">
292 <tbody>
293 <tr>
294 <th><label for="2fa-method"><?php esc_html_e( 'Customize code page text', 'wp-2fa' ); ?></label>
295 </th>
296 <td>
297 <fieldset class="contains-hidden-inputs">
298 <label for="use-defaults">
299 <input type="radio" name="wp_2fa_white_label[use_custom_2fa_message]" id="use-defaults" value="use-defaults"
300 <?php checked( WP2FA::get_wp2fa_white_label_setting( 'use_custom_2fa_message' ), 'use-defaults' ); ?>
301 >
302 <span><?php esc_html_e( 'Show this generic message to all users regardless of the 2FA method they are using.', 'wp-2fa' ); ?></span>
303 </label>
304
305 <br/>
306 <label for="use-custom">
307 <input type="radio" name="wp_2fa_white_label[use_custom_2fa_message]" id="use-custom" value="use-custom"
308 <?php checked( WP2FA::get_wp2fa_white_label_setting( 'use_custom_2fa_message' ), 'use-custom' ); ?>
309 data-unhide-when-checked=".custom-from-inputs">
310 <span><?php esc_html_e( 'Show a message that is specific to the method that the user is using.', 'wp-2fa' ); ?></span>
311 </label>
312
313 <fieldset class="hidden custom-from-inputs">
314 <p class="description">
315 <?php esc_html_e( '2FA via app', 'wp-2fa' ); ?>
316 </p>
317 <?php echo White_Labeling_Render::get_method_text_editor( 'custom-text-app-code-page' ); ?>
318 <br/>
319
320 <p class="description">
321 <?php esc_html_e( '2FA code over email', 'wp-2fa' ); ?>
322 </p>
323 <?php echo White_Labeling_Render::get_method_text_editor( 'custom-text-email-code-page' ); ?>
324 <br/>
325
326 <p class="description">
327 <?php esc_html_e( '2FA link over email', 'wp-2fa' ); ?>
328 </p>
329 <?php echo White_Labeling_Render::get_method_text_editor( 'default-text-oob-page' ); ?>
330 <br/>
331
332 <p class="description">
333 <?php esc_html_e( '2FA code over SMS', 'wp-2fa' ); ?>
334 </p>
335 <?php echo White_Labeling_Render::get_method_text_editor( 'custom-text-twilio-code-page' ); ?>
336 <br/>
337
338 <p class="description">
339 <?php esc_html_e( '2FA with Push Notification - Intro', 'wp-2fa' ); ?>
340 </p>
341 <?php echo White_Labeling_Render::get_method_text_editor( 'custom-text-authy-code-page-intro' ); ?>
342 <br/>
343
344 <p class="description">
345 <?php esc_html_e( '2FA with Push Notification - Awaiting Response', 'wp-2fa' ); ?>
346 </p>
347 <?php echo White_Labeling_Render::get_method_text_editor( 'custom-text-authy-code-page-awaiting' ); ?>
348 <br/>
349
350 <p class="description">
351 <?php esc_html_e( '2FA with Push Notification', 'wp-2fa' ); ?>
352 </p>
353 <?php echo White_Labeling_Render::get_method_text_editor( 'custom-text-authy-code-page' ); ?>
354 <br/>
355 </fieldset>
356
357 </fieldset>
358 </td>
359 </tr>
360 </tbody>
361 </table>
362 <?php } ?>
363
364 <h3><?php esc_html_e( 'Change the default text used in the 2FA code page', 'wp-2fa' ); ?></h3>
365 <p class="description">
366 <?php esc_html_e( 'This is the text shown to the users on the page when they are asked to enter the 2FA code. To change the default text, simply type it in the below placeholder.', 'wp-2fa' ); ?>
367 </p>
368
369 <table class="form-table">
370 <tbody>
371 <tr>
372 <th><label for="2fa-method"><?php esc_html_e( '2FA code page text', 'wp-2fa' ); ?></label></th>
373 <td>
374 <?php
375 if ( class_exists( 'WP2FA\Extensions\WhiteLabeling\White_Labeling_Render' ) ) {
376 echo White_Labeling_Render::get_method_text_editor( 'default-text-code-page' ); // phpcs:ignore
377 } else {
378 echo self::create_standard_editor( WP2FA::get_wp2fa_white_label_setting( 'default-text-code-page', true ), 'default-text-code-page' );
379 } ?>
380 <div style="margin-top: 5px;"><span><strong><i><?php esc_html_e( 'Note:', 'wp-2fa' ); ?></i></strong> <?php esc_html_e( 'Only plain text is allowed.', 'wp-2fa' ); ?></span></div>
381 </td>
382 </tr>
383 <tr>
384 <th><label for="backup-method"><?php esc_html_e( 'Backup code page text', 'wp-2fa' ); ?></label></th>
385 <td>
386 <?php
387 if ( class_exists( 'WP2FA\Extensions\WhiteLabeling\White_Labeling_Render' ) ) {
388 echo White_Labeling_Render::get_method_text_editor( 'default-backup-code-page' ); // phpcs:ignore
389 } else {
390 echo self::create_standard_editor( WP2FA::get_wp2fa_white_label_setting( 'default-backup-code-page', true ), 'default-backup-code-page' );
391 } ?>
392 <div style="margin-top: 5px;"><span><strong><i><?php esc_html_e( 'Note:', 'wp-2fa' ); ?></i></strong> <?php esc_html_e( 'Only plain text is allowed.', 'wp-2fa' ); ?></span></div>
393 </td>
394 </tr>
395
396 <tr>
397 <th><label for="backup-method"><?php esc_html_e( 'Text for logged out users trying to access the 2FA configuration page', 'wp-2fa' ); ?></label></th>
398 <td>
399 <?php
400 if ( class_exists( 'WP2FA\Extensions\WhiteLabeling\White_Labeling_Render' ) ) {
401 echo White_Labeling_Render::get_method_text_editor( 'login-to-view-area' ); // phpcs:ignore
402 } else {
403 echo self::create_standard_editor( WP2FA::get_wp2fa_white_label_setting( 'login-to-view-area', true ), 'login-to-view-area' );
404 } ?>
405 </td>
406 </tr>
407
408 <?php
409 /**
410 * Gives the ability for the 3rd party extensions to add additional white label settings
411 */
412 do_action( WP_2FA_PREFIX . 'white_labeling_settings_page_after_code_page' );
413 ?>
414 </tbody>
415 </table>
416
417 <?php
418 /* @free:start */
419 ?>
420 <h3><?php esc_html_e( 'Change the styling of the user 2FA wizards', 'wp-2fa' ); ?></h3>
421 <p class="description">
422 <?php esc_html_e( 'By default, the user 2FA wizards which the users see and use to set up 2FA have our own styling. Disable the below setting so the wizards use the styling of your website\'s theme.', 'wp-2fa' ); ?>
423 </p>
424 <table class="form-table">
425 <tbody>
426 <tr>
427 <th><label for="enable_wizard_styling"><?php esc_html_e( 'Enable styling', 'wp-2fa' ); ?></label></th>
428 <td>
429 <fieldset>
430 <input type="checkbox" id="enable_wizard_styling" name="wp_2fa_white_label[enable_wizard_styling]" value="enable_wizard_styling"
431 <?php checked( 'enable_wizard_styling', WP2FA::get_wp2fa_white_label_setting( 'enable_wizard_styling' ), true ); ?>
432 >
433 <?php esc_html_e( 'Enable our CSS within user wizards', 'wp-2fa' ); ?>
434 </fieldset>
435 </td>
436 </tr>
437 </tbody>
438 </table>
439 <?php
440 /* @free:end */
441 ?>
442
443 <?php
444 /**
445 * Fires after the white label settings tab is rendered.
446 *
447 * @since 2.0.0
448 */
449 do_action( WP_2FA_PREFIX . 'white_labeling_settings_page_after_default_text' );
450 }
451
452 /**
453 * Simple function to create a neat text editor in free.
454 *
455 * @param string $content
456 * @param string $requested_slide
457 * @return void
458 */
459 private static function create_standard_editor( $content, $requested_slide ) {
460 $settings = array(
461 'media_buttons' => false,
462 'editor_height' => 200,
463 'textarea_name' => 'wp_2fa_white_label[' . $requested_slide . ']',
464 );
465
466 if ( isset( $content ) ) {
467 wp_editor( $content, $requested_slide, $settings );
468 }
469 }
470 }
471 }
472