PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.4.0
Defender Security – Malware Scanner, Login Security & Firewall v5.4.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / view / two-fa / otp.php

otp.php in Defender Security – Malware Scanner, Login Security & Firewall 5.4.0, at src/view/two-fa/otp.php

495 lines 13.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This template is used to display 2FA OTP field.
4 *
5 * @package WP_Defender
6 */
7
8 if ( ! function_exists( 'login_header_otp' ) ) {
9 // Copy from wp-login.php.
10 /**
11 * Output the login page header.
12 *
13 * @param string $title Optional. WordPress login Page title to display in the `<title>` element. Default 'Log In'.
14 * @param string $message Optional. Message to display in header. Default empty.
15 * @param bool $show_logo Optional. Show/hide header logo. Default true.
16 * @param WP_Error $wp_error Optional. The error to pass. Default empty.
17 */
18 function login_header_otp( $title = 'Log In', $message = '', $show_logo = true, $wp_error = '' ) {
19 global $error, $interim_login, $action;
20
21 if ( empty( $wp_error ) ) {
22 $wp_error = new WP_Error();
23 }
24
25 // Shake it!
26 $shake_error_codes = array(
27 'empty_password',
28 'empty_email',
29 'invalid_email',
30 'invalidcombo',
31 'empty_username',
32 'invalid_username',
33 'incorrect_password',
34 );
35 /**
36 * Filters the error codes array for shaking the login form.
37 *
38 * @param array $shake_error_codes Error codes that shake the login form.
39 *
40 * @since 3.0.0
41 */
42 $shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes );
43 if ( $shake_error_codes && $wp_error->get_error_code() && in_array(
44 $wp_error->get_error_code(),
45 $shake_error_codes,
46 true
47 ) ) {
48 add_action( 'login_head', 'wp_shake_js', 12 );
49 }
50
51 $separator = is_rtl() ? ' &rsaquo; ' : ' &lsaquo; ';
52
53 ?><!DOCTYPE html>
54 <!--[if IE 8]>
55 <html xmlns="http://www.w3.org/1999/xhtml" class="ie8"
56 <?php
57 language_attributes();
58 ?>
59 >
60 <![endif]-->
61 <!--[if !(IE 8) ]><!-->
62 <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
63 <!--<![endif]-->
64
65 <head>
66 <meta http-equiv="Content-Type"
67 content="<?php bloginfo( 'html_type' ); ?>; charset=<?php bloginfo( 'charset' ); ?>"/>
68 <meta name="viewport" content="width=device-width">
69 <title>
70 <?php
71 printf( '%s%s%s', esc_attr( get_bloginfo( 'name', 'display' ) ), esc_attr( $separator ), esc_attr( $title ) );
72 ?>
73 </title>
74 <?php
75
76 wp_enqueue_style( 'login' );
77
78 /*
79 * Remove all stored post data on logging out.
80 * This could be added by add_action('login_head'...) like wp_shake_js(),
81 * but maybe better if it's not removable by plugins.
82 */
83 if ( 'loggedout' === $wp_error->get_error_code() ) {
84 ?>
85 <script>if ("sessionStorage" in window) {
86 try {
87 for (var key in sessionStorage) {
88 if (key.indexOf("wp-autosave-") != -1) {
89 sessionStorage.removeItem(key)
90 }
91 }
92 } catch (e) {
93 }
94 }
95 </script>
96 <?php
97 }
98
99 /**
100 * Enqueue scripts and styles for the login page.
101 *
102 * @since 3.1.0
103 */
104 do_action( 'login_enqueue_scripts' );
105
106 /**
107 * Fires in the login page header after scripts are enqueued.
108 *
109 * @since 2.1.0
110 */
111 do_action( 'login_head' );
112
113 if ( is_multisite() ) {
114 $login_header_url = network_home_url();
115 $login_header_title = get_network()->site_name;
116 } else {
117 $login_header_url = 'https://wordpress.org/';
118 $login_header_title = esc_html__( 'Powered by WordPress', 'defender-security' );
119 }
120
121 /**
122 * Filters link URL of the header logo above login form.
123 *
124 * @param string $login_header_url Login header logo URL.
125 *
126 * @since 2.1.0
127 */
128 $login_header_url = apply_filters( 'login_headerurl', $login_header_url );
129
130 /**
131 * Filters the title attribute of the header logo above login form.
132 *
133 * @param string $login_header_title Login header logo title attribute.
134 *
135 * @since 2.1.0
136 */
137 $login_header_title = apply_filters( 'login_headertitle', $login_header_title );
138
139 $classes = array( 'login-action-' . $action, 'wp-core-ui' );
140 if ( is_rtl() ) {
141 $classes[] = 'rtl';
142 }
143 if ( $interim_login ) {
144 $classes[] = 'interim-login';
145 ?>
146 <style type="text/css">
147 html {
148 background-color: transparent;
149 }
150 </style>
151 <?php
152
153 if ( 'success' === $interim_login ) {
154 $classes[] = 'interim-login-success';
155 }
156 }
157 $classes[] = ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
158
159 /**
160 * Filters the login page body classes.
161 *
162 * @param array $classes An array of body classes.
163 * @param string $action The action that brought the visitor to the login page.
164 *
165 * @since 3.5.0
166 */
167 $classes = apply_filters( 'login_body_class', $classes, $action );
168
169 ?>
170 </head>
171
172 <body class="login <?php echo esc_attr( implode( ' ', $classes ) ); ?>">
173 <?php
174 /**
175 * Fires in the login page header after the body tag is opened.
176 *
177 * @since 4.6.0
178 */
179 do_action( 'login_header' );
180 ?>
181 <div id="login">
182 <?php if ( true === $show_logo ) { ?>
183 <h1>
184 <a id="otp-logo" href="<?php echo esc_url( $login_header_url ); ?>"
185 title="<?php echo esc_attr( $login_header_title ); ?>" tabindex="-1"><?php bloginfo( 'name' ); ?></a>
186 </h1>
187 <div id="notification"></div>
188 <?php
189 }
190 unset( $login_header_url, $login_header_title );
191 /**
192 * Filters the message to display above the login form.
193 *
194 * @param string $message Login message text.
195 *
196 * @since 2.1.0
197 */
198 $message = apply_filters( 'login_message', $message );
199 if ( ! empty( $message ) ) {
200 echo wp_kses_post( $message );
201 }
202
203 // In case a plugin uses $error rather than the $wp_errors object.
204 if ( ! empty( $error ) ) {
205 $wp_error->add( 'error', $error );
206 unset( $error );
207 }
208
209 if ( $wp_error->get_error_code() ) {
210 $errors = '';
211 $messages = '';
212 foreach ( $wp_error->get_error_codes() as $code ) {
213 $severity = $wp_error->get_error_data( $code );
214 foreach ( $wp_error->get_error_messages( $code ) as $error_message ) {
215 if ( 'message' === $severity ) {
216 $messages .= ' ' . $error_message . "<br />\n";
217 } else {
218 $errors .= ' ' . $error_message . "<br />\n";
219 }
220 }
221 }
222 if ( ! empty( $errors ) ) {
223 /**
224 * Filters the error messages displayed above the login form.
225 *
226 * @param string $errors Login error message.
227 *
228 * @since 2.1.0
229 */
230 echo wp_kses_post( sprintf( '<div id="login_error" class="notice notice-error">%s</div>', apply_filters( 'login_errors', $errors ) ) );
231 }
232 if ( ! empty( $messages ) ) {
233 /**
234 * Filters instructional messages displayed above the login form.
235 *
236 * @param string $messages Login messages.
237 *
238 * @since 2.5.0
239 */
240 echo wp_kses_post( sprintf( '<p class="message">%s</p>', apply_filters( 'login_messages', $messages ) ) );
241 }
242 }
243 }
244 }
245
246 $show_logo = WP_Defender\Model\Setting\Two_Fa::CUSTOM_GRAPHIC_TYPE_NO !== $custom_graphic_type;
247 if ( isset( $interim_login ) && 'success' === $interim_login ) {
248 login_header_otp( '', $message, $show_logo );
249
250 $modal_close_script = <<<END
251 <script>
252 jQuery(function ($) {
253 $('.wp-auth-check-close', window.parent.document).trigger('click');
254 });
255 </script>
256 END;
257
258 add_action(
259 'wp_print_footer_scripts',
260 function () use ( $modal_close_script ) {
261 /**
262 * Ignore WordPress.Security.EscapeOutput.OutputNotEscaped
263 * Why?
264 * We don't want to escape scripts here.
265 */
266 echo $modal_close_script; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
267 }
268 );
269 } else {
270 login_header_otp( '', '', $show_logo, $error );
271
272 if ( ! empty( $providers ) ) {
273 $nonce = wp_create_nonce( 'verify_otp' );
274 foreach ( $providers as $slug => $provider ) {
275 ?>
276 <form method="post" class="wpdef-2fa-form" id="wpdef-2fa-form-<?php echo esc_attr( $slug ); ?>" action="
277 <?php
278 echo esc_url(
279 add_query_arg(
280 'action',
281 'defender-verify-otp',
282 site_url( 'wp-login.php', 'login_post' )
283 )
284 );
285 ?>
286 ">
287
288 <?php $provider->authentication_form(); ?>
289
290 <input type="hidden" name="auth_method" value="<?php echo esc_attr( $slug ); ?>"/>
291 <input type="hidden" name="login_token" value="<?php echo esc_attr( $token ); ?>"/>
292 <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $redirect_to ); ?>"/>
293 <input type="hidden" name="password" value="<?php echo esc_attr( $password ); ?>"/>
294 <input type="hidden" name="requested_user" value="<?php echo esc_attr( $user_id ); ?>"/>
295 <input type="hidden" id="_wpnonce_<?php echo esc_attr( $slug ); ?>" name="_wpnonce" value="<?php echo esc_attr( $nonce ); ?>" />
296 <?php
297 if ( ! empty( defender_get_data_from_request( 'interim-login', 'r' ) ) ) {
298 ?>
299 <input type="hidden" name="interim-login" value="1"/>
300 <?php
301 }
302 ?>
303 </form>
304 <?php
305 }
306 if ( ( is_array( $providers ) || $providers instanceof Countable ? count( $providers ) : 0 ) > 1 ) {
307 ?>
308 <div id="wrap-nav">
309 <p><?php esc_attr_e( 'Having problems? Try another way to log in', 'defender-security' ); ?></p>
310 <ul id="nav">
311 <?php foreach ( $providers as $slug => $provider ) { ?>
312 <li class="wpdef-2fa-link" id="wpdef-2fa-link-<?php echo esc_attr( $slug ); ?>"
313 data-slug="<?php echo esc_attr( $slug ); ?>">
314
315 <?php echo $provider->get_login_label(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
316
317 </li>
318 <?php } ?>
319 </ul>
320 </div>
321 <?php } ?>
322 <?php } ?>
323 <?php if ( $custom_graphic ) { ?>
324 <style type="text/css">
325 body.login div#login h1 a {
326 background-image: url("<?php echo esc_url_raw( $custom_graphic ); ?>");
327 }
328 </style>
329 <?php } ?>
330 <?php
331 $totp_script = <<<END
332 <script>
333 jQuery(function ($) {
334 function two_factor_providers(defaultSlug) {
335 // Hide all forms and show the one default.
336 $('.wpdef-2fa-form').hide();
337 $('#wpdef-2fa-form-' + defaultSlug).show();
338 // Hide all links and show others except the default.
339 if ($('.wpdef-2fa-link').length > 0) {
340 $('.wpdef-2fa-link').hide();
341 $('.wpdef-2fa-link:not(#wpdef-2fa-link-' + defaultSlug + ')').each(function () {
342 $(this).show();
343 });
344 }
345 // Focus on the current input-field.
346 if ($('#wpdef-2fa-form-' + defaultSlug).find('[name="otp"]').length > 0) {
347 $('#wpdef-2fa-form-' + defaultSlug).find('[name="otp"]').trigger('focus');
348 }
349 }
350
351 var is_sent = false;
352 // Logic for FallbackEmail method.
353 function resend_code() {
354 // Work with the button 'Resend Code'.
355 var that = $('#wd-2fa-resend-code');
356 if (is_sent === false) {
357 is_sent = true;
358 }
359 let data = {
360 data: JSON.stringify({
361 'token': '{$token}',
362 'requested_user': '{$user_id}'
363 })
364 };
365 $.ajax({
366 type: 'POST',
367 url: '{$action_fallback_email}',
368 data: data,
369 beforeSend: function () {
370 that.prop('disabled', true);
371 $('.def-ajaxloader').show();
372 },
373 success: function (data) {
374 that.prop('disabled', false);
375 $('.def-ajaxloader').hide();
376 $('#notification').removeClass().addClass('notice notice-success').text(data.data.message).show();
377 is_sent = false;
378 }
379 });
380 }
381
382 $('.def-ajaxloader').hide();
383 // Hide all forms and show the one default.
384 var defaultSlug = '{$default_slug}';
385 if (!defaultSlug && 0 < $('form.wpdef-2fa-form').first().length) {
386 var twoFaFormId = $('form.wpdef-2fa-form').first().attr('id');
387 defaultSlug = twoFaFormId.replace('wpdef-2fa-form-', '');
388 if ('fallback-email' === defaultSlug) {
389 resend_code();
390 } else {
391 $('#notification').hide();
392 }
393 }
394 two_factor_providers(defaultSlug);
395 // Work with links.
396 $('body').on('click', '.wpdef-2fa-link', function () {
397 $('#login_error').remove();
398 // Clear any previous notification.
399 var slug = $(this).data('slug');
400 two_factor_providers(slug);
401 // Switch to 'Fallback Email' method.
402 if ('fallback-email' === slug) {
403 resend_code();
404 } else {
405 $('#notification').hide();
406 }
407 });
408 // Resend code.
409 $('body').on('click', '#wd-2fa-resend-code', function (e) {
410 e.preventDefault();
411 resend_code();
412 });
413 });
414 </script>
415 END;
416 add_action(
417 'wp_print_footer_scripts',
418 function () use ( $totp_script ) {
419 /**
420 * Ignore WordPress.Security.EscapeOutput.OutputNotEscaped
421 * Why?
422 * We don't want to escape scripts here.
423 */
424 echo $totp_script; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
425 }
426 );
427 ?>
428 <?php
429 }
430 ?>
431
432 <?php
433 if ( ! function_exists( 'login_footer' ) ) {
434 /**
435 * Outputs the footer for the login page.
436 *
437 * @param string $input_id Which input to auto-focus.
438 */
439 function login_footer( $input_id = '' ) {
440 global $interim_login;
441
442 // Don't allow interim logins to navigate away from the page.
443 if ( ! $interim_login ) :
444 ?>
445 <p id="backtoblog"><a href="
446 <?php
447 echo esc_url( home_url( '/' ) );
448 ?>
449 ">
450 <?php
451 printf(
452 /* translators: %s: site title */
453 esc_html_x( '&larr; Back to %s', 'site', 'defender-security' ),
454 esc_html( get_bloginfo( 'title', 'display' ) )
455 );
456 ?>
457 </a></p>
458 <?php
459 endif;
460 ?>
461
462 </div>
463
464 <?php
465 if ( ! empty( $input_id ) ) :
466 ?>
467 <script type="text/javascript">
468 try {
469 document.getElementById('<?php echo esc_js( $input_id ); ?>').focus();
470 } catch (e) {
471 }
472 if (typeof wpOnload == 'function') wpOnload();
473 </script>
474 <?php
475 endif;
476 ?>
477
478 <?php
479 /**
480 * Fires in the login page footer.
481 *
482 * @since 3.1.0
483 */
484 do_action( 'login_footer' );
485 ?>
486 <div class="clear"></div>
487 </body>
488
489 </html>
490 <?php
491 }
492 }
493 login_footer();
494 ?>
495