Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c5e1502
Add network-level settings to force 2-factor auth for whole site or s…
mikeselander Sep 3, 2018
571bc63
Add helper functions to evaluate whether the current user requires 2f…
mikeselander Sep 3, 2018
48e4ba1
Add basic force-2fa-view functionality
mikeselander Sep 3, 2018
4e2873c
Add form submission and AJAX handling of two-factor settings form
mikeselander Sep 3, 2018
7d478a9
Small self-review cleanups
mikeselander Sep 4, 2018
de2d5bb
Load force-2fa script more intelligently
mikeselander Sep 4, 2018
28024b8
Replace Back to Site link with Logout link as an escape hatch
mikeselander Sep 4, 2018
8ace959
Do not block REST requests
mikeselander Sep 4, 2018
0ed9963
Clean up title styling
mikeselander Sep 4, 2018
884baed
Prepare value getters to work with either multi or single site
mikeselander Sep 4, 2018
82ee390
Handle REST check with two separate hooks to properly capture late-re…
mikeselander Sep 4, 2018
1db7029
Add hook for providers to save their data against on AJAX submission …
mikeselander Sep 4, 2018
5b644f7
Remove inline styles and use user-edit CSS instead
mikeselander Sep 4, 2018
1ace71e
Hide unnecessary label on force-2fa view
mikeselander Sep 4, 2018
bad9706
CS cleanup
mikeselander Sep 4, 2018
681da69
Add tests for business-critical methods
mikeselander Sep 4, 2018
8d531bf
Add returns to maybe_force_2fa_settings for better testability
mikeselander Sep 4, 2018
d4712ce
Self-review cleanup
mikeselander Sep 4, 2018
bcbfec3
Register and save values against a single site'
mikeselander Sep 4, 2018
0898fdc
Enqueue assets for Fido 2f on forced 2f takeover
mikeselander Sep 4, 2018
26824fc
Add spacing
mikeselander Sep 5, 2018
51b93a3
Remove unnecessary ternary
mikeselander Sep 5, 2018
2723f88
Update language on global 2fa forcing option
mikeselander Sep 5, 2018
8980d90
Split up core class into Force and Core for better separation
mikeselander Sep 5, 2018
e8ccab1
Add custom path and handling for force-2fa
mikeselander Sep 5, 2018
13a8cf7
Clean up
mikeselander Sep 5, 2018
0b356f3
Clean up according to es linter on Travis
mikeselander Sep 5, 2018
de8ea84
Add phpcs:ignore for incorrectly flagged issues
mikeselander Sep 17, 2018
7b4cce3
Properly space these
mikeselander Sep 17, 2018
f7cc27e
Allow user to remove forced 2fa on all roles
tcrsavage May 8, 2019
252e3e0
Merge pull request #2 from humanmade/force-2fa-fix-empty-role-config
joehoyle Jul 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions assets/js/force-2fa.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* global ajaxurl, jQuery */

/**
* Checks that an element has a non-empty `name` and `value` property.
*
* @param {Element} element The element to check
* @return {Boolean} true if the element is an input, false if not
*/
var isValidElement = function( element ) {
return element.name && element.value;
};

/**
* Checks if an element’s value can be saved (e.g. not an unselected checkbox).
*
* @param {Element} element The element to check
* @return {Boolean} true if the value should be added, false if not
*/
var isValidValue = function( element ) {
return ( ! [ 'checkbox', 'radio' ].includes( element.type ) || element.checked );
};

/**
* Checks if an input is a checkbox, because checkboxes allow multiple values.
*
* @param {Element} element The element to check
* @return {Boolean} true if the element is a checkbox, false if not
*/
var isCheckbox = function( element ) {
return 'checkbox' === element.type;
};

/**
* Retrieves input data from a form and returns it as a JSON object.
*
* @param {HTMLFormControlsCollection} elements the form elements
* @return {Object} form data as an object literal
*/
var formToJSON = function( elements ) {
return [].reduce.call( elements, function( data, element ) {

// Make sure the element has the required properties and should be added.
if ( ! isValidElement( element ) || ! isValidValue( element ) ) {
return data;
}

/*
* Some fields allow for more than one value, so we need to check if this
* is one of those fields and, if so, store the values as an array.
*/
if ( isCheckbox( element ) ) {
data[ element.name ] = ( data[ element.name ] || [] ).concat( element.value );
} else {
data[ element.name ] = element.value;
}

return data;
}, {} );
};

/**
* A handler function to prevent default submission and run our custom script.
*
* @param {Event} event the submit event triggered by the user
*/
var handleFormSubmit = function( event ) {

// Get form data.
var formData = formToJSON( event.target.elements );

event.preventDefault();

formData.action = 'two_factor_force_form_submit';

// Submit data to WordPress.
jQuery.post(
ajaxurl,
formData,
function () {
window.location.reload();
}
);
};

window.addEventListener( 'load', function() {
var form = document.querySelector( '#force_2fa_form' );
form.addEventListener( 'submit', handleFormSubmit );
} );
16 changes: 14 additions & 2 deletions class.two-factor-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ public static function add_hooks() {
add_action( 'edit_user_profile', array( __CLASS__, 'user_two_factor_options' ) );
add_action( 'personal_options_update', array( __CLASS__, 'user_two_factor_options_update' ) );
add_action( 'edit_user_profile_update', array( __CLASS__, 'user_two_factor_options_update' ) );
add_action( 'two_factor_ajax_options_update', array( __CLASS__, 'user_two_factor_options_update' ) );
add_filter( 'manage_users_columns', array( __CLASS__, 'filter_manage_users_columns' ) );
add_filter( 'wpmu_users_columns', array( __CLASS__, 'filter_manage_users_columns' ) );
add_filter( 'manage_users_custom_column', array( __CLASS__, 'manage_users_custom_column' ), 10, 3 );
add_action( 'init', array( __CLASS__, 'register_scripts' ) );
}

/**
Expand All @@ -58,6 +60,16 @@ public static function load_textdomain() {
load_plugin_textdomain( 'two-factor' );
}

/**
* Register scripts.
*/
public static function register_scripts() {
wp_register_style(
'user-edit-2fa',
plugins_url( 'user-edit.css', __FILE__ )
);
}

/**
* For each provider, include it and then instantiate it.
*
Expand Down Expand Up @@ -608,7 +620,7 @@ public static function manage_users_custom_column( $output, $column_name, $user_
* @param WP_User $user WP_User object of the logged-in user.
*/
public static function user_two_factor_options( $user ) {
wp_enqueue_style( 'user-edit-2fa', plugins_url( 'user-edit.css', __FILE__ ) );
wp_enqueue_style( 'user-edit-2fa' );

$enabled_providers = array_keys( self::get_available_providers_for_user( $user->ID ) );
$primary_provider = self::get_primary_provider_for_user( $user->ID );
Expand All @@ -625,7 +637,7 @@ public static function user_two_factor_options( $user ) {
<input type="hidden" name="<?php echo esc_attr( self::ENABLED_PROVIDERS_USER_META_KEY ); ?>[]" value="<?php /* Dummy input so $_POST value is passed when no providers are enabled. */ ?>" />
<table class="form-table">
<tr>
<th>
<th class="two-factor-main-label">
<?php esc_html_e( 'Two-Factor Options' ); ?>
</th>
<td>
Expand Down
Loading