// Define Turnstile site key from PHP constant. const turnstileSiteKey = '0x4AAAAAAB1h6NJWcSzCNa-D'; $("#main .container").addClass("wp-auth-hide-init"); console.log('on'); // Function to load the Cloudflare Turnstile script if a captcha widget is present. function loadTurnstile(loadme) { var id = ".cf-turnstile"; if(!turnstileSiteKey){ console.log("No sitekey"); } if(!loadTurnstile.loaded) { console.log("t loaded"); // return; loadTurnstile.loaded = true; //if ( document.querySelector('.cf-turnstile') ) { const script = document.createElement('script'); script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'; script.async = true; script.onerror = function() { console.error('Failed to load Turnstile script'); }; document.head.appendChild(script); // } } //turnstile.ready(function () { unloadTurnstile(); if(id && loadme){ loadTurnstile.Id =turnstile.render(id, { sitekey: turnstileSiteKey, callback: function (token) { //console.log(`Challenge Success ${token}`); }, }); } //}); } function unloadTurnstile(){ try{ if(loadTurnstile.Id && turnstile ){ turnstile.remove(loadTurnstile.Id ) }else{ console.log("Missing id and turnstile"); } }catch(e){ console.log(e,"t error"); } } loadTurnstile(); class WPAuth { constructor(options = {}) { this.ajaxUrl = 'https://www.jamestaylor.com/wp-admin/admin-ajax.php'; this.options = { onLogin: null, onRegister: null, ...options }; this.init(); } init() { // Add stylesheet to head const style = document.createElement('style'); style.textContent = ` .wp-auth-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.3); display: flex; align-items: center; justify-content: center; z-index: 999999; backdrop-filter: blur(3px); } .wp-auth-modal { background: var(--wp-auth-bg); color: var(--wp-auth-text); padding: 2rem; border-radius: 12px; width: 90%; max-width: 400px; position: relative; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); animation: modalSlideIn 0.3s ease-out; } .wp-auth-modal.light { --wp-auth-bg: rgba(255, 255, 255, 0.5); --wp-auth-text: #333333; --wp-auth-input-bg: #f5f5f5; --wp-auth-input-border: #e0e0e0; --wp-auth-input-focus: #4a90e2; --wp-auth-button-bg: #4a90e2; --wp-auth-button-text: #ffffff; --wp-auth-link: #4a90e2; --wp-auth-background: rgba(0, 0, 0, 0.6); } .wp-auth-modal.dark { --wp-auth-bg: rgba(0, 0, 0, 0.5); --wp-auth-text: #ffffff; --wp-auth-input-bg: #3d3d3d; --wp-auth-input-border: #4d4d4d; --wp-auth-input-focus: #6ab0f3; --wp-auth-button-bg: #6ab0f3; --wp-auth-button-text: #ffffff; --wp-auth-link: #6ab0f3; --wp-auth-background: rgba(255, 255, 255, 0.6); } @keyframes modalSlideIn { from { transform: translateY(-20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .wp-auth-modal h2 { margin: 0 0 1.5rem 0; font-size: 1.5rem; font-weight: 600; color: var(--wp-auth-text); } .wp-auth-close { position: absolute; right: 1rem; top: 1rem; border: none; background: none; font-size: 1.5rem; cursor: pointer; color: var(--wp-auth-text); opacity: 0.7; transition: opacity 0.2s; padding: 0.5rem; line-height: 1; } .wp-auth-close:hover { opacity: 1; } .wp-auth-form { display: flex; flex-direction: column; gap: 1rem; } .wp-auth-input { padding: 0.75rem 1rem; border: 1px solid var(--wp-auth-input-border); border-radius: 6px; background: var(--wp-auth-input-bg); color: var(--wp-auth-text); font-size: 1rem; transition: border-color 0.2s, box-shadow 0.2s; } .wp-auth-input:focus { outline: none; border-color: var(--wp-auth-input-focus); box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1); } .wp-auth-checkbox { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; } .wp-auth-checkbox input { cursor: pointer; } .wp-auth-button { background: var(--wp-auth-button-bg); color: var(--wp-auth-button-text); padding: 0.75rem 1.5rem; border: none; border-radius: 6px; font-size: 1rem; font-weight: 500; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; } .wp-auth-button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(74, 144, 226, 0.2); } .wp-auth-message { text-align: center; margin-top: 1rem; padding: 0.75rem; border-radius: 6px; font-size: 0.9rem; } .wp-auth-message.error { background: #ffebee; color: #c62828; } .wp-auth-message.success { background: #e8f5e9; color: #2e7d32; } .wp-auth-links { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 1rem; text-align: center; } .wp-auth-links a { color: var(--wp-auth-link); text-decoration: none; font-size: 0.9rem; transition: opacity 0.2s; } .wp-auth-links a:hover { opacity: 0.8; } .wp-auth-modal h1 { margin: 0 0 1.5rem 0; font-size: 2rem; font-weight: 600; color: #454343; } `; if(this.options.styleOverride){ style.textContent += this.options.styleOverride; } document.head.appendChild(style); // Create container for modals if (!document.getElementById('wp-auth-popup')) { const container = document.createElement('div'); container.id = 'wp-auth-popup'; document.body.appendChild(container); } } async login(username, password, remember = false,cf_turnstile_response="") { const formData = new FormData(); formData.append('action', 'simple_login'); formData.append('username', username); formData.append('password', password); formData.append('remember', remember); formData.append('cf-turnstile-response', cf_turnstile_response); try { const response = await fetch(this.ajaxUrl, { method: 'POST', credentials: 'include', body: formData }); const data = await response.json(); if (data.success) { if (this.options.onLogin) { this.options.onLogin(data.data); } return data.data; } else { throw new Error(data.data.message); } } catch (error) { throw error; } } async register(username, email, password,cf_turnstile_response="") { const formData = new FormData(); formData.append('action', 'simple_register'); formData.append('username', username); formData.append('email', email); formData.append('password', password); formData.append('cf-turnstile-response', cf_turnstile_response); try { const response = await fetch(this.ajaxUrl, { method: 'POST', credentials: 'include', body: formData }); const data = await response.json(); if (data.success) { if (this.options.onRegister) { this.options.onRegister(data.data); } return data.data; } else { throw new Error(data.data.message); } } catch (error) { throw error; } } async forgotPassword(username,cf_turnstile_response="") { const formData = new FormData(); formData.append('action', 'simple_forgot'); formData.append('username', username); formData.append('cf-turnstile-response', cf_turnstile_response); try { const response = await fetch(this.ajaxUrl, { method: 'POST', credentials: 'include', body: formData }); const data = await response.json(); if (data.success) { return data.data; } else { throw new Error(data.data.message); } } catch (error) { throw error; } } showLoginForm() { const container = document.getElementById('wp-auth-popup'); container.innerHTML = `

