const isDebugMode = window.location.search.includes('debug=true'); let debugLogContainer = null; let debugLogCounter = 0; const cookieDomain = '.' + getMainDomain(window.location.href); firebaseDebugLog(true, 'cookieDomain-' + cookieDomain); let refreshInterval; let logoutInProgress = false; let pendingCred = null; document.addEventListener('DOMContentLoaded', function () { // Create debug overlay if debug mode is enabled if (isDebugMode) { createDebugOverlay(); } //Safe to expose as they are identification values not auth keys const firebaseConfig = { apiKey: "AIzaSyA6qrL3tY40YlRkSK4XTS7zijAJ4n15MNU", authDomain: "sso.consequence.net", projectId: "consequence-25a8e", storageBucket: "consequence-25a8e.appspot.com", messagingSenderId: "993189234631", appId: "1:993189234631:web:4d0a240cc0ab799b65fbe2", measurementId: "G-V7CZFS1TQG" }; firebase.initializeApp(firebaseConfig); // Check for native Facebook OAuth callback first (Option 5) handleFacebookOAuthCallback().then(handled => { if (handled) { firebaseDebugLog(true, 'Facebook OAuth callback handled, skipping Firebase redirect check'); return; } // If not a Facebook OAuth callback, check for Firebase redirect result return firebase.auth().getRedirectResult(); }).then(async (result) => { if (!result) return; // Already handled by Facebook OAuth callback if (!result || !result.user) return; const user = result.user; const idToken = await user.getIdToken(); const response = await login(user, idToken); if (response && response.success) { window.location.reload(); } else { console.log("WP login failed after redirect"); } }) .catch((e) => { console.log("getRedirectResult error:", e.code, e.message, e); }); var googleLoginBtn = document.getElementById('googleLoginBtn'); var facebookLoginBtn = document.getElementById('facebook-login'); var twitterLoginBtn = document.getElementById('twitter-login'); var appleLoginBtn = document.getElementById('apple-login'); var logoutBtn = document.getElementById('logoutBtn'); if (googleLoginBtn) { googleLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.GoogleAuthProvider(); provider.setCustomParameters({ prompt: 'select_account' }); handleSignInWithProvider(provider, 'google'); }); } // Facebook Authentication if (facebookLoginBtn) { facebookLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.FacebookAuthProvider(); // provider.setCustomParameters({ // auth_type: 'reauthenticate' // }); handleSignInWithProvider(provider, 'facebook'); }); } // Twitter Authentication if (twitterLoginBtn) { twitterLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.TwitterAuthProvider(); provider.setCustomParameters({ 'force_login': 'true' // Forces the user to reauthenticate }); handleSignInWithProvider(provider, 'twitter'); }); } // Apple Authentication if (appleLoginBtn) { appleLoginBtn.addEventListener('click', function () { var provider = new firebase.auth.OAuthProvider('apple.com'); handleSignInWithProvider(provider, 'apple'); }); } if (logoutBtn) { logoutBtn.addEventListener('click', function () { logout(); }); } firebase.auth().onAuthStateChanged((user) => { firebaseDebugLog(true, '---Start onAuthStateChanged---'); if (logoutInProgress == true) return; // Don't logout if Facebook OAuth is in progress (Option 5 only) if (localStorage.getItem('fb_oauth_processing') === 'true') { firebaseDebugLog(true, 'Facebook OAuth in progress, skipping auth state check'); firebaseDebugLog(true, '---End onAuthStateChanged---'); return; } if (user) { syncGeoToLambda(user.email); firebaseDebugLog(true, 'User signed in:' + user); // regenerateIdToken(user); // Start the refresh process if (checkCookieExists()) { firebaseDebugLog(true, 'CookieExists'); startTokenRefresh(user); } else { firebaseDebugLog(true, 'No CookieExists'); firebaseDebugLog(true, 'No sessioncookie found, logout'); localStorage.setItem('localLogout', 2); //1=local, 2=auto logout(); } } else { firebaseDebugLog(true, 'No user signed in'); clearInterval(refreshInterval); // Clear the interval on sign-out firebaseDebugLog(true, 'On authstatechange check cookie'); // checkSessionCookie(); } firebaseDebugLog(true, '---End onAuthStateChanged---'); }); async function handleSignInWithProvider(provider, pname) { firebaseDebugLog(true, '---Start handleSignInWithProvider'); const loader = document.getElementById('loginSpinner'); try { localStorage.setItem('loggedInLocally', 'true'); logoutInProgress = true; // Option 5: Use native Facebook OAuth for mobile devices ONLY // This includes: mobile regular browsers AND mobile in-app browsers // Desktop in-app browsers will use standard popup flow // This bypasses Firebase's /__/auth/ handler which is blocked by nginx if (pname === 'facebook' && isMobileDevice()) { firebaseDebugLog(true, 'Using custom Facebook OAuth (Option 5) for mobile device'); await handleFacebookNativeAuth(); return; } if (isInAppBrowser()) { await firebase.auth().signInWithRedirect(provider); return; } const result = await firebase.auth().signInWithPopup(provider); loader.style.display = 'flex'; document.getElementById('socialLogin').style.display = 'none'; document.querySelector('.sfba-close').style.display = 'none'; const user = result.user; firebaseDebugLog(true, 'handleSignInWithProvider-' + user); const idToken = await user.getIdToken(); firebaseDebugLog(true, 'ID Token:-' + idToken); const response = await login(user, idToken); if (!response || !response.success) { // Handle unsuccessful login localStorage.removeItem('loggedInLocally'); document.getElementById('socialLogin').style.display = 'block'; document.querySelector('.sfba-close').style.display = 'block'; loader.style.display = 'none'; throw new Error('Failed to authenticate.'); } logoutInProgress = false; window.location.reload(); // Reload the page on successful login } catch (error) { logoutInProgress = false; firebaseDebugLog(true, 'Error during Firebase authentication:' + error.message); localStorage.removeItem('loggedInLocally'); // Ensure localStorage is cleaned up handleLoginError(error); } firebaseDebugLog(true, '---End handleSignInWithProvider'); } function login(user, idToken) { firebaseDebugLog(true, '---Start Login'); return new Promise((resolve, reject) => { jQuery.ajax({ url: firebaseAuthAjax.ajax_url, method: 'POST', data: { action: 'firebase_login', nonce: firebaseAuthAjax.nonce, email: user.email, display_name: user.displayName, provider_id: user.providerData[0].uid, provider_name: user.providerData[0].providerId, idToken: idToken, firebase_uid: user.uid }, success: function (response) { firebaseDebugLog(true, 'login success response:-' + response); setCookie('ssosession', idToken, 24, cookieDomain); syncGeoToLambda(user.email); resolve(response); firebaseDebugLog(true, '---End Login'); }, error: function (error) { firebaseDebugLog(true, 'Error logging in:-' + error); reject(error); } }); }); } async function handleLoginError(error) { if (error.code === 'auth/account-exists-with-different-credential') { jQuery('.temp-preferences').show(); jQuery('.temp-preferences .sfba-before-login').show(); jQuery(".socialLogin").hide(); var email = error.email; // Store credential in memory - cannot reliably serialize Firebase credentials to JSON pendingCred = error.credential; try { var methods = await firebase.auth().fetchSignInMethodsForEmail(email); if (methods.length > 0) { localStorage.setItem('existingProvider', methods[0]); jQuery(".sfba-mask").removeClass("sfba-active"); jQuery(".sfba-link-mask").addClass('sfba-active'); handleLinkModel(methods[0]); } } catch (fetchError) { firebaseDebugLog(true, 'Error fetching sign-in methods: ' + fetchError.message); } } else if (error.code === 'auth/popup-blocked' || error.code === 'auth/popup-closed-by-user') { firebaseDebugLog(true, 'Popup blocked or closed by user'); // Note: Cannot redirect here as we don't have provider context } else { firebaseDebugLog(true, error.message); jQuery('.temp-preferences').hide(); jQuery('.temp-preferences .sfba-before-login').hide(); jQuery(".socialLogin").show(); localStorage.removeItem('Firebaseuserstorage'); } } function handleLinkModel(provider) { // Hide all link buttons first, then show only the relevant one jQuery(".sfba-social-btn-link").hide(); if (provider == 'google.com') { jQuery("#socialLoginLink .link-message .provider-name").html("Google"); jQuery(".sfba-social-btn-link.sfba-login-with-google-btn").show(); } else if (provider == 'facebook.com') { jQuery("#socialLoginLink .link-message .provider-name").html("Facebook"); jQuery(".sfba-social-btn-link.sfba-login-with-facebook-btn").show(); } else if (provider == 'apple.com') { jQuery("#socialLoginLink .link-message .provider-name").html("Apple"); jQuery(".sfba-social-btn-link.sfba-login-with-apple-btn").show(); } else { firebaseDebugLog(true, 'Provider doesnt exist: ' + provider); } } function getAuthProvider(providerId) { switch (providerId) { case firebase.auth.GoogleAuthProvider.PROVIDER_ID: return new firebase.auth.GoogleAuthProvider(); case firebase.auth.FacebookAuthProvider.PROVIDER_ID: return new firebase.auth.FacebookAuthProvider(); case 'apple.com': return new firebase.auth.OAuthProvider('apple.com'); default: throw new Error('No provider found for the given provider ID.'); } } // Modal for SSO Social media buttons and Add ARtist/Tags jQuery(".sfba-show").on("click", function () { var errorElement = document.getElementById("errorMessage"); if (errorElement) { errorElement.innerHTML = ''; } jQuery(".sfba-mask").addClass("sfba-active"); }); // Close popup jQuery(".sfba-close").on("click", function () { jQuery(".sfba-mask").removeClass("sfba-active"); }); // Close popup jQuery(".sfba-link-close").on("click", function () { jQuery(".sfba-link-mask").removeClass("sfba-active"); }); jQuery(".sfba-show-pref").on("click", function () { jQuery(".sfba-mask-pref").addClass("sfba-active"); }); jQuery(".sfba-close-pref").on("click", function () { jQuery(".sfba-mask-pref").removeClass("sfba-active"); }); jQuery('.tab-nav span').on('click', function () { if (jQuery(this).text() == 'My Tags') { jQuery('#all-preferences .tab-nav ul li').removeClass('active'); jQuery('#all-preferences .tab-nav ul li:nth-child(2)').addClass('active'); jQuery('#all-preferences #all-artists').removeClass('active'); jQuery('#all-preferences #all-tags').addClass('active'); } else { jQuery('#all-preferences .tab-nav ul li').addClass('active'); jQuery('#all-preferences .tab-nav ul li:nth-child(2)').removeClass('active'); jQuery('#all-preferences #all-artists').addClass('active'); jQuery('#all-preferences #all-tags').removeClass('active'); } jQuery([jQuery(this).parent()[0], jQuery(jQuery(this).data('href'))[0]]).addClass('active').siblings('.active').removeClass('active'); }); // Delete Artists/Tags jQuery('body').on('click', '.preference-delete, .preference-add.deleteid', function () { var preftype = jQuery(this).data("preftype"); var currentemailaddress = jQuery("#current-email-address").val(); if (jQuery(this).hasClass('deleteid')) { jQuery(this).removeClass('deleteid'); jQuery(this).addClass('addid'); jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); var delId = jQuery(this).data("addid"); if (preftype == "artist") { jQuery(".my-artist-list li").each(function () { if (jQuery(this).find("a").attr("data-delid") == delId) { jQuery(this).remove(); } }); } else { jQuery(".my-tags-list li").each(function () { if (jQuery(this).find("a").attr("data-delid") == delId) { jQuery(this).remove(); } }); } } else { var delId = jQuery(this).data("delid"); jQuery(this).parent().remove(); if (preftype == "artist") { jQuery(".preferences-list ul.artist-list li").each(function () { if (jQuery(this).find("a").attr("data-addid") == delId) { jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); } }); } else { jQuery(".preferences-list ul.post_tag-list li").each(function () { if (jQuery(this).find("a").attr("data-addid") == delId) { jQuery(this).find('span.pref-add').html('').html('✛'); jQuery(this).find('span.pref-add').css('color', '#009b1a'); } }); } } jQuery.ajax({ type: 'POST', url: firebaseAuthAjax.ajax_url, cache: true, data: { action: 'delete_preferences_action', currentemailaddress: currentemailaddress, delId: delId, preftype: preftype, }, success: function (response) { if (preftype == "artist") { if (jQuery('ul.my-artist-list').find('li').length === 0) { jQuery('.preferences-list.my-artists-ul').html('
Please click the "plus" icon to the right to add Artists to your profile
'); } } else { if (jQuery('ul.my-tags-list').find('li').length === 0) { jQuery('.preferences-list.my-tags-ul').html('Please click the "plus" icon to the right to add Tags to your profile
'); } } } }); }); let currentAjaxRequest = null; jQuery('.search-preferences').keyup(function (event) { if ((event.key === 'Enter' && jQuery(this).val().length > 2) || jQuery(this).val().length > 2) { jQuery('.search-pref-btn').click(); } if (event.key === 'Backspace') { jQuery('.search-pref-btn').click(); } }); jQuery('.search-pref-btn').on('click', function () { jQuery('.filterButton').removeClass('active'); searchTerm = jQuery(this).prev().val(); var ptype = jQuery(this).data('type'); var preftype = ''; var prefidstring = ''; var textpref = ''; var arrayinside = false; if (ptype === 'artist') { preftype = "artist"; prefidstring = jQuery("#artist_id").val(); textpref = "Artist"; } else if (ptype === 'post_tag') { preftype = "tags"; prefidstring = jQuery("#tag_id").val(); textpref = "Tags"; } if (searchTerm != "") { // Make AJAX request if (currentAjaxRequest) { currentAjaxRequest.abort(); } currentAjaxRequest = jQuery.ajax({ type: 'POST', url: firebaseAuthAjax.ajax_url, dataType: 'json', data: { action: 'preferences_search_action', nonce: firebaseAuthAjax.nonce, search_term: searchTerm, ptype: ptype }, success: function (response) { currentAjaxRequest = null; jQuery('.' + ptype + '-list li').css("display", "none"); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); var jsonString = JSON.stringify(response); var dataArray = JSON.parse(jsonString); setTimeout(function () { if (Array.isArray(dataArray) && dataArray.length > 0) { jQuery('.post_tag-list p').remove(); jQuery('.artist-list p').remove(); $.each(dataArray, function (index, item) { if (prefidstring !== '' && prefidstring.includes(item.term_id)) { arrayinside = true; } if (arrayinside) { jQuery('.' + ptype + '-list').append('No ' + textpref + ' found
'); } } }, 500); } }); } else { jQuery('.filterButton:first-child').addClass('active'); jQuery('.' + ptype + '-list li').css("display", "block"); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); } }); jQuery('.filterButton').on('click', function () { jQuery('.post_tag-list p').remove(); jQuery('.artist-list p').remove(); jQuery('.filterButton').removeClass("active"); var filter = jQuery(this).data('filter'); jQuery(this).addClass("active"); jQuery(this).parent().prev().find('.search-preferences').val(filter); var preid = jQuery(this).parent().parent().attr('id'); if (preid === 'all-artists') { var ptype = 'artist'; } else { var ptype = 'post_tag'; } if (ptype == "artist") { var customclass = '.artist-list li'; } else if (ptype == "post_tag") { var customclass = '.post_tag-list li'; } if (filter == "ALL") { jQuery('.' + ptype + '-list li').css("display", "block"); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); } else { jQuery(customclass).each(function () { var firstLetter = jQuery(this).text().charAt(0).toUpperCase(); if (firstLetter === filter) { jQuery(this).show(); } else { jQuery(this).hide(); } }); jQuery('.' + ptype + '-list li.nonpop-search-data').remove(); } }); // Add Artists/Tags jQuery('body').on('click', '.preference-add.addid', function () { var preftype = jQuery(this).data("preftype"); var currentemailaddress = jQuery("#current-email-address").val(); var newValueartist = '', newValuetags = '', artistadd = '', tagsadd = ''; if (preftype == 'artist') { newValueartist = jQuery(this).data('addid'); artistname = jQuery(this).data('title'); artistadd = 'Please click the "plus" icon to the right to add Artists to your profile
'); } } else { if (jQuery('ul.my-tags-list').find('li').length === 0) { jQuery('.preferences-list.my-tags-ul').html('Please click the "plus" icon to the right to add Tags to your profile
'); } } } }); }); function appendLi(selector, litoadd, textname) { var $list = jQuery(selector); var $newItem = jQuery(litoadd); var textnameIsNumeric = !isNaN(textname); var inserted = false; $list.children('li').each(function () { var $currentItem = jQuery(this); var currentTextName = $currentItem.find('span:first').text(); var currentIsNumeric = !isNaN(currentTextName); if (textnameIsNumeric && currentIsNumeric) { if (parseFloat(textname) < parseFloat(currentTextName)) { $currentItem.before($newItem); inserted = true; return false; } } else if (!textnameIsNumeric && !currentIsNumeric) { if (String(textname).toLowerCase() < String(currentTextName).toLowerCase()) { $currentItem.before($newItem); inserted = true; return false; } } else if (textnameIsNumeric && !currentIsNumeric) { $currentItem.before($newItem); inserted = true; return false; } }); if (!inserted) { $list.append($newItem); } } jQuery(".sfba-social-btn-link").on("click", async function () { jQuery(".sfba-link-mask").removeClass('sfba-active'); var existingProvider = localStorage.getItem('existingProvider'); localStorage.removeItem('existingProvider'); var authProvider = getAuthProvider(existingProvider); try { // Step 1: Sign in with the existing (original) provider var result = await firebase.auth().signInWithPopup(authProvider); var user = result.user; var idToken = await user.getIdToken(); // Step 2: Log in / create the WordPress user (reuses the same login() helper) var loginResponse = await login(user, idToken); if (!loginResponse || !loginResponse.success) { localStorage.removeItem('loggedInLocally'); throw new Error('Failed to authenticate with WordPress.'); } // Step 3: Link the pending credential (from the failed sign-in attempt) if (pendingCred) { try { // var linkResult = await user.linkWithCredential(pendingCred); // // Update cookie with fresh token from the now-linked account // var newIdToken = await linkResult.user.getIdToken(true); setCookie('ssosession', idToken, 24, cookieDomain); firebaseDebugLog(true, 'Account linking successful'); } catch (linkError) { firebaseDebugLog(true, 'Error linking account (non-fatal): ' + linkError.message); // Linking failed but user is already logged in — proceed with existing token } pendingCred = null; } window.location.reload(); } catch (error) { firebaseDebugLog(true, 'Error during account link flow: ' + error.message); } }); /** * Handle native Facebook OAuth (Option 5) * Redirects to Facebook OAuth URL */ async function handleFacebookNativeAuth() { firebaseDebugLog(true, '=== NATIVE FACEBOOK OAUTH (Option 5) ==='); // Facebook App ID (from Facebook Developer Console) const facebookAppId = '2018160385090572'; // Build Facebook OAuth URL const redirectUri = encodeURIComponent(window.location.origin + window.location.pathname); const state = Math.random().toString(36).substring(7); // Random state for security localStorage.setItem('fb_oauth_state', state); localStorage.setItem('fb_oauth_redirect', window.location.href); const facebookAuthUrl = `https://www.facebook.com/v12.0/dialog/oauth?` + `client_id=${facebookAppId}` + `&redirect_uri=${redirectUri}` + `&state=${state}` + `&scope=email,public_profile` + `&response_type=token`; firebaseDebugLog(true, 'Redirecting to Facebook OAuth:', facebookAuthUrl); // Redirect to Facebook window.location.href = facebookAuthUrl; } /** * Handle Facebook OAuth callback * Called on page load to check if we're returning from Facebook OAuth */ async function handleFacebookOAuthCallback() { // Check if login just completed (prevent reload loop) if (sessionStorage.getItem('fb_login_complete') === 'true') { firebaseDebugLog(true, 'Facebook login already completed this session, skipping callback'); sessionStorage.removeItem('fb_login_complete'); return false; } firebaseDebugLog(true, 'Checking for Facebook OAuth callback...'); // Check if URL has Facebook OAuth response (access_token in hash) const hash = window.location.hash; if (!hash || hash.indexOf('access_token=') === -1) { firebaseDebugLog(true, 'No access_token in hash, not a Facebook OAuth callback'); return false; } // Prevent multiple executions if (localStorage.getItem('fb_oauth_processing') === 'true') { firebaseDebugLog(true, 'Already processing Facebook OAuth, skipping'); return true; // Return true to prevent other handlers } localStorage.setItem('fb_oauth_processing', 'true'); firebaseDebugLog(true, '=== FACEBOOK OAUTH CALLBACK DETECTED ==='); try { // Parse the hash fragment const params = new URLSearchParams(hash.substring(1)); const accessToken = params.get('access_token'); const state = params.get('state'); firebaseDebugLog(true, 'Parsed access_token length:', accessToken?.length); firebaseDebugLog(true, 'Parsed state:', state); // Verify state to prevent CSRF const savedState = localStorage.getItem('fb_oauth_state'); firebaseDebugLog(true, 'Saved state:', savedState); if (state !== savedState) { firebaseDebugLog(true, 'ERROR: State mismatch, possible CSRF attack'); localStorage.removeItem('fb_oauth_processing'); return false; } // Exchange Facebook access token for Firebase credential firebaseDebugLog(true, 'Creating Facebook credential from access token'); const credential = firebase.auth.FacebookAuthProvider.credential(accessToken); firebaseDebugLog(true, 'Signing into Firebase with Facebook credential'); const result = await firebase.auth().signInWithCredential(credential); firebaseDebugLog(true, 'Firebase signInWithCredential successful'); const user = result.user; firebaseDebugLog(true, 'User:', user.email, 'UID:', user.uid); // Get Firebase ID token const idToken = await user.getIdToken(); firebaseDebugLog(true, 'Got Firebase ID token, length:', idToken.length); // Login to WordPress firebaseDebugLog(true, 'Calling WordPress login'); const loginResponse = await login(user, idToken); if (!loginResponse || !loginResponse.success) { firebaseDebugLog(true, 'ERROR: WordPress login failed'); localStorage.removeItem('fb_oauth_processing'); throw new Error('Failed to authenticate with WordPress.'); } firebaseDebugLog(true, 'WordPress login successful!'); // Clean up localStorage.removeItem('fb_oauth_state'); localStorage.removeItem('fb_oauth_processing'); localStorage.removeItem('fb_oauth_redirect'); // Set flag to prevent re-processing on reload sessionStorage.setItem('fb_login_complete', 'true'); // Clean hash from URL and reload window.location.hash = ''; window.location.reload(); return true; } catch (error) { firebaseDebugLog(true, 'ERROR in Facebook OAuth callback:', error.code, error.message); localStorage.removeItem('fb_oauth_processing'); // Handle account-exists-with-different-credential error (same as standard flow) if (error.code === 'auth/account-exists-with-different-credential') { // Clean the hash from URL first window.location.hash = ''; jQuery('.temp-preferences').show(); jQuery('.temp-preferences .sfba-before-login').show(); jQuery(".socialLogin").hide(); var email = error.email; // Store credential in memory pendingCred = error.credential; try { var methods = await firebase.auth().fetchSignInMethodsForEmail(email); if (methods.length > 0) { localStorage.setItem('existingProvider', methods[0]); jQuery(".sfba-mask").removeClass("sfba-active"); jQuery(".sfba-link-mask").addClass('sfba-active'); handleLinkModel(methods[0]); } } catch (fetchError) { firebaseDebugLog(true, 'Error fetching sign-in methods: ' + fetchError.message); } } return false; } } }); function logout() { firebaseDebugLog(true, '---Start Logout'); logoutInProgress = true; if (localStorage.getItem('localLogout') === null || localStorage.getItem('localLogout') == 1) { logoutPopup(); } localStorage.removeItem('localLogout'); // Sign out from Firebase firebase.auth().signOut().then(function () { firebaseDebugLog(true, 'User signed out from Firebase.'); // Perform an AJAX request to log the user out from WordPress jQuery.ajax({ url: firebaseAuthAjax.ajax_url, type: 'POST', data: { action: 'firebase_logout' // nonce: firebaseAuthAjax.nonce }, success: function (response) { if (response.success) { localStorage.removeItem('loggedInLocally'); logoutInProgress = false; document.cookie = 'ssosession=; path=/; domain=' + cookieDomain + '; expires=Thu, 01 Jan 1970 00:00:00 UTC;'; window.location.reload(); // Reload the page after successful logout } else { firebaseDebugLog(true, 'Logout failed: ', response.data.message); } firebaseDebugLog(true, '---End Logout'); }, error: function (xhr, status, error) { firebaseDebugLog(true, 'Error logging out: ', xhr.responseText); } }); }).catch(function (error) { firebaseDebugLog(true, 'Firebase logout failed: ', error.message); }); } function loginPopup() { const popupOverlay = document.createElement('div'); popupOverlay.className = 'popup-overlay'; popupOverlay.innerHTML = `