Version Description
Download this release
Release Info
Developer | kasparsd |
Plugin | Two-Factor |
Version | 0.7.1 |
Comparing to | |
See all releases |
Code changes from version 0.7.2 to 0.7.1
- class-two-factor-core.php +26 -46
- providers/class-two-factor-email.php +3 -3
- providers/class-two-factor-fido-u2f-admin.php +0 -1
- providers/class-two-factor-totp.php +1 -1
- providers/css/fido-u2f-admin.css +0 -2
- providers/js/fido-u2f-admin-inline-edit.js +8 -12
- providers/js/fido-u2f-admin.js +2 -2
- providers/js/fido-u2f-login.js +2 -2
- readme.txt +9 -2
- two-factor.php +2 -2
- user-edit.css +1 -1
class-two-factor-core.php
CHANGED
@@ -550,7 +550,7 @@ class Two_Factor_Core {
|
|
550 |
}
|
551 |
|
552 |
if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
|
553 |
-
wp_safe_redirect(
|
554 |
exit;
|
555 |
}
|
556 |
|
@@ -680,34 +680,34 @@ class Two_Factor_Core {
|
|
680 |
</div>
|
681 |
<?php endif; ?>
|
682 |
<style>
|
683 |
-
|
684 |
-
|
685 |
margin-top: 16px;
|
686 |
padding: 0 24px;
|
687 |
-
|
688 |
-
|
689 |
color: #999;
|
690 |
text-decoration: none;
|
691 |
-
|
692 |
-
|
693 |
display: none;
|
694 |
padding-left: 1.5em;
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
display: block;
|
700 |
-
|
701 |
</style>
|
702 |
|
703 |
<?php
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
|
708 |
login_footer();
|
709 |
?>
|
710 |
-
|
711 |
}
|
712 |
|
713 |
/**
|
@@ -728,17 +728,6 @@ class Two_Factor_Core {
|
|
728 |
return add_query_arg( $params, site_url( 'wp-login.php', $scheme ) );
|
729 |
}
|
730 |
|
731 |
-
/**
|
732 |
-
* Get the hash of a nonce for storage and comparison.
|
733 |
-
*
|
734 |
-
* @param string $nonce Nonce value to be hashed.
|
735 |
-
*
|
736 |
-
* @return string
|
737 |
-
*/
|
738 |
-
protected static function hash_login_nonce( $nonce ) {
|
739 |
-
return wp_hash( $nonce, 'nonce' );
|
740 |
-
}
|
741 |
-
|
742 |
/**
|
743 |
* Create the login nonce.
|
744 |
*
|
@@ -748,21 +737,15 @@ class Two_Factor_Core {
|
|
748 |
* @return array
|
749 |
*/
|
750 |
public static function create_login_nonce( $user_id ) {
|
751 |
-
$login_nonce = array(
|
752 |
-
'expiration' => time() + HOUR_IN_SECONDS,
|
753 |
-
);
|
754 |
-
|
755 |
try {
|
756 |
$login_nonce['key'] = bin2hex( random_bytes( 32 ) );
|
757 |
} catch ( Exception $ex ) {
|
758 |
$login_nonce['key'] = wp_hash( $user_id . wp_rand() . microtime(), 'nonce' );
|
759 |
}
|
|
|
760 |
|
761 |
-
|
762 |
-
$login_nonce_stored = $login_nonce;
|
763 |
-
$login_nonce_stored['key'] = self::hash_login_nonce( $login_nonce['key'] );
|
764 |
-
|
765 |
-
if ( ! update_user_meta( $user_id, self::USER_META_NONCE_KEY, $login_nonce_stored ) ) {
|
766 |
return false;
|
767 |
}
|
768 |
|
@@ -792,19 +775,16 @@ class Two_Factor_Core {
|
|
792 |
*/
|
793 |
public static function verify_login_nonce( $user_id, $nonce ) {
|
794 |
$login_nonce = get_user_meta( $user_id, self::USER_META_NONCE_KEY, true );
|
795 |
-
|
796 |
-
if ( ! $login_nonce || empty( $login_nonce['key'] ) || empty( $login_nonce['expiration'] ) ) {
|
797 |
return false;
|
798 |
}
|
799 |
|
800 |
-
if (
|
801 |
-
|
|
|
802 |
}
|
803 |
|
804 |
-
|
805 |
-
self::delete_login_nonce( $user_id );
|
806 |
-
|
807 |
-
return false;
|
808 |
}
|
809 |
|
810 |
/**
|
@@ -826,7 +806,7 @@ class Two_Factor_Core {
|
|
826 |
}
|
827 |
|
828 |
if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
|
829 |
-
wp_safe_redirect(
|
830 |
exit;
|
831 |
}
|
832 |
|
@@ -999,7 +979,7 @@ class Two_Factor_Core {
|
|
999 |
*
|
1000 |
* @param WP_User $user The user.
|
1001 |
*/
|
1002 |
-
do_action_deprecated(
|
1003 |
do_action( 'two_factor_user_options_' . $class, $user );
|
1004 |
?>
|
1005 |
</td>
|
550 |
}
|
551 |
|
552 |
if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
|
553 |
+
wp_safe_redirect( get_bloginfo( 'url' ) );
|
554 |
exit;
|
555 |
}
|
556 |
|
680 |
</div>
|
681 |
<?php endif; ?>
|
682 |
<style>
|
683 |
+
/* @todo: migrate to an external stylesheet. */
|
684 |
+
.backup-methods-wrap {
|
685 |
margin-top: 16px;
|
686 |
padding: 0 24px;
|
687 |
+
}
|
688 |
+
.backup-methods-wrap a {
|
689 |
color: #999;
|
690 |
text-decoration: none;
|
691 |
+
}
|
692 |
+
ul.backup-methods {
|
693 |
display: none;
|
694 |
padding-left: 1.5em;
|
695 |
+
}
|
696 |
+
/* Prevent Jetpack from hiding our controls, see https://github.com/Automattic/jetpack/issues/3747 */
|
697 |
+
.jetpack-sso-form-display #loginform > p,
|
698 |
+
.jetpack-sso-form-display #loginform > div {
|
699 |
display: block;
|
700 |
+
}
|
701 |
</style>
|
702 |
|
703 |
<?php
|
704 |
+
if ( ! function_exists( 'login_footer' ) ) {
|
705 |
+
include_once TWO_FACTOR_DIR . 'includes/function.login-footer.php';
|
706 |
+
}
|
707 |
|
708 |
login_footer();
|
709 |
?>
|
710 |
+
<?php
|
711 |
}
|
712 |
|
713 |
/**
|
728 |
return add_query_arg( $params, site_url( 'wp-login.php', $scheme ) );
|
729 |
}
|
730 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
731 |
/**
|
732 |
* Create the login nonce.
|
733 |
*
|
737 |
* @return array
|
738 |
*/
|
739 |
public static function create_login_nonce( $user_id ) {
|
740 |
+
$login_nonce = array();
|
|
|
|
|
|
|
741 |
try {
|
742 |
$login_nonce['key'] = bin2hex( random_bytes( 32 ) );
|
743 |
} catch ( Exception $ex ) {
|
744 |
$login_nonce['key'] = wp_hash( $user_id . wp_rand() . microtime(), 'nonce' );
|
745 |
}
|
746 |
+
$login_nonce['expiration'] = time() + HOUR_IN_SECONDS;
|
747 |
|
748 |
+
if ( ! update_user_meta( $user_id, self::USER_META_NONCE_KEY, $login_nonce ) ) {
|
|
|
|
|
|
|
|
|
749 |
return false;
|
750 |
}
|
751 |
|
775 |
*/
|
776 |
public static function verify_login_nonce( $user_id, $nonce ) {
|
777 |
$login_nonce = get_user_meta( $user_id, self::USER_META_NONCE_KEY, true );
|
778 |
+
if ( ! $login_nonce ) {
|
|
|
779 |
return false;
|
780 |
}
|
781 |
|
782 |
+
if ( $nonce !== $login_nonce['key'] || time() > $login_nonce['expiration'] ) {
|
783 |
+
self::delete_login_nonce( $user_id );
|
784 |
+
return false;
|
785 |
}
|
786 |
|
787 |
+
return true;
|
|
|
|
|
|
|
788 |
}
|
789 |
|
790 |
/**
|
806 |
}
|
807 |
|
808 |
if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
|
809 |
+
wp_safe_redirect( get_bloginfo( 'url' ) );
|
810 |
exit;
|
811 |
}
|
812 |
|
979 |
*
|
980 |
* @param WP_User $user The user.
|
981 |
*/
|
982 |
+
do_action_deprecated( 'two-factor-user-options-' . $class, array( $user ), '0.7.0', 'two_factor_user_options_' . $class );
|
983 |
do_action( 'two_factor_user_options_' . $class, $user );
|
984 |
?>
|
985 |
</td>
|
providers/class-two-factor-email.php
CHANGED
@@ -187,7 +187,7 @@ class Two_Factor_Email extends Two_Factor_Provider {
|
|
187 |
$hashed_token = $this->get_user_token( $user_id );
|
188 |
|
189 |
// Bail if token is empty or it doesn't match.
|
190 |
-
if ( empty( $hashed_token ) ||
|
191 |
return false;
|
192 |
}
|
193 |
|
@@ -224,7 +224,7 @@ class Two_Factor_Email extends Two_Factor_Provider {
|
|
224 |
$token = $this->generate_token( $user->ID );
|
225 |
|
226 |
/* translators: %s: site name */
|
227 |
-
$subject = wp_strip_all_tags( sprintf( __( 'Your login confirmation code for %s', 'two-factor' ),
|
228 |
/* translators: %s: token */
|
229 |
$message = wp_strip_all_tags( sprintf( __( 'Enter %s to log in.', 'two-factor' ), $token ) );
|
230 |
|
@@ -245,7 +245,7 @@ class Two_Factor_Email extends Two_Factor_Provider {
|
|
245 |
*/
|
246 |
$message = apply_filters( 'two_factor_token_email_message', $message, $token, $user->ID );
|
247 |
|
248 |
-
return wp_mail( $user->user_email, $subject, $message );
|
249 |
}
|
250 |
|
251 |
/**
|
187 |
$hashed_token = $this->get_user_token( $user_id );
|
188 |
|
189 |
// Bail if token is empty or it doesn't match.
|
190 |
+
if ( empty( $hashed_token ) || ( wp_hash( $token ) !== $hashed_token ) ) {
|
191 |
return false;
|
192 |
}
|
193 |
|
224 |
$token = $this->generate_token( $user->ID );
|
225 |
|
226 |
/* translators: %s: site name */
|
227 |
+
$subject = wp_strip_all_tags( sprintf( __( 'Your login confirmation code for %s', 'two-factor' ), get_bloginfo( 'name' ) ) );
|
228 |
/* translators: %s: token */
|
229 |
$message = wp_strip_all_tags( sprintf( __( 'Enter %s to log in.', 'two-factor' ), $token ) );
|
230 |
|
245 |
*/
|
246 |
$message = apply_filters( 'two_factor_token_email_message', $message, $token, $user->ID );
|
247 |
|
248 |
+
return wp_mail( $user->user_email, $subject, $message );
|
249 |
}
|
250 |
|
251 |
/**
|
providers/class-two-factor-fido-u2f-admin.php
CHANGED
@@ -281,7 +281,6 @@ class Two_Factor_FIDO_U2F_Admin {
|
|
281 |
Two_Factor_FIDO_U2F::delete_security_key( $user_id, $slug );
|
282 |
|
283 |
wp_safe_redirect( remove_query_arg( 'new_app_pass', wp_get_referer() ) . '#security-keys-section' );
|
284 |
-
exit;
|
285 |
}
|
286 |
}
|
287 |
|
281 |
Two_Factor_FIDO_U2F::delete_security_key( $user_id, $slug );
|
282 |
|
283 |
wp_safe_redirect( remove_query_arg( 'new_app_pass', wp_get_referer() ) . '#security-keys-section' );
|
|
|
284 |
}
|
285 |
}
|
286 |
|
providers/class-two-factor-totp.php
CHANGED
@@ -361,7 +361,7 @@ class Two_Factor_Totp extends Two_Factor_Provider {
|
|
361 |
if ( PHP_INT_SIZE >= 8 ) {
|
362 |
// If we're on PHP 5.6.3+ we can use the new 64bit pack functionality.
|
363 |
if ( version_compare( PHP_VERSION, '5.6.3', '>=' ) && PHP_INT_SIZE >= 8 ) {
|
364 |
-
return pack( 'J', $value );
|
365 |
}
|
366 |
$highmap = 0xffffffff << 32;
|
367 |
$higher = ( $value & $highmap ) >> 32;
|
361 |
if ( PHP_INT_SIZE >= 8 ) {
|
362 |
// If we're on PHP 5.6.3+ we can use the new 64bit pack functionality.
|
363 |
if ( version_compare( PHP_VERSION, '5.6.3', '>=' ) && PHP_INT_SIZE >= 8 ) {
|
364 |
+
return pack( 'J', $value );
|
365 |
}
|
366 |
$highmap = 0xffffffff << 32;
|
367 |
$higher = ( $value & $highmap ) >> 32;
|
providers/css/fido-u2f-admin.css
CHANGED
@@ -1,11 +1,9 @@
|
|
1 |
#security-keys-section .wp-list-table {
|
2 |
margin-bottom: 2em;
|
3 |
}
|
4 |
-
|
5 |
#security-keys-section .register-security-key .spinner {
|
6 |
float: none;
|
7 |
}
|
8 |
-
|
9 |
#security-keys-section .security-key-status {
|
10 |
vertical-align: middle;
|
11 |
font-style: italic;
|
1 |
#security-keys-section .wp-list-table {
|
2 |
margin-bottom: 2em;
|
3 |
}
|
|
|
4 |
#security-keys-section .register-security-key .spinner {
|
5 |
float: none;
|
6 |
}
|
|
|
7 |
#security-keys-section .security-key-status {
|
8 |
vertical-align: middle;
|
9 |
font-style: italic;
|
providers/js/fido-u2f-admin-inline-edit.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/* global
|
2 |
var inlineEditKey;
|
3 |
|
4 |
( function( $ ) {
|
@@ -39,12 +39,7 @@ var inlineEditKey;
|
|
39 |
|
40 |
toggle: function( el ) {
|
41 |
var t = this;
|
42 |
-
|
43 |
-
if ( 'none' === $( t.what + t.getId( el ) ).css( 'display' ) ) {
|
44 |
-
t.revert();
|
45 |
-
} else {
|
46 |
-
t.edit( el );
|
47 |
-
}
|
48 |
},
|
49 |
|
50 |
edit: function( id ) {
|
@@ -56,9 +51,7 @@ var inlineEditKey;
|
|
56 |
id = t.getId( id );
|
57 |
}
|
58 |
|
59 |
-
editRow = $( '#inline-edit' ).clone( true );
|
60 |
-
rowData = $( '#inline_' + id );
|
61 |
-
|
62 |
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '#security-keys-section .widefat thead' ).length );
|
63 |
|
64 |
$( t.what + id ).hide().after( editRow ).after( '<tr class="hidden"></tr>' );
|
@@ -97,7 +90,7 @@ var inlineEditKey;
|
|
97 |
// Make ajax request.
|
98 |
$.post( ajaxurl, params,
|
99 |
function( r ) {
|
100 |
-
var row, newID;
|
101 |
$( '#security-keys-section table.widefat .spinner' ).removeClass( 'is-active' );
|
102 |
|
103 |
if ( r ) {
|
@@ -108,8 +101,10 @@ var inlineEditKey;
|
|
108 |
$( '#edit-' + id ).before( r ).remove();
|
109 |
|
110 |
if ( newID ) {
|
|
|
111 |
row = $( '#' + newID );
|
112 |
} else {
|
|
|
113 |
row = $( inlineEditKey.what + id );
|
114 |
}
|
115 |
|
@@ -147,4 +142,5 @@ var inlineEditKey;
|
|
147 |
$( document ).ready( function() {
|
148 |
inlineEditKey.init();
|
149 |
} );
|
150 |
-
|
|
1 |
+
/* global inlineEditL10n, ajaxurl */
|
2 |
var inlineEditKey;
|
3 |
|
4 |
( function( $ ) {
|
39 |
|
40 |
toggle: function( el ) {
|
41 |
var t = this;
|
42 |
+
'none' === $( t.what + t.getId( el ) ).css( 'display' ) ? t.revert() : t.edit( el );
|
|
|
|
|
|
|
|
|
|
|
43 |
},
|
44 |
|
45 |
edit: function( id ) {
|
51 |
id = t.getId( id );
|
52 |
}
|
53 |
|
54 |
+
editRow = $( '#inline-edit' ).clone( true ), rowData = $( '#inline_' + id );
|
|
|
|
|
55 |
$( 'td', editRow ).attr( 'colspan', $( 'th:visible, td:visible', '#security-keys-section .widefat thead' ).length );
|
56 |
|
57 |
$( t.what + id ).hide().after( editRow ).after( '<tr class="hidden"></tr>' );
|
90 |
// Make ajax request.
|
91 |
$.post( ajaxurl, params,
|
92 |
function( r ) {
|
93 |
+
var row, newID, optionValue;
|
94 |
$( '#security-keys-section table.widefat .spinner' ).removeClass( 'is-active' );
|
95 |
|
96 |
if ( r ) {
|
101 |
$( '#edit-' + id ).before( r ).remove();
|
102 |
|
103 |
if ( newID ) {
|
104 |
+
optionValue = newID.replace( 'key-', '' );
|
105 |
row = $( '#' + newID );
|
106 |
} else {
|
107 |
+
optionValue = id;
|
108 |
row = $( inlineEditKey.what + id );
|
109 |
}
|
110 |
|
142 |
$( document ).ready( function() {
|
143 |
inlineEditKey.init();
|
144 |
} );
|
145 |
+
|
146 |
+
} )( jQuery );
|
providers/js/fido-u2f-admin.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/* global
|
2 |
( function( $ ) {
|
3 |
var $button = $( '#register_security_key' );
|
4 |
var $statusNotice = $( '#security-keys-section .security-key-status' );
|
@@ -45,4 +45,4 @@
|
|
45 |
$( '<form>' )[0].submit.call( $( '#your-profile' )[0] );
|
46 |
} );
|
47 |
} );
|
48 |
-
}( jQuery )
|
1 |
+
/* global u2f, u2fL10n */
|
2 |
( function( $ ) {
|
3 |
var $button = $( '#register_security_key' );
|
4 |
var $statusNotice = $( '#security-keys-section .security-key-status' );
|
45 |
$( '<form>' )[0].submit.call( $( '#your-profile' )[0] );
|
46 |
} );
|
47 |
} );
|
48 |
+
} )( jQuery );
|
providers/js/fido-u2f-login.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/* global
|
2 |
( function( $ ) {
|
3 |
if ( ! window.u2fL10n ) {
|
4 |
window.console.error( 'u2fL10n is not defined' );
|
@@ -13,4 +13,4 @@
|
|
13 |
$( '#loginform' ).submit();
|
14 |
}
|
15 |
} );
|
16 |
-
}( jQuery )
|
1 |
+
/* global u2f, u2fL10n */
|
2 |
( function( $ ) {
|
3 |
if ( ! window.u2fL10n ) {
|
4 |
window.console.error( 'u2fL10n is not defined' );
|
13 |
$( '#loginform' ).submit();
|
14 |
}
|
15 |
} );
|
16 |
+
} )( jQuery );
|
readme.txt
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
Contributors: georgestephanis, valendesigns, stevenkword, extendwings, sgrant, aaroncampbell, johnbillion, stevegrunwell, netweb, kasparsd, alihusnainarshad, passoniate
|
3 |
Tags: two factor, two step, authentication, login, totp, fido u2f, u2f, email, backup codes, 2fa, yubikey
|
4 |
Requires at least: 4.3
|
5 |
-
Tested up to:
|
6 |
Requires PHP: 5.6
|
7 |
Stable tag: trunk
|
8 |
|
@@ -37,7 +37,14 @@ Here is a list of action and filter hooks provided by the plugin:
|
|
37 |
|
38 |
== Get Involved ==
|
39 |
|
40 |
-
Development happens [on GitHub](https://github.com/wordpress/two-factor/).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
2 |
Contributors: georgestephanis, valendesigns, stevenkword, extendwings, sgrant, aaroncampbell, johnbillion, stevegrunwell, netweb, kasparsd, alihusnainarshad, passoniate
|
3 |
Tags: two factor, two step, authentication, login, totp, fido u2f, u2f, email, backup codes, 2fa, yubikey
|
4 |
Requires at least: 4.3
|
5 |
+
Tested up to: 5.8
|
6 |
Requires PHP: 5.6
|
7 |
Stable tag: trunk
|
8 |
|
37 |
|
38 |
== Get Involved ==
|
39 |
|
40 |
+
Development happens [on GitHub](https://github.com/wordpress/two-factor/). Join the `#core-passwords` channel [on WordPress Slack](http://wordpress.slack.com) ([sign up here](http://chat.wordpress.org)).
|
41 |
+
|
42 |
+
Here is how to get started:
|
43 |
+
|
44 |
+
$ git clone https://github.com/wordpress/two-factor.git
|
45 |
+
$ npm install
|
46 |
+
|
47 |
+
Then open [a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) with the suggested changes.
|
48 |
|
49 |
== Changelog ==
|
50 |
|
two-factor.php
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
* Plugin URI: https://wordpress.org/plugins/two-factor/
|
13 |
* Description: Two-Factor Authentication using time-based one-time passwords, Universal 2nd Factor (FIDO U2F), email and backup verification codes.
|
14 |
* Author: Plugin Contributors
|
15 |
-
* Version: 0.7.
|
16 |
* Author URI: https://github.com/wordpress/two-factor/graphs/contributors
|
17 |
* Network: True
|
18 |
* Text Domain: two-factor
|
@@ -26,7 +26,7 @@ define( 'TWO_FACTOR_DIR', plugin_dir_path( __FILE__ ) );
|
|
26 |
/**
|
27 |
* Version of the plugin.
|
28 |
*/
|
29 |
-
define( 'TWO_FACTOR_VERSION', '0.7.
|
30 |
|
31 |
/**
|
32 |
* Include the base class here, so that other plugins can also extend it.
|
12 |
* Plugin URI: https://wordpress.org/plugins/two-factor/
|
13 |
* Description: Two-Factor Authentication using time-based one-time passwords, Universal 2nd Factor (FIDO U2F), email and backup verification codes.
|
14 |
* Author: Plugin Contributors
|
15 |
+
* Version: 0.7.1
|
16 |
* Author URI: https://github.com/wordpress/two-factor/graphs/contributors
|
17 |
* Network: True
|
18 |
* Text Domain: two-factor
|
26 |
/**
|
27 |
* Version of the plugin.
|
28 |
*/
|
29 |
+
define( 'TWO_FACTOR_VERSION', '0.7.1' );
|
30 |
|
31 |
/**
|
32 |
* Include the base class here, so that other plugins can also extend it.
|
user-edit.css
CHANGED
@@ -34,4 +34,4 @@
|
|
34 |
|
35 |
.two-factor-methods-table tbody tr:nth-child(odd) {
|
36 |
background-color: #f9f9f9;
|
37 |
-
}
|
34 |
|
35 |
.two-factor-methods-table tbody tr:nth-child(odd) {
|
36 |
background-color: #f9f9f9;
|
37 |
+
}
|