PageSourceSearch

https://57hours.com/wp-content/plugins/fifty7hours-firebase-user/p…ty7hours-firebase-user-public.js?ver=1.1.27

js 57hours.com collected 2026-10-02 06:16:53 UTC 29,565 bytes, 891 lines download raw bytes

1(function( $ ) {
2	'use strict';
3
4	/**
5	 * All of the code for your public-facing JavaScript source
6	 * should reside in this file.
7	 *
8	 * Note: It has been assumed you will write jQuery code here, so the
9	 * $ function reference has been prepared for usage within the scope
10	 * of this function.
11	 *
12	 * This enables you to define handlers, for when the DOM is ready:
13	 *
14	 * $(function() {
15	 *
16	 * });
17	 *
18	 * When the window is loaded:
19	 *
20	 * $( window ).load(function() {
21	 *
22	 * });
23	 *
24	 * ...and/or other possibilities.
25	 *
26	 * Ideally, it is not considered best practise to attach more than a
27	 * single DOM-ready or window-load handler for a particular page.
28	 * Although scripts in the WordPress core, Plugins and Themes may be
29	 * practising this, we should strive to set a better example in our own work.
30	 */
31
32	// Shared OTP state (current email, resend-cooldown timer).
33	var f7hOtpState = { email: '', resendInterval: null };
34
35	// True while a sign-in request is in flight. The login modal reads this via
36	// F7HIsAuthInProgress() and refuses to close, so a request the server is
37	// already processing can't be abandoned half-way.
38	var f7hAuthInProgress = false;
39	var f7hAuthLockTimeout = null;
40
41	/**
42	 * Disable / enable all login controls (social + OTP) together while a
43	 * request is in flight, so a user can't fire two sign-in attempts at once.
44	 */
45	function f7hDisableAuthControls() {
46		f7hAuthInProgress = true;
47
48		// Safety valve: never leave the modal stuck shut if a future code path
49		// forgets to re-enable. Far longer than any real sign-in round trip.
50		clearTimeout(f7hAuthLockTimeout);
51		f7hAuthLockTimeout = setTimeout(f7hEnableAuthControls, 60000);
52
53		$('.f-login-modal-fancybox .fancybox-close-small').css('pointer-events', 'none');
54		$('#f7h_wc_myaccount_login_btn').css('pointer-events', 'none');
55		$('#f7h_firebase_google_login').css('pointer-events', 'none');
56		$('#appleid-signin').css('pointer-events', 'none');
57		$('.js-otp-email-input').css('pointer-events', 'none');
58		$('.js-otp-request-code-btn').css('pointer-events', 'none');
59		$('.js-otp-verify-code-btn').css('pointer-events', 'none');
60		$('#f7h-wc-form-register-link').css('pointer-events', 'none');
61	}
62
63	function f7hEnableAuthControls() {
64		f7hAuthInProgress = false;
65		clearTimeout(f7hAuthLockTimeout);
66		f7hAuthLockTimeout = null;
67
68		$('.f-login-modal-fancybox .fancybox-close-small').css('pointer-events', 'auto');
69		$('#f7h_wc_myaccount_login_btn').css('pointer-events', 'auto');
70		$('#f7h_firebase_google_login').css('pointer-events', 'auto');
71		$('#appleid-signin').css('pointer-events', 'auto');
72		$('.js-otp-email-input').css('pointer-events', 'auto');
73		$('.js-otp-request-code-btn').css('pointer-events', 'auto');
74		$('.js-otp-verify-code-btn').css('pointer-events', 'auto');
75		$('#f7h-wc-form-register-link').css('pointer-events', 'auto');
76	}
77
78	// Read by the login modal's fancybox beforeClose guard in the theme.
79	window.F7HIsAuthInProgress = function() {
80		return f7hAuthInProgress;
81	};
82
83	function f7hShowAuthError(message) {
84		$('.js-social-login-error').text(message).fadeIn(350);
85	}
86
87	function f7hClearAuthError() {
88		$('.js-social-login-error').hide().text('');
89	}
90
91	function f7hGetAuthErrorMessage(error) {
92		if (error && error.code === 'auth/account-exists-with-different-credential') {
93			return 'You have already signed up with a different auth provider for that email.';
94		}
95
96		if (error && (error.code === 'auth/popup-closed-by-user' || error.code === 'auth/cancelled-popup-request')) {
97			return 'Sign in was cancelled.';
98		}
99
100		return error && error.message ? error.message : 'Something went wrong. Please try again.';
101	}
102
103	/**
104	 * Shared post-Firebase-auth handoff for Google, Apple, and Email OTP.
105	 * Gets a fresh, verifiable Firebase ID token and posts it to the WP
106	 * verified-login callback, which verifies it server-side before creating
107	 * any WP session - the client never asserts its own identity.
108	 */
109	function f7hCompleteVerifiedLogin(user, provider, redirectPath, onError, showError) {
110		function handleError(errorData) {
111			if (typeof onError === 'function') onError();
112
113			if (typeof showError === 'function') {
114				showError(errorData);
115				return;
116			}
117
118			f7hShowAuthError(errorData && errorData.message ? errorData.message : 'Something went wrong. Please try again.');
119		}
120
121		return user.getIdToken(true).then(function(idToken) {
122				return $.post(f7h_fb_social_login.ajax_url, {
123					action: 'fifty7hours_firebase_verified_login',
124					idToken: idToken,
125					provider: provider,
126					redirect: redirectPath,
127					nonce: f7h_register_user_ajax_obj.nonce
128				});
129		}).then(function(response) {
130			if (true === response.success) {
131				if (response.data.status === 'register' && typeof f7hTracking !== 'undefined' && f7hTracking.trackFbLead) {
132					// send event to Facebook
133					f7hTracking.trackFbLead(user.email);
134				}
135
136				window.dataLayer = window.dataLayer || [];
137				window.dataLayer.push({
138					'event': response.data.status === 'register' ? 'User Sign Up' : 'User Log In',
139					'email': user.email,
140					'signup_method': provider === 'google' ? 'Google' : (provider === 'apple' ? 'Apple' : 'Email OTP')
141				});
142
143				window.location.href = response.data.redirect;
144				} else {
145					handleError(response.data);
146				}
147			}).catch(function(error) {
148				handleError({ message: error && error.message ? error.message : 'Something went wrong. Please try again.' });
149			});
150	}
151
152	/**
153	 * Google/Apple: trade the provider sign-in for the 57hours account's custom token,
154	 * then hand off to the shared verified login like Email OTP does.
155	 */
156	function f7hCompleteSocialLogin(socialUser, provider, redirectPath, onError) {
157		return socialUser.getIdToken(true).then(function(idToken) {
158			return $.post(f7h_fb_social_login.ajax_url, {
159				action: 'fifty7hours_social_verify',
160				idToken: idToken,
161				nonce: f7h_register_user_ajax_obj.nonce
162			});
163		}).then(function(response) {
164			if (true !== response.success) {
165				throw response.data || {};
166			}
167
168			return firebase.auth().signInWithCustomToken(response.data.token);
169		}).then(function(result) {
170			return f7hCompleteVerifiedLogin(result.user, provider, redirectPath, onError);
171		}).catch(function(error) {
172			if (typeof onError === 'function') onError();
173
174			f7hShowAuthError(error && error.message ? error.message : 'Something went wrong. Please try again.');
175		});
176	}
177
178	/**
179	 * Where to send the visitor after signing in - shared by Email OTP, Google and Apple,
180	 * so all three land in the same place.
181	 *
182	 * The page they are on, query string and all, read at sign-in time rather than from a
183	 * `data-redirect` rendered into the page. A rendered one is wrong more often than it
184	 * looks: the page may be served from cache, and any param picked up since it loaded -
185	 * a chosen date, a coupon, a campaign tag - would be dropped on the way back.
186	 *
187	 * An explicit `data-redirect` still wins, for the forms that deliberately send the
188	 * visitor somewhere other than where they are.
189	 *
190	 * Read with `.attr()` rather than `.data()` on purpose: jQuery caches a `.data()` read
191	 * and stops consulting the attribute afterwards, so a later `setAttribute` elsewhere
192	 * would be silently ignored.
193	 */
194	function f7hGetLoginRedirectPath($trigger) {
195		$trigger = ($trigger && $trigger.length) ? $trigger.first() : $();
196
197		var redirectPath = $trigger.attr('data-redirect') || (window.location.pathname + window.location.search);
198		var triggerEvent = $trigger.data('event') || $('#f-login-modal').data('event') || '';
199
200		if (triggerEvent) {
201			redirectPath += (redirectPath.indexOf('?') > -1 ? '&' : '?') + 'event=' + encodeURIComponent(triggerEvent);
202		}
203
204		return redirectPath;
205	}
206
207	/** Email OTP step/state helpers **/
208	function f7hOtpResolveForm($form) {
209		if ($form && $form.length) {
210			return $form.first();
211		}
212
213		var $visibleForm = $('.js-email-otp-form:visible').first();
214
215		return $visibleForm.length ? $visibleForm : $('.js-email-otp-form').first();
216	}
217
218	function f7hOtpEachForm($form, callback) {
219		if ($form && $form.length) {
220			callback($form.first());
221			return;
222		}
223
224		$('.js-email-otp-form').each(function() {
225			callback($(this));
226		});
227	}
228
229	function f7hOtpGetContext($form) {
230		$form = f7hOtpResolveForm($form);
231
232		var $context = $form.closest('#f-login-modal, .f-myaccount-unauthenticated, .site-content');
233
234		return $context.length ? $context.first() : $form;
235	}
236
237	function f7hOtpUpdateRequestButtonState($form) {
238		f7hOtpEachForm($form, function($currentForm) {
239			var email = $.trim($currentForm.find('.js-otp-email-input').val());
240			$currentForm.find('.js-otp-request-code-btn').prop('disabled', email === '');
241		});
242	}
243
244	function f7hOtpUpdateVerifyButtonState($form) {
245		f7hOtpEachForm($form, function($currentForm) {
246			var code = '';
247
248			$currentForm.find('.f-otp-code-input').each(function() {
249				code += $(this).val();
250			});
251
252			$currentForm.find('.js-otp-verify-code-btn').prop('disabled', code === '');
253		});
254	}
255
256	function f7hOtpGetTitleElement() {
257		return $('#f-login-modal .js-f-login-modal-title, #f-login-modal .title').first();
258	}
259
260	function f7hOtpGetDefaultTitle() {
261		var $title = f7hOtpGetTitleElement();
262
263		return $title.data('default-title') || 'Sign in to 57hours';
264	}
265
266	function f7hOtpGetDefaultReason() {
267		var $reason = $('.js-f-login-modal-reason').first();
268
269		return $reason.data('default-reason') || 'Enter your email to continue. No passwords needed.';
270	}
271
272	window.F7HSetLoginModalCopy = function(copy) {
273		copy = copy || {};
274
275		if (copy.title) {
276			f7hOtpGetTitleElement().text(copy.title);
277			f7hOtpState.emailStepTitle = copy.title;
278		}
279
280		if (typeof copy.reason !== 'undefined') {
281			$('.js-f-login-modal-reason').html(copy.reason);
282		}
283
284		if (typeof copy.otpContinueText !== 'undefined') {
285			$('#f-login-modal').data('otp-continue-text', copy.otpContinueText);
286		}
287	};
288
289	function f7hOtpShowEmailStep($form) {
290		$form = f7hOtpResolveForm($form);
291		var $context = f7hOtpGetContext($form);
292
293		f7hOtpStopResendCooldown();
294		$context.find('.js-otp-step-code').hide();
295		$context.find('.js-otp-step-email').show();
296		$context.find('.js-f-login-modal-reason').show();
297		$form.find('.js-otp-code-errors, .js-otp-email-errors').hide().html('');
298		f7hOtpClearCode($form);
299		f7hOtpUpdateRequestButtonState($form);
300
301		var $title = f7hOtpGetTitleElement();
302		if ($title.length && f7hOtpState.emailStepTitle) {
303			$title.text(f7hOtpState.emailStepTitle);
304		}
305	}
306
307	function f7hOtpShowCodeStep($form, email) {
308		$form = f7hOtpResolveForm($form);
309		var $context = f7hOtpGetContext($form);
310		var $title = f7hOtpGetTitleElement();
311
312		if ($title.length) {
313			f7hOtpState.emailStepTitle = $title.text();
314			$title.text('Check your inbox');
315		}
316
317		var continueText = $('#f-login-modal').data('otp-continue-text') || 'to continue.';
318		var changeEmail = String($form.data('lock-email')) === '1' ? '' :
319			' <button type="button" class="f-btn f-btn--tertiary js-otp-use-different-email">Use a different email</button>.';
320
321		$form.find('.js-otp-code-email-display').html(
322			'We sent a 6-digit code to <strong>' + $('<div>').text(email).html() + '</strong>. ' +
323			'Enter it below ' + continueText + changeEmail
324		);
325		$context.find('.js-otp-step-email').hide();
326		$form.find('.js-otp-step-code').show();
327		$context.find('.js-f-login-modal-reason').hide();
328		f7hOtpUpdateVerifyButtonState($form);
329		$form.find('.f-otp-code-input[data-otp-index="0"]').focus();
330	}
331
332	function f7hOtpClearCode($form, keepErrorState) {
333		$form = f7hOtpResolveForm($form);
334		$form.find('.f-otp-code-input').val('');
335
336		if (!keepErrorState) {
337			$form.find('.js-otp-code-inputs').removeClass('is-error');
338		}
339
340		f7hOtpUpdateVerifyButtonState($form);
341	}
342
343	function f7hOtpGetCode($form) {
344		$form = f7hOtpResolveForm($form);
345		var code = '';
346		$form.find('.f-otp-code-input').each(function(){ code += $(this).val(); });
347		return code;
348	}
349
350	function f7hOtpShowEmailError($form, errorData) {
351		$form = f7hOtpResolveForm($form);
352		var message = (errorData && errorData.message) ? errorData.message : 'Something went wrong. Please try again.';
353		$form.find('.js-otp-email-errors').text(message).show();
354	}
355
356	function f7hOtpShowCodeError($form, errorData) {
357		$form = f7hOtpResolveForm($form);
358		var message = (errorData && errorData.message) ? errorData.message : 'Invalid or expired code.';
359		$form.find('.js-otp-code-inputs').addClass('is-error');
360		$form.find('.js-otp-code-errors').text(message).show();
361	}
362
363	function f7hOtpStartResendCooldown($form) {
364		$form = f7hOtpResolveForm($form);
365		var seconds = 30;
366		var $btn = $form.find('.js-otp-resend-btn');
367
368		f7hOtpStopResendCooldown();
369		f7hOtpState.resendButton = $btn;
370
371		$btn.data('original-text', $btn.data('original-text') || $btn.text());
372		$btn.prop('disabled', true).text('Resend (' + seconds + 's)');
373
374		f7hOtpState.resendInterval = setInterval(function() {
375			seconds--;
376
377			if (seconds <= 0) {
378				f7hOtpStopResendCooldown();
379				return;
380			}
381
382			$btn.text('Resend (' + seconds + 's)');
383		}, 1000);
384	}
385
386	function f7hOtpStopResendCooldown() {
387		var $btn = f7hOtpState.resendButton && f7hOtpState.resendButton.length
388			? f7hOtpState.resendButton
389			: $('.js-otp-resend-btn');
390
391		if (f7hOtpState.resendInterval) {
392			clearInterval(f7hOtpState.resendInterval);
393			f7hOtpState.resendInterval = null;
394		}
395
396		$btn.prop('disabled', false).text($btn.data('original-text') || 'Resend');
397		f7hOtpState.resendButton = null;
398	}
399
400	// Reset the OTP form to its initial state - called whenever the login
401	// modal is (re)opened, so a stale code screen never reappears.
402	window.F7HResetLoginModal = function() {
403		var $form = f7hOtpResolveForm($('#f-login-modal .js-email-otp-form'));
404
405		f7hOtpState.emailStepTitle = '';
406		f7hOtpShowEmailStep($form);
407		f7hOtpGetTitleElement().text(f7hOtpGetDefaultTitle());
408		$('.js-f-login-modal-reason').html(f7hOtpGetDefaultReason());
409		$form.find('.js-otp-email-input').val('');
410		$form.removeData('otp-email');
411		$('#f-login-modal').removeData('otp-continue-text');
412		// Cleared here rather than by each opener, so a trigger's `event=` can't follow
413		// the visitor into the next sign-in the modal is reused for.
414		$('#f-login-modal').removeData('event');
415		$('#f-login-modal').find('form').removeData('event');
416		f7hOtpUpdateRequestButtonState($form);
417	};
418
419	$(function(){
420		// toggle password
421		$(document).on("click",".js-toggle-password", function() {
422			$(this).toggleClass('password-is-visible');
423			if ($(this).hasClass('password-is-visible')) {
424				$(this).parent().find('input').prop("type", "text");
425			} else {
426				$(this).parent().find('input').prop("type", "password");
427			}
428		});
429
430			/** Email OTP login/signup **/
431			f7hOtpUpdateRequestButtonState();
432
433			$(document).on('input', '.js-otp-email-input', function() {
434				f7hOtpUpdateRequestButtonState($(this).closest('.js-email-otp-form'));
435			});
436
437			$(document).on('click', '.js-otp-request-code-btn', function(e) {
438				e.preventDefault();
439
440				var $btn = $(this);
441				var $form = $btn.closest('.js-email-otp-form');
442				var email = $.trim($form.find('.js-otp-email-input').val());
443
444				$form.find('.js-otp-email-errors').hide().html('');
445
446				if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
447					f7hOtpShowEmailError($form, { message: 'Please enter a valid email address.' });
448					return;
449				}
450
451			// Honeypot - if a bot filled this hidden field, silently no-op.
452			if ($form.find('input[name="user_consent"]').is(':checked')) return;
453
454			$btn.addClass('is-loading');
455			f7hDisableAuthControls();
456
457				$.post(f7h_register_user_ajax_obj.ajax_url, {
458					action: 'fifty7hours_email_otp_request_code',
459					email: email,
460					nonce: f7h_register_user_ajax_obj.nonce
461				}, function(response) {
462					$btn.removeClass('is-loading');
463					f7hEnableAuthControls();
464
465					if (true === response.success) {
466						f7hOtpState.email = email;
467						$form.data('otp-email', email);
468						f7hOtpShowCodeStep($form, email);
469						f7hOtpStartResendCooldown($form);
470					} else {
471						f7hOtpShowEmailError($form, response.data);
472					}
473				}).fail(function() {
474					$btn.removeClass('is-loading');
475					f7hEnableAuthControls();
476					f7hOtpShowEmailError($form, { message: 'Something went wrong. Please try again.' });
477				});
478			});
479
480		$(document).on('click', '.js-otp-resend-btn', function(e) {
481			e.preventDefault();
482
483			var $btn = $(this);
484			var $form = $btn.closest('.js-email-otp-form');
485			var email = $form.data('otp-email') || f7hOtpState.email;
486
487			if ($btn.prop('disabled')) return;
488
489			$btn.prop('disabled', true).addClass('is-loading');
490
491				$.post(f7h_register_user_ajax_obj.ajax_url, {
492					action: 'fifty7hours_email_otp_request_code',
493					email: email,
494					nonce: f7h_register_user_ajax_obj.nonce
495				}, function(response) {
496					$btn.removeClass('is-loading');
497
498					if (true === response.success) {
499						$form.find('.js-otp-code-errors').hide().html('');
500						f7hOtpStartResendCooldown($form);
501					} else {
502						f7hOtpShowCodeError($form, response.data);
503
504						if (response.data && response.data.code === 'OtpTooManyRequests') {
505							f7hOtpStartResendCooldown($form);
506						} else {
507							$btn.prop('disabled', false);
508						}
509					}
510				}).fail(function() {
511					$btn.removeClass('is-loading').prop('disabled', false);
512					f7hOtpShowCodeError($form, { message: 'Something went wrong. Please try again.' });
513				});
514			});
515
516		$(document).on('click', '.js-otp-use-different-email', function(e) {
517			e.preventDefault();
518			f7hOtpShowEmailStep($(this).closest('.js-email-otp-form'));
519		});
520
521		// 6-digit code inputs - auto-advance / backspace-to-previous / paste support
522			$(document).on('input', '.f-otp-code-input', function() {
523				var $this = $(this);
524				var $form = $this.closest('.js-email-otp-form');
525
526				$this.val($this.val().replace(/[^0-9]/g, '').slice(0, 1));
527				$this.closest('.js-otp-code-inputs').removeClass('is-error');
528				$form.find('.js-otp-code-errors').hide().html('');
529
530				if ($this.val().length === 1) {
531					var nextIndex = parseInt($this.data('otp-index'), 10) + 1;
532				var $next = $this.closest('.js-otp-code-inputs').find('.f-otp-code-input[data-otp-index="' + nextIndex + '"]');
533				if ($next.length) $next.focus();
534				}
535
536				f7hOtpUpdateVerifyButtonState($form);
537			});
538
539		$(document).on('keydown', '.f-otp-code-input', function(e) {
540			var $this = $(this);
541
542			if (e.key === 'Backspace' && $this.val() === '') {
543				var prevIndex = parseInt($this.data('otp-index'), 10) - 1;
544				var $prev = $this.closest('.js-otp-code-inputs').find('.f-otp-code-input[data-otp-index="' + prevIndex + '"]');
545				if ($prev.length) $prev.focus();
546			}
547		});
548
549			$(document).on('paste', '.f-otp-code-input', function(e) {
550				var $form = $(this).closest('.js-email-otp-form');
551				var clipboardData = (e.originalEvent || e).clipboardData || window.clipboardData;
552				var pasted = clipboardData ? clipboardData.getData('text').replace(/[^0-9]/g, '').slice(0, 6) : '';
553
554			if (pasted.length > 1) {
555				e.preventDefault();
556
557					var $inputs = $(this).closest('.js-otp-code-inputs').find('.f-otp-code-input');
558					$inputs.closest('.js-otp-code-inputs').removeClass('is-error');
559					$form.find('.js-otp-code-errors').hide().html('');
560					pasted.split('').forEach(function(digit, i) { $inputs.eq(i).val(digit); });
561					$inputs.eq(Math.min(pasted.length, 6) - 1).focus();
562					f7hOtpUpdateVerifyButtonState($form);
563				}
564			});
565
566		$(document).on('click', '.js-otp-verify-code-btn', function(e) {
567			e.preventDefault();
568
569			var $btn = $(this);
570			var $form = $btn.closest('.js-email-otp-form');
571			var email = $form.data('otp-email') || f7hOtpState.email;
572			var code = f7hOtpGetCode($form);
573
574			if ($btn.prop('disabled')) return;
575
576			$form.find('.js-otp-code-errors').hide().html('');
577
578			if (code.length !== 6) {
579				f7hOtpShowCodeError($form, { message: 'Please enter the 6-digit code.' });
580				return;
581			}
582
583			$btn.addClass('is-loading');
584			f7hDisableAuthControls();
585
586				$.post(f7h_register_user_ajax_obj.ajax_url, {
587					action: 'fifty7hours_email_otp_verify_code',
588					email: email,
589					code: code,
590					nonce: f7h_register_user_ajax_obj.nonce
591				}, function(response) {
592					if (true !== response.success) {
593						$btn.removeClass('is-loading');
594						f7hEnableAuthControls();
595						f7hOtpShowCodeError($form, response.data);
596						f7hOtpClearCode($form, true);
597						$form.find('.f-otp-code-input[data-otp-index="0"]').focus();
598						return;
599					}
600
601					var customToken = response.data.token;
602
603					firebase.auth().signInWithCustomToken(customToken).then(function(result) {
604						var redirectPath = f7hGetLoginRedirectPath(f7hOtpResolveForm($form));
605
606						return f7hCompleteVerifiedLogin(result.user, 'email_otp', redirectPath, function() {
607							$btn.removeClass('is-loading');
608							f7hEnableAuthControls();
609						}, function(errorData) {
610							f7hOtpShowCodeError($form, errorData);
611						});
612					}).catch(function(error) {
613						$btn.removeClass('is-loading');
614						f7hEnableAuthControls();
615						f7hOtpShowCodeError($form, { message: error.message });
616					});
617				}).fail(function() {
618					$btn.removeClass('is-loading');
619					f7hEnableAuthControls();
620					f7hOtpShowCodeError($form, { message: 'Something went wrong. Please try again.' });
621				});
622			});
623
624			$('.js-email-otp-form[data-auto-request="1"]').each(function() {
625				var $form = $(this);
626				var email = $.trim($form.find('.js-otp-email-input').val());
627
628				if (!email || $form.data('auto-requested')) return;
629
630				$form.data('auto-requested', true);
631				$form.find('.js-otp-request-code-btn').trigger('click');
632			});
633
634		// Firebase Google login
635		function firebaseGoogleLoginInit() {
636			var firebaseConfig = {
637				apiKey: f7h_fb_social_login.fbSocialAuth.apiKey,
638				authDomain: f7h_fb_social_login.fbSocialAuth.authDomain,
639				databaseURL: f7h_fb_social_login.fbSocialAuth.databaseURL,
640				projectId: f7h_fb_social_login.fbSocialAuth.projectId,
641				storageBucket: f7h_fb_social_login.fbSocialAuth.storageBucket,
642			};
643			firebase.initializeApp(firebaseConfig);
644		}
645
646		/**/
647		firebaseGoogleLoginInit();
648
649			var f7hActiveAppleLoginButton = null;
650
651			function toggleSignIn() {
652			var loginBtn = this.id;
653			var button = $(this);
654			var buttonTextEl = button.find('.f7h-social-login-text');
655			var buttonText = button.data('text') || $.trim(buttonTextEl.text()) || 'Continue with Google';
656			var provider = null;
657
658			f7hClearAuthError();
659			f7hDisableAuthControls();
660			button.addClass('is-loading');
661
662			if (loginBtn == 'f7h_firebase_google_login') {
663				provider = new firebase.auth.GoogleAuthProvider();
664				buttonTextEl.html('<span class="f7h-myaccount-btn-loading-spinner white-btn-spinner"></span>');
665			}
666
667			if (!provider) {
668				button.removeClass('is-loading');
669				f7hEnableAuthControls();
670				f7hShowAuthError('Something went wrong. Please try again.');
671				return;
672			}
673
674			var redirectPath = f7hGetLoginRedirectPath($(this));
675
676			provider.addScope('email');
677
678		    firebase.auth().signInWithPopup(provider).then(function(result) {
679		      // The signed-in user info.
680		      var user = result.user;
681
682		      f7hCompleteSocialLogin(user, 'google', redirectPath, function() {
683					button.removeClass('is-loading');
684					f7hEnableAuthControls();
685
686					if (loginBtn == 'f7h_firebase_google_login') {
687						buttonTextEl.html(buttonText);
688					}
689				});
690			    }).catch(function(error) {
691			  button.removeClass('is-loading');
692
693		      f7hShowAuthError(f7hGetAuthErrorMessage(error));
694
695		      f7hEnableAuthControls();
696
697			  if (loginBtn == 'f7h_firebase_google_login') {
698				buttonTextEl.html(buttonText);
699			  }
700		    });
701		}
702
703		$(document).on('click', '#f7h_firebase_google_login', toggleSignIn);
704
705		// Apple sign in init
706		async function f7hAppleSignInInit() {
707			var rawNonce = 'f7h-sign-in-Apple-id';
708			// Create SHA256 nonce
709			// encode as UTF-8
710			const nonceUint8Array = new TextEncoder('utf-8').encode(rawNonce);
711			// hash the message
712			const hashedNonce = await crypto.subtle.digest("SHA-256", nonceUint8Array);
713			// convert ArrayBuffer to Array
714			const hashedNonceArray = Array.from(new Uint8Array(hashedNonce));
715			// convert bytes to hex string
716			const hashNonceHexTxt = hashedNonceArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
717
718			// Init Apple sign in
719			AppleID.auth.init({
720				clientId : f7h_fb_social_login.appleIdIdentifier,
721				scope : 'name email',
722				redirectURI : f7h_fb_social_login.appleIdRedirectUrl,
723				nonce : hashNonceHexTxt,
724				usePopup : true
725			});
726		}
727
728		/**/
729		f7hAppleSignInInit();
730
731		$(document).on('click', '#appleid-signin', f7hDisableLoginButtonsOnAppleLogin);
732
733		function f7hDisableLoginButtonsOnAppleLogin() {
734			f7hActiveAppleLoginButton = $(this);
735			f7hClearAuthError();
736			f7hDisableAuthControls();
737
738			f7hActiveAppleLoginButton.addClass('is-loading').next('.f-btn').addClass('is-loading');
739		}
740
741		function f7hEnableLoginButtonsOnAppleLogin() {
742			var appleButton = (f7hActiveAppleLoginButton && f7hActiveAppleLoginButton.length) ? f7hActiveAppleLoginButton : $('#appleid-signin');
743
744			f7hEnableAuthControls();
745
746			appleButton.removeClass('is-loading').next('.f-btn').removeClass('is-loading');
747		}
748
749		// Listen for Apple sign in authorization success
750			document.addEventListener('AppleIDSignInOnSuccess', (event) => {
751				var appleButton = (f7hActiveAppleLoginButton && f7hActiveAppleLoginButton.length) ? f7hActiveAppleLoginButton : $('#appleid-signin').first();
752				var redirectPath = f7hGetLoginRedirectPath(appleButton);
753
754				var eventData = event.detail;
755				var idToken = eventData && eventData.authorization ? eventData.authorization.id_token : '';
756
757				if (!idToken) {
758					f7hEnableLoginButtonsOnAppleLogin();
759					f7hShowAuthError('Something went wrong. Please try again.');
760					return;
761				}
762
763					var rawNonce = 'f7h-sign-in-Apple-id';
764
765			// Sing in user on Firebase
766			var provider = new firebase.auth.OAuthProvider('apple.com');
767			var credential = provider.credential({
768				idToken: idToken,
769				rawNonce: rawNonce
770			});
771
772					firebase.auth().signInWithCredential(credential).then(function(result){
773						var user = result.user;
774
775						f7hCompleteSocialLogin(user, 'apple', redirectPath, f7hEnableLoginButtonsOnAppleLogin);
776						}).catch(function(error){
777					f7hShowAuthError(f7hGetAuthErrorMessage(error));
778					f7hEnableLoginButtonsOnAppleLogin();
779				});
780			});
781
782		// Listen for Apple sign in authorization failures
783		document.addEventListener('AppleIDSignInOnFailure', (event) => {
784			// Handle error.
785			f7hEnableLoginButtonsOnAppleLogin();
786			var appleError = event.detail && event.detail.error ? event.detail.error : '';
787
788				if ( appleError === 'popup_closed_by_user' ) {
789					f7hShowAuthError("Sign in was cancelled.");
790				} else {
791					f7hShowAuthError('Something went wrong. Please try again.');
792				}
793			});
794
795		function f7hHandleUserVisitsCookie() {
796			var loggedIn = ($('body').hasClass('logged-in')) ? true : false;
797			let userVisitsCount;
798			let cookieExpirationTime;
799			let lastSavedUserVisitedPath;
800
801			if ( ! loggedIn && !! f7h_register_user_ajax_obj.is_content_page ) {
802				let currentVisitPath = f7h_register_user_ajax_obj.current_users_visit_path;
803
804				let userVisitsCookie = Cookies.get('f7hUserVisits');
805
806				if ( userVisitsCookie !== undefined ) {
807					userVisitsCookie = JSON.parse(userVisitsCookie);
808
809					lastSavedUserVisitedPath = userVisitsCookie.last_user_visited_path;
810					userVisitsCount = userVisitsCookie.visit_count;
811					cookieExpirationTime = new Date(userVisitsCookie.expiration_time);
812
813					// check for a page refresh
814					if ( lastSavedUserVisitedPath !== currentVisitPath ) {
815						userVisitsCount++;
816					}
817				} else {
818					userVisitsCount = 1;
819
820					let dateExpires = new Date();
821					dateExpires.setDate(dateExpires.getDate() + 1);
822
823					cookieExpirationTime = dateExpires;
824				}
825
826				let newCookieValue = {
827					last_user_visited_path: currentVisitPath,
828					visit_count: userVisitsCount,
829					expiration_time: cookieExpirationTime
830				}
831
832				Cookies.set('f7hUserVisits', newCookieValue, { path: '/', expires: cookieExpirationTime });
833			}
834		}
835
836		f7hHandleUserVisitsCookie();
837
838		// Show login popup form if user has visited at least 3 content pages
839		if ( true === shouldShowLoginPopUpForm() ) {
840			window.F7HResetLoginModal();
841
842			$('.js-f-login-modal-reason').html("Hey there! Thank you for reading our content. You've reached your daily limit for non-users. Please sign in to continue enjoying more good reads.");
843
844			$.fancybox.open({
845				src: $('#f-login-modal'),
846				type: 'html',
847				baseClass: 'f-login-modal-fancybox',
848				toolbar: false,
849				smallBtn: false,
850				clickSlide: false,
851				clickOutside: false,
852				touch: false,
853				modal: true,
854				afterShow: function( instance ) {
855					var targetblock = document.querySelector('.fancybox-slide');
856					bodyScrollLock.disableBodyScroll(targetblock);
857				},
858				afterClose: function( instance, current ) {
859					bodyScrollLock.clearAllBodyScrollLocks();
860				},
861			});
862		}
863
864		function shouldShowLoginPopUpForm() {
865			var loggedIn = ($('body').hasClass('logged-in')) ? true : false;
866
867			if (loggedIn) return false;
868
869			let userVisitsCookie = Cookies.get('f7hUserVisits');
870
871			if ( userVisitsCookie !== undefined ) {
872				userVisitsCookie = JSON.parse(userVisitsCookie);
873
874				let userVisitsNum = userVisitsCookie.visit_count;
875
876				if ( userVisitsNum >= 3 && f7h_register_user_ajax_obj.is_content_page ) return true;
877			}
878
879			return false;
880		}
881
882		const isWebview = (userAgent) => {
883		  return /webview|wv|ip((?!.*Safari)|(?=.*like Safari))/i.test(userAgent);
884		};
885
886		if (isWebview(window.navigator.userAgent)) {
887			$('#f7h_firebase_google_login').hide();
888		}
889
890	});
891})( jQuery );

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.