jQuery(function($) {
var username_requires_otp = [];
/**
* Returns the jQuery identifiers for finding the username field. Abstracted here to avoid maintaining multiple lists.
*
* @return String
*/
function get_username_identifiers() {
// 'username' is used by WooCommerce
return '[name="log"], [name="username"], #user_login, #affwp-login-user-login, #affwp-user-login, #gform_fields_login input[type="text"]';
}
/**
* Process the results of a check for whether the user has TFA enabled or not
*
* @param Object form - jQuery form object
* @param Object response - the response from the check; must have the property (boolean) "status" and potentially user_(boolean) "can_trust" and (boolean) user_can_trust.
*/
function process_user_tfa_enabled_check_results(form, response) {
if (true === response.status) {
// Don't bother to remove the spinner if the form is being submitted.
$('.simbaotp_spinner').remove();
var user_can_trust = (response.hasOwnProperty('user_can_trust') && response.user_can_trust) ? true : false;
var user_already_trusted = (response.hasOwnProperty('user_already_trusted') && response.user_can_trust) ? true : false;
console.log("Simba TFA: User has OTP enabled: showing OTP field (user_can_trust="+user_can_trust+")");
show_otp_field(form, user_can_trust, user_already_trusted);
return true;
} else {
console.log("Simba TFA: User does not have OTP enabled: submitting form");
// For some reason, .submit() stopped working with TML 7.x. N.B. Used to do this only for form_type == 2 ("TML shortcode or widget, WP Members, bbPress, Ultimate Membership Pro, WooCommerce or Elementor login form")
$(form).find('input[type="submit"], button[type="submit"]').first().trigger('click');
// $('#wp-submit').parents('form').first().trigger('submit');
}
return false;
}
/**
* Check if the user requires an OTP field and if so, display it
*
* @param String form - DOM selector string
* @param Boolean only_cache_the_results - if true, then nothing more will be done that caching the results (in the variable username_requires_otp will be updated)
*
* @uses show_otp_field()
*
* @return Boolean - true if we got involved
*/
function check_and_possibly_show_otp_field(form, only_cache_the_results) {
// If this is a "lost password" form, then exit
if ($(form).attr('id') === 'lostpasswordform' || $(form).attr('id') === 'resetpasswordform') return false;
var username = $(form).find(get_username_identifiers()).first().val();
if (!username.length) return false;
// Is the result already known?
if ('object' === typeof username_requires_otp[username]) {
if (!only_cache_the_results) {
// Process the already-known result
return process_user_tfa_enabled_check_results($(form), username_requires_otp[username]);
}
// No further processing
return true;
}
var $submit_button = $(form).find('input[name="wp-submit"], input[type="submit"], button[type="submit"]').first();
if (simba_tfasettings.hasOwnProperty('spinnerimg') && $('.simbaotp_spinner').length === 0) {
var styling = 'float:right; margin:6px 12px; width: 20px; height: 20px;';
if ($('#theme-my-login #wp-submit').length >0) {
styling = 'margin-left: 4px; position: relative; top: 4px; width: 20px; height: 20px; border:0px; box-shadow:none;';
}
$submit_button.after('');
}
$.ajax({
url: simba_tfasettings.ajaxurl,
type: 'POST',
data: {
action: 'simbatfa-init-otp',
user: username
},
dataType: 'text',
success: function(resp) {
try {
var json_begins = resp.search('{"jsonstarter":"justhere"');
if (json_begins > -1) {
if (json_begins > 0) {
console.log("Expected JSON marker found at position: "+json_begins);
resp = resp.substring(json_begins);
}
} else {
console.log("Expected JSON marker not found");
console.log(resp);
}
response = JSON.parse(resp);
if (response.hasOwnProperty('php_output')) {
console.log("PHP output was returned (follows)");
console.log(response.php_output);
}
if (response.hasOwnProperty('extra_output')) {
console.log("Extra output was returned (follows)");
console.log(response.extra_output);
}
if (only_cache_the_results) {
// Save the result for later processing
username_requires_otp[username] = response;
$('.simbaotp_spinner').remove();
} else {
process_user_tfa_enabled_check_results($(form), response);
}
} catch(err) {
$('#login').html(resp);
console.log("Simba TFA: Error when processing response");
console.log(err);
console.log(resp);
}
},
error: function(jq_xhr, text_status, error_thrown) {
console.log("Simba TFA: AJAX error: "+error_thrown+": "+text_status);
console.log(jq_xhr);
if (jq_xhr.hasOwnProperty('responseText')) {
console.log(jq_xhr.responseText);
$(form).append('
'+simba_tfasettings.error+'
'); } } }); return true; } // Parameters: see check_and_possibly_show_otp_field function show_otp_field(form, user_can_trust, user_already_trusted) { var $submit_button; user_can_trust = ('undefined' == typeof user_can_trust) ? false : user_can_trust; user_already_trusted = ('undefined' == typeof user_already_trusted) ? false : user_already_trusted; if ('https:' != window.location.protocol && 'localhost' !== location.hostname && '127.0.0.1' !== location.hostname && /^\.localdomain$/.test(location.hostname)) { user_can_trust = false; } if (!user_can_trust) { user_already_trusted = false; } var form_is_gravity_forms = ('object' == typeof window['gform_gravityforms'] && 'undefined' !== typeof $(form).attr('id') && 'gform_' === $(form).attr('id').substring(0, 6)); // Gravity Forms won't submit if the elements are hidden var form_retain_existing_elements = form_is_gravity_forms ? true : false; // name="Submit" is WP-Members. 'submit' is Theme My Login starting from 7.x $submit_button = $(form).find('input[name="wp-submit"], input[name="Submit"], input[name="submit"]'); // This hasn't been needed for anything yet (Jul 2018), but is a decent back-stop that would have prevented some breakage in the past that needed manual attention: if (0 == $submit_button.length) { $submit_button = $(form).find('input[type="submit"], button[type="submit"]').first(); } if (!form_retain_existing_elements) { // Hide all elements in a browser-safe way // .user-pass-wrap is the wrapper used (instead of a paragraph) on wp-login.php from WP 5.3 $submit_button.parents('form').first().find('p, .impu-form-line-fr, .tml-field-wrap, .user-pass-wrap, .elementor-field-type-text, .elementor-field-type-submit, .elementor-remember-me, .bbp-username, .bbp-password, .bbp-submit-wrapper, .gform_body').each(function(i) { $(this).css('visibility', 'hidden').css('position', 'absolute'); // On the WooCommerce form, the 'required' asterisk in the child still shows without this $(this).find('span').css('visibility', 'hidden').css('position', 'absolute'); }); // WP-Members $submit_button.parents('#wpmem_login').find('fieldset').css('visibility', 'hidden').css('position', 'absolute'); } // Add new field and controls var html = ''; if (user_already_trusted) { html += ''; // Would need further styling investigations to display this if (!form_is_gravity_forms) { html += ''+simba_tfasettings.otp_login_help+''; } if (user_can_trust) { html += ''; } } html += '
'; var submit_button_text; var submit_button_name; // Gravity forms doesn't like its button being disabled if (!form_is_gravity_forms) { if ('button' == $submit_button.prop('nodeName').toLowerCase()) { submit_button_text = $submit_button.text().trim(); submit_button_name = $submit_button.attr('name'); } else { submit_button_text = $submit_button.val(); submit_button_name = $submit_button.attr('name'); } html += ''; $submit_button.prop('disabled', true).hide(); } if (form_retain_existing_elements && form_is_gravity_forms) { // $submit_button.parents('form').first().append(html); //$('