PageSourceSearch

https://haar-accessoires.com/wp-content/plugins/wp-2fa/includes/cl…/passkeys/assets/js/user-login.js?ver=3.1.1

js haar-accessoires.com collected 2026-10-07 04:32:18 UTC 6,976 bytes, 256 lines download raw bytes

1import { browserSupportsWebAuthn, browserSupportsWebAuthnAutofill, startAuthentication } from "./index.js";
2
3/**
4 * Authenticate Passkey.
5 */
6async function authenticate( username, redirectTo ) {
7	let asseResp;
8	let requestId;
9	try {
10		const response = await wp.apiFetch({
11			path: '/wp-2fa-passkeys/v1/singin/request',
12			method: 'POST',
13			data: { 'user': username },
14		});
15
16		const { options, request_id } = response;
17
18		requestId = request_id;
19		asseResp = await startAuthentication(options);
20	} catch (error) {
21		throw error;
22	}
23
24	// POST the response to the endpoint that calls.
25	try {
26		const response = await wp.apiFetch({
27			path: '/wp-2fa-passkeys/v1/singin/response',
28			method: 'POST',
29			data: {
30				request_id: requestId,
31				asseResp,
32				'user': username,
33				'redirect_to': redirectTo,
34			},
35		});
36
37		if (response.status !== 'verified') {
38			throw new Error('Passkey authentication failed. Method is not set?');
39		}
40
41		let iframe = !(window === window.parent); // interim login ?
42
43		if (iframe) {
44			var someIframe = window.parent.document.getElementById('wp-auth-check-wrap');
45			someIframe.parentNode.removeChild(someIframe);
46		} else {
47
48			let redirect_to = '';
49
50			if (response.redirect_to && '' !== response.redirect_to) {
51				redirect_to = response.redirect_to;
52			} else {
53				// Get redirect_to from query string.
54				const urlParams = new URLSearchParams(window.location.search);
55				redirect_to = urlParams.get('redirect_to') || '/wp-admin';
56			}
57
58			// Redirect to redirect url or wp-admin as default.
59			window.location.href = redirect_to;
60		}
61	} catch (error) {
62		throw error;
63	}
64}
65
66/**
67 * Show error message.
68 *
69 * @param {string} message Error message.
70 */
71function showError(message) {
72	let loginForm = document.getElementById('loginform');
73
74	if ( !loginForm ) {
75		loginForm = document.getElementsByClassName('woocommerce-form woocommerce-form-login login')[0];
76	}
77
78	if ( !loginForm ) {
79		return;
80	}
81
82	// Create Error element if not exists.
83	const errorElement = document.createElement('div');
84	errorElement.id = 'login_error';
85	errorElement.className = 'notice notice-error';
86	errorElement.innerHTML = message;
87
88	// Add error element before login form.
89	loginForm.parentNode.insertBefore(errorElement, loginForm);
90
91	loginForm.classList.add('shake');
92}
93
94async function delay(time) {
95	return new Promise(resolve => setTimeout(resolve, time));
96}
97
98function onClick() {
99
100	// create invisible dummy input to receive the focus first
101	const fakeInput = document.createElement('input')
102	fakeInput.setAttribute('type', 'text')
103	fakeInput.style.position = 'absolute'
104	fakeInput.style.opacity = 0
105	fakeInput.style.height = 0
106	fakeInput.style.fontSize = '16px' // disable auto zoom
107
108	// you may need to append to another element depending on the browser's auto 
109	// zoom/scroll behavior
110	document.body.prepend(fakeInput)
111
112	// focus so that subsequent async focus will work
113	fakeInput.focus()
114
115	setTimeout(() => {
116
117		// now we can focus on the target input
118		document.getElementById('user_login').focus()
119
120		// cleanup
121		fakeInput.remove()
122
123	}, 1000)
124
125}
126
127wp.domReady(async () => {
128	// If the browser doesn't support WebAuthn, don't do anything.
129	if (!browserSupportsWebAuthn()) {
130		return;
131	}
132
133	// var $user_password = jQuery( '.user-pass-wrap' );
134	// $user_password.hide();
135
136	let usernameField = document.getElementById('user_login');
137
138	if ( ! usernameField ) {
139		usernameField = document.getElementById('username');
140	}
141
142	if ( !usernameField ) {
143		return;
144	}
145
146	// add autocomplete="webauthn" to the username field.
147	if (usernameField) {
148		usernameField.setAttribute('autocomplete', 'username webauthn');
149	}
150
151	if (browserSupportsWebAuthnAutofill()) {
152
153		const usePasskeysButton = document.querySelector('.wp-2fa-login-via-passkey');
154		const useStandardButton = document.querySelector('.wp-2fa-login-standard');
155
156		// Helper to detect if the password field is currently visible
157		const isPasswordVisible = () => {
158			let $user_password = jQuery('.user-pass-wrap');
159			if (!$user_password.length) {
160				$user_password = jQuery(jQuery('.woocommerce-form-row.woocommerce-form-row--wide.form-row.form-row-wide')[1]);
161			}
162			return $user_password.length ? $user_password.is(':visible') : false;
163		};
164
165		if ( usePasskeysButton ) {
166			usePasskeysButton.addEventListener('click', async () => {
167
168				if ( useStandardButton ) {
169					const standardLoginWrap = jQuery( '#wp-2fa-standard-login-wrapper' );
170					standardLoginWrap.show();
171				}
172
173				let $user_password = jQuery( '.user-pass-wrap' );
174
175				if ( ! $user_password.length ) {
176					$user_password = jQuery(jQuery( '.woocommerce-form-row.woocommerce-form-row--wide.form-row.form-row-wide')[1]);
177				}
178				if ($user_password.is(":visible")) {
179					$user_password.hide();
180
181					jQuery( 'p.forgetmenot' ).hide();
182					jQuery( 'p.submit' ).hide();
183
184					jQuery( 'button[name="login"]' ).parent().hide();
185
186					return;
187				}
188
189				jQuery( '#user_login' ).prop( 'required', false );
190				jQuery( '#user_pass' ).prop( 'required', false );
191
192				if ('' === usernameField.value) {
193					showError('Please enter your username or email address to use Passkey login.');
194
195					return;
196				}
197
198				// Collect redirect input value with fallbacks: redirect_to -> redirect -> 'wp-admin/'
199				let redirectTo = '';
200				const redirectInput = document.querySelector('input[name="redirect_to"]') || document.querySelector('input[name="redirect"]');
201				if (redirectInput && redirectInput.value && redirectInput.value.trim() !== '') {
202					redirectTo = redirectInput.value;
203				} else {
204					redirectTo = '';
205				}
206
207				try {
208					await authenticate( usernameField.value, redirectTo );
209				} catch (error) {
210					showError(error.message);
211				}
212			});
213		}
214		if ( useStandardButton ) {
215			useStandardButton.addEventListener('click', async () => {
216
217				var $user_password = jQuery( '.user-pass-wrap' );
218
219				if ( ! $user_password.length ) {
220					$user_password = jQuery(jQuery( '.woocommerce-form-row.woocommerce-form-row--wide.form-row.form-row-wide')[1]);
221				}
222
223				$user_password.show();
224
225				jQuery( '#user_login' ).prop( 'required', true );
226				jQuery( '#user_pass' ).prop( 'required', true );
227
228				jQuery( 'p.forgetmenot' ).show();
229				jQuery( 'p.submit' ).show();
230
231				jQuery( 'button[name="login"]' ).parent().show();
232
233				const standardLoginWrap = jQuery( '#wp-2fa-standard-login-wrapper' );
234				standardLoginWrap.hide();
235			});
236		}
237
238		// Trigger Passkey authentication when pressing Enter on the username field
239		// if the password field is hidden (i.e., passkey flow is active).
240		if ( usePasskeysButton && usernameField ) {
241			usernameField.addEventListener('keydown', (e) => {
242				const isEnter = (e.key && e.key.toLowerCase() === 'enter') || e.keyCode === 13;
243				if (!isEnter) return;
244
245				if (!isPasswordVisible()) {
246					e.preventDefault();
247					usePasskeysButton.click();
248				}
249			});
250		}
251
252	} else {
253		const passkeyUseWrap = document.getElementById('wp-2fa-login-wrapper');
254		passkeyUseWrap.style.display = 'none';
255	}
256});

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.