${this.options.MembershipPopUpHeaderText}

Login

`; setTimeout(()=>loadTurnstile(true),10); document.getElementById('login-form').addEventListener('submit', async (e) => { e.preventDefault(); const form = e.target; const message = document.getElementById('login-message'); try { const result = await this.login( form.username.value, form.password.value, form.remember.checked, (form['cf-turnstile-response'] && form['cf-turnstile-response'].value)||"" ); message.style.color = 'green'; message.textContent = 'Login successful!'; setTimeout(() => { container.innerHTML = ''; if (this.options.onLogin) { this.options.onLogin(result); } }, 1000); } catch (error) { message.style.color = 'darkred'; message.innerHTML = error.message.includes('undefined') ? 'Error: please check your entry and try again' : error.message; } }); } showRegisterForm() { const container = document.getElementById('wp-auth-popup'); container.innerHTML = `

${this.options.MembershipPopUpHeaderText}

Create Account

`; setTimeout(()=>loadTurnstile(true),10); document.getElementById('register-form').addEventListener('submit', async (e) => { e.preventDefault(); const form = e.target; const message = document.getElementById('register-message'); try { const result = await this.register( form.username.value, form.email.value, form.password.value, (form['cf-turnstile-response'] && form['cf-turnstile-response'].value)||"" ); message.style.color = 'green'; message.textContent = 'Registration successful!'; setTimeout(() => { container.innerHTML = ''; if (this.options.onRegister) { this.options.onRegister(result); } }, 1000); } catch (error) { message.style.color = 'darkred'; message.innerHTML = error.message.includes('undefined') ? 'Error: please check your entry and try again' : error.message; } }); } showForgotForm() { const container = document.getElementById('wp-auth-popup'); container.innerHTML = `

${this.options.MembershipPopUpHeaderText}

Reset Password

