PageSourceSearch

https://javapro.io/wp-content/plugins/all-in-one-wp-security-and-f…/simba-tfa/includes/tfa.js?ver=1790954247

js javapro.io collected 2026-10-02 15:18:21 UTC 11,830 bytes, 326 lines download raw bytes

1jQuery(function($) {
2
3	var username_requires_otp = [];
4	
5	/**
6	 * Returns the jQuery identifiers for finding the username field. Abstracted here to avoid maintaining multiple lists.
7	 *
8	 * @return String
9	 */
10	function get_username_identifiers() {
11		// 'username' is used by WooCommerce
12		return '[name="log"], [name="username"], #user_login, #affwp-login-user-login, #affwp-user-login, #gform_fields_login input[type="text"]';
13	}
14	
15	/**
16	 * Process the results of a check for whether the user has TFA enabled or not
17	 *
18	 * @param Object form	  - jQuery form object
19	 * @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.
20	 */
21	function process_user_tfa_enabled_check_results(form, response) {
22
23		if (true === response.status) {
24			// Don't bother to remove the spinner if the form is being submitted.
25			$('.simbaotp_spinner').remove();
26			
27			var user_can_trust = (response.hasOwnProperty('user_can_trust') && response.user_can_trust) ? true : false;
28			
29			var user_already_trusted = (response.hasOwnProperty('user_already_trusted') && response.user_can_trust) ? true : false;
30			
31			console.log("Simba TFA: User has OTP enabled: showing OTP field (user_can_trust="+user_can_trust+")");
32			
33			show_otp_field(form, user_can_trust, user_already_trusted);
34			
35			return true;
36			
37		} else {
38			console.log("Simba TFA: User does not have OTP enabled: submitting form");
39			// 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")
40			$(form).find('input[type="submit"], button[type="submit"]').first().trigger('click');
41			// $('#wp-submit').parents('form').first().trigger('submit');
42		}
43		return false;
44	}
45	
46	/**
47	 * Check if the user requires an OTP field and if so, display it
48	 *
49	 * @param String  form					   - DOM selector string
50	 * @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)
51	 *
52	 * @uses show_otp_field()
53	 *
54	 * @return Boolean - true if we got involved
55	 */
56	function check_and_possibly_show_otp_field(form, only_cache_the_results) {
57
58		// If this is a "lost password" form, then exit
59		if ($(form).attr('id') === 'lostpasswordform' || $(form).attr('id') === 'resetpasswordform') return false;
60
61		var username = $(form).find(get_username_identifiers()).first().val();
62		
63		if (!username.length) return false;
64		
65		// Is the result already known?
66		if ('object' === typeof username_requires_otp[username]) {
67			if (!only_cache_the_results) {
68				// Process the already-known result
69				return process_user_tfa_enabled_check_results($(form), username_requires_otp[username]);
70			}
71			// No further processing
72			return true;
73		}
74		
75		var $submit_button = $(form).find('input[name="wp-submit"], input[type="submit"], button[type="submit"]').first();
76		
77		if (simba_tfasettings.hasOwnProperty('spinnerimg') && $('.simbaotp_spinner').length === 0) {
78			var styling = 'float:right; margin:6px 12px; width: 20px; height: 20px;';
79			if ($('#theme-my-login #wp-submit').length >0) {
80				styling = 'margin-left: 4px; position: relative; top: 4px; width: 20px; height: 20px; border:0px; box-shadow:none;';
81			}	
82			$submit_button.after('<img class="simbaotp_spinner" src="'+simba_tfasettings.spinnerimg+'" style="'+styling+'">');
83		}
84
85		$.ajax({
86			url: simba_tfasettings.ajaxurl,
87			type: 'POST',
88			data: {
89				action: 'simbatfa-init-otp',
90				user: username
91			},
92			dataType: 'text',
93			success: function(resp) {
94				try {
95					var json_begins = resp.search('{"jsonstarter":"justhere"');
96					if (json_begins > -1) {
97						if (json_begins > 0) {
98							console.log("Expected JSON marker found at position: "+json_begins);
99							resp = resp.substring(json_begins);
100						}
101					} else {
102						console.log("Expected JSON marker not found");
103						console.log(resp);
104					}
105					
106					response = JSON.parse(resp);
107					
108					if (response.hasOwnProperty('php_output')) {
109						console.log("PHP output was returned (follows)");
110						console.log(response.php_output);
111					}
112					
113					if (response.hasOwnProperty('extra_output')) {
114						console.log("Extra output was returned (follows)");
115						console.log(response.extra_output);
116					}
117					
118					if (only_cache_the_results) {
119						// Save the result for later processing
120						username_requires_otp[username] = response;
121						$('.simbaotp_spinner').remove();
122					} else {
123						process_user_tfa_enabled_check_results($(form), response);
124					}
125					
126				} catch(err) {
127					$('#login').html(resp);
128					console.log("Simba TFA: Error when processing response");
129					console.log(err);
130					console.log(resp);
131				}
132			},
133			error: function(jq_xhr, text_status, error_thrown) {
134				console.log("Simba TFA: AJAX error: "+error_thrown+": "+text_status);
135				console.log(jq_xhr);
136				if (jq_xhr.hasOwnProperty('responseText')) {
137					console.log(jq_xhr.responseText);
138					$(form).append('<p class="error" style="clear:left;">
138'+simba_tfasettings.error+'</p>');
139				}
140			}
141		});
142		return true;
143	}
144	
145	// Parameters: see check_and_possibly_show_otp_field
146	function show_otp_field(form, user_can_trust, user_already_trusted) {
147		
148		var $submit_button;
149		
150		user_can_trust = ('undefined' == typeof user_can_trust) ? false : user_can_trust;
151		user_already_trusted = ('undefined' == typeof user_already_trusted) ? false : user_already_trusted;
152		
153		if ('https:' != window.location.protocol && 'localhost' !== location.hostname && '127.0.0.1' !== location.hostname && /^\.localdomain$/.test(location.hostname)) {
154			user_can_trust = false;
155		}
156		
157		if (!user_can_trust) { user_already_trusted = false; }
158		
159		var form_is_gravity_forms = ('object' == typeof window['gform_gravityforms'] && 'undefined' !== typeof $(form).attr('id') && 'gform_' === $(form).attr('id').substring(0, 6));
160		
161		// Gravity Forms won't submit if the elements are hidden
162		var form_retain_existing_elements = form_is_gravity_forms ? true : false;
163		
164		// name="Submit" is WP-Members. 'submit' is Theme My Login starting from 7.x
165		$submit_button = $(form).find('input[name="wp-submit"], input[name="Submit"], input[name="submit"]');
166		// 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:
167		if (0 == $submit_button.length) {
168			$submit_button = $(form).find('input[type="submit"], button[type="submit"]').first();
169		}
170
171		if (!form_retain_existing_elements) {
172			// Hide all elements in a browser-safe way
173			// .user-pass-wrap is the wrapper used (instead of a paragraph) on wp-login.php from WP 5.3
174			$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) {
175				$(this).css('visibility', 'hidden').css('position', 'absolute');
176				// On the WooCommerce form, the 'required' asterisk in the child <span> still shows without this
177				$(this).find('span').css('visibility', 'hidden').css('position', 'absolute');
178			});
179			
180			// WP-Members
181			$submit_button.parents('#wpmem_login').find('fieldset').css('visibility', 'hidden').css('position', 'absolute');
182			
183		}
184		
185		// Add new field and controls
186		var html = '';
187		
188		if (user_already_trusted) {
189			
190			html += '<br><span class="simbaotp_is_trusted">'+simba_tfasettings.is_trusted+'</span>';
191			
192		} else {
193			
194			html += '<label ';
195			
196			if (form_is_gravity_forms) {
197				html += 'class="gfield_label"';
198			}
199			
200			html += 'for="simba_two_factor_auth">' + simba_tfasettings.otp + '<br><input type="text" name="two_factor_code" id="simba_two_factor_auth" autocomplete="off" data-lpignore="true"';
201			
202			if ($(form).hasClass('woocommerce-form-login')) {
203				// Retain compatibility with previous full-width layout
204				html += ' style="width: 100%;"';
205			}
206			
207			html += '></label>';
208			
209			html += '<p class="forgetmenot';
210			if (form_is_gravity_forms) html += ' gfield';
211			html += '" style="font-size:small;';
212			if (!$(form).hasClass('woocommerce-form-login')) {
213				// Retain compatibility with previous full-width layout
214				html += ' max-width: 60%;';
215			}
216			html += '">';
217			
218			// Would need further styling investigations to display this
219			if (!form_is_gravity_forms) {
220				html += '<span class="simba_tfa_otp_login_help">'+simba_tfasettings.otp_login_help+'</span>';
221			}
222			
223			if (user_can_trust) {
224			
225				html += '<input type="checkbox" name="simba_tfa_mark_as_trusted" id="simba_tfa_mark_as_trusted" value="1"><label for="simba_tfa_mark_as_trusted">'+ simba_tfasettings.mark_as_trusted+'</label>';
226				
227			}
228		}
229		
230		html += '</p>';
231		
232		var submit_button_text;
233		var submit_button_name;
234		
235		// Gravity forms doesn't like its button being disabled
236		if (!form_is_gravity_forms) {
237		
238			if ('button' == $submit_button.prop('nodeName').toLowerCase()) {
239				submit_button_text = $submit_button.text().trim();
240				submit_button_name = $submit_button.attr('name');
241			} else {
242				submit_button_text = $submit_button.val();
243				submit_button_name = $submit_button.attr('name');
244			}
245			
246			html += '<p class="submit"><input id="tfa_login_btn" class="button button-primary button-large" type="submit" ';
247			if ('undefined' !== typeof submit_button_name && '' != submit_button_name) { html += 'name="'+submit_button_name+'" '; }
248			html += 'value="' + submit_button_text + '"></p>';
249			
250			$submit_button.prop('disabled', true).hide();
251		
252		}
253		
254		if (form_retain_existing_elements && form_is_gravity_forms) {
255			// $submit_button.parents('form').first().append(html);
256			//$('<div style="clear:both;">
256'+html+'</div>').insertBefore($submit_button);
257			$(form).find('#gform_fields_login').append(html);
258		} else {
259			$submit_button.parents('form').first().prepend(html);
260		}
261
262		$('#login_error').hide();
263			
264		if (user_already_trusted) {
265			if (form_retain_existing_elements) {
266				$submit_button.trigger('click');
267			} else {
268				$('#tfa_login_btn').trigger('click');
269			}
270		} else {
271
272			$('#simba_two_factor_auth').trigger('focus');
273
274			// Hide extra boxes of third party plugins
275			jQuery('.hide-when-displaying-tfa-input').hide();
276		}
277
278	}
279	
280	/**
281	 * This function gets attached to a form submission handler and decides whether to add an OTP field or not.
282	 *
283	 * @param Object e - submission event
284	 *
285	 * @return Boolean - whether to proceed with the submission or not
286	 */
287	var form_submit_handler = function(e) {
288		
289		console.log('Simba TFA: form submit request');
290
291		var form = e.target;
292		
293		var form_is_gravity_forms = ('object' == typeof window['gform_gravityforms'] && 'undefined' !== typeof $(form).attr('id') && 'gform_' === $(form).attr('id').substring(0, 6));
294		
295		// Turn off everything
296		$(form).off();
297
298		if (0 == $(form).find('#simba_two_factor_auth').length && check_and_possibly_show_otp_field(form)) {
299			
300			if (form_is_gravity_forms) {
301				var form_id = $(form).attr('id').substring(6);
302				// Gravity Forms won't allow the form to submit if this is already true
303				window['gf_submitting_'+form_id] = false;
304			}
305			
306			e.preventDefault();
307			return false;
308			
309		}
310		
311		return true;
312		
313	};
314	
315	if (simba_tfasettings.login_form_off_selectors) {
316		$(simba_tfasettings.login_form_off_selectors).off('submit');
317	}
318	
319	$(simba_tfasettings.login_form_selectors).on('submit', form_submit_handler);
320	
321	$(simba_tfasettings.login_form_selectors).find(get_username_identifiers()).on('blur', function() {
322		var $form = $(this).parents('form').first();
323		check_and_possibly_show_otp_field($form, true);
324	});
325	
326});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.