`; setTimeout(()=>loadTurnstile(true),10); document.getElementById('forgot-form').addEventListener('submit', async (e) => { e.preventDefault(); const form = e.target; const message = document.getElementById('forgot-message'); try { const result = await this.forgotPassword(form.username.value, (form['cf-turnstile-response'] && form['cf-turnstile-response'].value)||""); message.style.color = 'green'; message.textContent = 'Password reset email sent!'; setTimeout(() => { this.showLoginForm(); }, 2000); } catch (error) { message.style.color = 'darkred'; message.innerHTML = error.message.includes('undefined') ? 'Error: please check your entry and try again' : error.message; } }); } } // Make WPAuth globally available window.WPAuth = WPAuth; //window.wpAuth = new WPAuth(); var MinimalAuth = { config: { membersClass: 'members-only-access', publicClass: 'public-only-access', userInfoClass: 'user-info', loginBtnClass: 'login-btn', logoutBtnClass: 'logout-btn' }, state: { isLoggedIn: false }, init: function() { this.state.isLoggedIn = this.checkLogin(); this.updateVisibility(this.state.isLoggedIn); this.bindElements(); }, checkLogin: function() { try { var userState = this.getCookie('wp_user_state'); if (userState) { var data = JSON.parse(userState); if (data.logged_in && data.exp > Date.now() / 1000) { return true; } } var authCookie = document.cookie.split(';') .find(function(c) { return c.trim().startsWith('wordpress_logged_in_'); }); if (!authCookie) return false; var cookieValue = decodeURIComponent(authCookie.split('=')[1]); return this.validateAuthCookie(cookieValue); } catch(e) { console.error('Auth check failed:', e); return false; } }, validateAuthCookie: function(cookieValue) { if (!cookieValue) return false; var parts = cookieValue.split('|'); if (parts.length !== 4) return false; var expiration = parseInt(parts[1], 10); if (isNaN(expiration) || expiration < (Date.now() / 1000)) { this.clearAuthCookie(); return false; } return true; }, clearAuthCookie: function() { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookieName = cookies[i].split('=')[0].trim(); if (cookieName.startsWith('wordpress_logged_in_') || cookieName === 'wp_user_state') { document.cookie = cookieName + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'; } } }, updateVisibility: function(isLoggedIn) { document.querySelectorAll('.' + this.config.membersClass).forEach(function(el) { el.style.display = isLoggedIn ? el.getAttribute("display") : 'none'; // get attr to maintain flex vs block }); document.querySelectorAll('.' + this.config.publicClass).forEach(function(el) { el.style.display = isLoggedIn ? 'none' : el.getAttribute("display") ;// get attr to maintain flex vs block }); if (isLoggedIn) { var displayedName = ''; var userState = this.getCookie('wp_user_state'); if (userState) { try { var data = JSON.parse(userState); if (data.username) { displayedName = data.username; } } catch(e) {} } if (!displayedName) { var authCookie = document.cookie.split(';') .find(function(c) { return c.trim().startsWith('wordpress_logged_in_'); }); if (authCookie) { displayedName = decodeURIComponent(authCookie.split('|')[0].split('=')[1]); } } document.querySelectorAll('.' + this.config.userInfoClass).forEach(function(el) { el.textContent = displayedName; }); } else { document.querySelectorAll('.' + this.config.userInfoClass).forEach(function(el) { el.textContent = ''; }); } }, bindElements: function() { document.querySelectorAll('.' + this.config.loginBtnClass).forEach(function(el) { el.addEventListener('click', function(e) { e.preventDefault(); var returnUrl = encodeURIComponent(window.location.href); window.location.href = '/wp-login.php?redirect_to=' + returnUrl + '&redirect_initiator=plugin'; }); }); document.querySelectorAll('.' + this.config.logoutBtnClass).forEach(function(el) { el.addEventListener('click', function(e) { e.preventDefault(); var returnUrl = encodeURIComponent(window.location.href); window.location.href = '/wp-login.php?action=logout&redirect_to=' + returnUrl; }); }); }, getCookie: function(name) { var nameEq = name + '='; var parts = document.cookie.split(';'); for (var i = 0; i < parts.length; i++) { var c = parts[i].trim(); if (c.indexOf(nameEq) === 0) { return decodeURIComponent(c.substring(nameEq.length)); } } return null; } }; function findAndReplace({ find, replace, caseSensitive = false, wholeWord = false, includeHtml = false, selector = "body", regex = false, }) { if (!find) return 0; const target = document.querySelector(selector); if (!target) return 0; let count = 0; let searchRegex; if (regex) { try { searchRegex = new RegExp(find, caseSensitive ? "g" : "gi"); } catch (e) { console.error("Invalid regex pattern:", e); return 0; } } else { const escapedFind = find.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); let pattern = escapedFind; if (wholeWord) { pattern = `\\b${pattern}\\b`; } searchRegex = new RegExp(pattern, caseSensitive ? "g" : "gi"); } if (includeHtml) { const originalHtml = target.innerHTML; const newHtml = originalHtml.replace(searchRegex, (match) => { count++; return replace; }); if (originalHtml !== newHtml) { target.innerHTML = newHtml; } } else { const walker = document.createTreeWalker(target, NodeFilter.SHOW_TEXT, null, false); const nodesToUpdate = []; let node; while ((node = walker.nextNode())) { const originalText = node.textContent; const newText = originalText.replace(searchRegex, (match) => { count++; return replace; }); if (originalText !== newText) { nodesToUpdate.push([node, newText]); } } nodesToUpdate.forEach(([node, newText]) => { node.textContent = newText; }); } return count; } function far(f, r) { findAndReplace({ find: f, replace: r, caseSensitive: false, wholeWord: false, includeHtml: true, selector: "body", regex: false, }); } // Function to find element by text content and optionally class function findElementByTextAndClass(searchText, className = '') { const elements = document.getElementsByTagName('*'); return Array.from(elements).map(element => { $modifications.log && $modifications.log("1",element); if(element.localName ==="script"){ return false; } if(element.localName ==="style"){ return false; } if(element.localName ==="link"){ return false; } $modifications.log && $modifications.log("2",element); const hasText =(!$(element).html().includes('<')) && element.textContent.toLowerCase().includes(searchText.toLowerCase()); if (className) { return hasText && element.classList.contains(className) && element; } return hasText && element; }); } // Function to safely add click handler function addClickHandler(element, handler) { if (typeof handler === 'function') { element.onclick = handler; } else if (typeof handler === 'string') { element.setAttribute('onclick', handler); } } // Function to add multiple classes function addClasses(element, classes) { if (typeof classes === 'string') { element.classList.add(classes); } else if (Array.isArray(classes)) { element.classList.add(...classes); } } // Function to duplicate and modify elements function duplicateAndModifyElement(searchText, modifications = {}) { // Find the original element using text and optional class return findElementByTextAndClass(searchText, modifications.searchClass).map(originalElement=>{ if (!originalElement) { console.error('Element not found with text:', searchText); return; } originalElement.setAttribute("display",$(originalElement).css("display")); // Create a duplicate const duplicate = originalElement.cloneNode(true); // Modify the duplicate if (modifications.text) { duplicate.textContent = modifications.text; } // Add classes to duplicate if (modifications.newClasses) { addClasses(duplicate, modifications.newClasses); } // Add classes to original if (modifications.originalNewClasses) { addClasses(originalElement, modifications.originalNewClasses); } // Modify links if element is an anchor if (modifications.newLink && duplicate.tagName.toLowerCase() === 'a') { duplicate.href = modifications.newLink; } // Add click handlers if ( modifications.originalOnClick) { addClickHandler(originalElement, modifications.originalOnClick); } if ( modifications.newOnClick) { addClickHandler(duplicate, modifications.newOnClick); } $(duplicate).removeClass("logout-btn"); // todo use logoutBtnClass variable // Insert the duplicate after the original element originalElement.parentNode.insertBefore(duplicate, originalElement.nextSibling); return { original: originalElement, duplicate }; }); } /* --- application starts here --- */ var $modifications = $modifications || { }; // Text for the duplicate $modifications.injectLocationForMembership=$modifications.injectLocationForMembership ||".header-row-1"; $modifications.text= $modifications.text ||'Members Only - Login'; $modifications.styleOverride = $modifications.styleOverride || false; $modifications.searchText= $modifications.searchText ||'Presale'; $modifications.searchTextMain= $modifications.searchTextMain || 'Sign Out'; $modifications.textMain= $modifications.textMain ||'Sign In'; $modifications.theme= $modifications.theme ||'dark'; $modifications.MembershipPopUpHeaderText= $modifications.MembershipPopUpHeaderText ||'Members Access'; $modifications.showMainLogin = ($modifications.showMainLogin=== false)? false: true; $modifications.testMode= $modifications.testMode ||false; // Class to search for the original element //$modifications.searchClass= 'PresaleClass', // Classes to add to the duplicate (string or array) $modifications.newClasses= $modifications.newClasses || ['public-only-access'], // Classes to add to the original element (string or array) $modifications.originalNewClasses= $modifications.originalNewClasses || ['members-only-access'], // New link for duplicate if it's an anchor // $modifications.newLink= 'https://example.com/new', // Click handlers (can be function or string) // $modifications.originalOnClick= function(e) { console.log('Original clicked!'); } // locked pages $modifications.lpages=$modifications.lpages||[]; $modifications.ready = $modifications.ready||function(){ $('.wp-auth-hide-init').removeClass('wp-auth-hide-init');}; $modifications.lpagesLoginHtml=$modifications.lpagesLoginHtml ||``; $modifications.addAllExtraPages = $modifications.addAllExtraPages == false? false : true; $modifications.addSubscriptionPage = $modifications.addSubscriptionPage == false? false : true; $modifications.applyDefaultAuthButtonInlineStyle = $modifications.applyDefaultAuthButtonInlineStyle ==false? false:true; $modifications.lpages.map((page)=>{ if(location.href.toLocaleLowerCase().includes(('/'+page).toLocaleLowerCase())){ // $("#main .container").addClass("wp-auth-hide-init"); }}); $modifications.newOnClick= (e) => { e.preventDefault(); e.stopPropagation(); window.wpAuth.showLoginForm({ title: 'Login', onSuccess: (data) => { console.log('Logged in:', data); window.location.reload(); } }); } let defaultAuthButtonInlineStyle = $modifications.applyDefaultAuthButtonInlineStyle ? `text-transform: uppercase; background: #ffe457; border: none; color: #000; padding: 6px 10px; border-radius: 4px; filter: drop-shadow(0.5rem 0.5rem 0.3rem #1d1c1c);`:`` let allExtraPages =$modifications.addAllExtraPages? `
  • Download
  • Photo Gallery
  • `:``; let subscriptionPage = $modifications.addSubscriptionPage?`
  • Subscribe
  • `:``; document.addEventListener("DOMContentLoaded", function() { if($modifications.showMainLogin){ $('.header-community').remove(); if(!$modifications.new_normal){ $($modifications.injectLocationForMembership).append(`
    `); }else{ $($modifications.injectLocationForMembership).append(`
    `); } } setTimeout(function(){ window.wpAuth = new WPAuth({ ...$modifications, onLogin: (data) => { console.log('Logged in successfully', data); // Handle successful login if($modifications.pathAfterLogin && (window.location.href !== window.location.origin+ $modifications.pathAfterLogin)){ window.location.href = window.location.origin+ $modifications.pathAfterLogin; }else{ window.location.reload(); } }, onRegister: (data) => { console.log('Registered successfully', data); // Handle successful registration if($modifications.pathAfterLogin && (window.location.href !== window.location.origin+ $modifications.pathAfterLogin)){ window.location.href = window.location.origin+ $modifications.pathAfterLogin; }else{ window.location.reload(); } } }); setTimeout(function(){ duplicateAndModifyElement($modifications.searchText, $modifications); $modifications.searchTextMain && $modifications.textMain && duplicateAndModifyElement($modifications.searchTextMain, {...$modifications,text:$modifications.textMain}); MinimalAuth.init(); let isLoggedIn = $modifications.testMode?false:MinimalAuth.state.isLoggedIn; MinimalAuth.updateVisibility(isLoggedIn); $modifications.lpages.map((page)=>{ if(location.href.toLocaleLowerCase().includes(('/'+page).toLocaleLowerCase())){ //$("#main .container").html($modifications.lpagesLoginHtml);//("members-only-access"); $( function() { setTimeout(()=>{ if(!MinimalAuth.checkLogin()) { $("#main .container").html($modifications.lpagesLoginHtml ); $("#main .container").css("display","block"); $modifications.newOnClick({preventDefault:()=>{}, stopPropagation:()=>{}}); }else{ $("#main .container").css("display","block"); } try{ $modifications.ready && $modifications.ready(); }catch(error2){ console.log(error2); } },100); }); } }); },50);; },50); }); function mbsLogin(){ $modifications.newOnClick({preventDefault:()=>{}, stopPropagation:()=>{}}); } console.log('did it'); /* --- application ends here --- */