From 245a04047ef4bd7a7b3a5ff4d2601a6d9f4a98a2 Mon Sep 17 00:00:00 2001 From: jelveh Date: Wed, 27 Aug 2025 17:29:34 -0700 Subject: [PATCH] Update initgui.js --- src/gui/src/initgui.js | 294 +++++++++++++++++++++++++++++++++++------ 1 file changed, 257 insertions(+), 37 deletions(-) diff --git a/src/gui/src/initgui.js b/src/gui/src/initgui.js index 6717ac9ef..d8739a0e1 100644 --- a/src/gui/src/initgui.js +++ b/src/gui/src/initgui.js @@ -151,6 +151,201 @@ if(jQuery){ }; } +/** + * Shows a Turnstile challenge modal for first-time temp user creation + * @param {Object} options - Configuration options + * @param {Function} options.onSuccess - Callback when challenge is completed successfully + * @param {Function} options.onError - Callback when challenge fails + */ +window.showTurnstileChallenge = function(options) { + return new Promise((resolve) => { + const modalId = 'turnstile-challenge-modal'; + const siteKey = window.gui_params?.turnstileSiteKey; + + if (!siteKey) { + options.onError('Turnstile site key not configured'); + return resolve(); + } + + // Create modal HTML + let modalHtml = ` + + + + `; + + // Add modal to DOM + document.body.insertAdjacentHTML('beforeend', modalHtml); + const modal = document.getElementById(modalId); + const errorMessage = modal.querySelector('.error-message'); + const loadingState = modal.querySelector('.loading-state'); + const turnstileContainer = modal.querySelector('.turnstile-container'); + + // Initialize Turnstile widget + const initTurnstile = () => { + if (!window.turnstile) { + setTimeout(initTurnstile, 100); + return; + } + + try { + window.turnstile.render(`#turnstile-widget-${modalId}`, { + sitekey: siteKey, + callback: function(token) { + // Show loading state + turnstileContainer.style.display = 'none'; + loadingState.style.display = 'block'; + + // Call success callback + options.onSuccess(token); + + // Remove modal after a brief delay + setTimeout(() => { + modal.remove(); + resolve(); + }, 500); + }, + 'expired-callback': function() { + showError('Verification expired. Please try again.'); + }, + 'error-callback': function() { + showError('Verification failed. Please refresh the page and try again.'); + options.onError('Turnstile verification failed'); + } + }); + } catch (error) { + console.error('Failed to initialize Turnstile:', error); + showError('Failed to load security verification. Please refresh the page.'); + options.onError(error); + } + }; + + const showError = (message) => { + errorMessage.textContent = message; + errorMessage.style.display = 'block'; + }; + + // Start initialization + initTurnstile(); + + // Prevent modal from closing by clicking outside + modal.addEventListener('click', (e) => { + if (e.target === modal) { + // Don't close - force users to complete verification + turnstileContainer.style.transform = 'scale(1.05)'; + setTimeout(() => { + if (turnstileContainer) { + turnstileContainer.style.transform = 'scale(1)'; + } + }, 200); + } + }); + + // Add transition styles + modal.style.opacity = '0'; + modal.style.transition = 'opacity 0.3s ease'; + + // Fade in + requestAnimationFrame(() => { + modal.style.opacity = '1'; + }); + }); +}; + window.initgui = async function(options){ const url = new URL(window.location).href; window.url = url; @@ -812,7 +1007,7 @@ window.initgui = async function(options){ } // ------------------------------------------------------------------------------------- - // Un-authed and first visit ever -> create temp user + // Un-authed and first visit ever -> create temp user with Turnstile challenge // ------------------------------------------------------------------------------------- else if(!window.is_auth() && window.first_visit_ever && !window.disable_temp_users){ let referrer; @@ -838,49 +1033,74 @@ window.initgui = async function(options){ if(window.custom_headers) headers = window.custom_headers; - // if this is a popup, show a spinner - let spinner_init_ts = Date.now(); - if(window.embedded_in_popup){ - puter.ui.showSpinner('Setting up your Puter.com account for secure AI and Cloud features'); - } + // Function to create temp user after captcha completion + const createTempUser = (turnstileToken) => { + // if this is a popup, show a spinner + let spinner_init_ts = Date.now(); + if(window.embedded_in_popup){ + puter.ui.showSpinner('Setting up your Puter.com account for secure AI and Cloud features'); + } - $.ajax({ - url: window.gui_origin + "/signup", - type: 'POST', - async: true, - headers: headers, - contentType: "application/json", - data: JSON.stringify({ + const requestData = { referrer: referrer, referral_code: window.referral_code, is_temp: true, - }), - success: async function (data){ - // if this is a popup, hide the spinner, make sure it was visible for at least 2 seconds - if(window.embedded_in_popup){ - let spinner_duration = (Date.now() - spinner_init_ts); - setTimeout(() => { - window.update_auth_data(data.token, data.user); - document.dispatchEvent(new Event("login", { bubbles: true})); - puter.ui.hideSpinner(); - }, spinner_duration > 2000 ? 10 : 2000 - spinner_duration); + }; - return; - }else{ - window.update_auth_data(data.token, data.user); - document.dispatchEvent(new Event("login", { bubbles: true})); - } - }, - error: async (err) => { - UIAlert({ - message: html_encode(err.responseText), - }); - }, - complete: function(){ - + // Add Turnstile token if available + if (turnstileToken) { + requestData['cf-turnstile-response'] = turnstileToken; } - }); + $.ajax({ + url: window.gui_origin + "/signup", + type: 'POST', + async: true, + headers: headers, + contentType: "application/json", + data: JSON.stringify(requestData), + success: async function (data){ + // if this is a popup, hide the spinner, make sure it was visible for at least 2 seconds + if(window.embedded_in_popup){ + let spinner_duration = (Date.now() - spinner_init_ts); + setTimeout(() => { + window.update_auth_data(data.token, data.user); + document.dispatchEvent(new Event("login", { bubbles: true})); + puter.ui.hideSpinner(); + }, spinner_duration > 2000 ? 10 : 2000 - spinner_duration); + + return; + }else{ + window.update_auth_data(data.token, data.user); + document.dispatchEvent(new Event("login", { bubbles: true})); + } + }, + error: async (err) => { + UIAlert({ + message: html_encode(err.responseText), + }); + }, + complete: function(){ + + } + }); + }; + + // Check if Turnstile is enabled and show challenge + if (window.gui_params?.turnstileSiteKey) { + window.showTurnstileChallenge({ + onSuccess: createTempUser, + onError: (error) => { + console.error('Turnstile verification failed:', error); + UIAlert({ + message: 'Security verification failed. Please refresh the page and try again.', + }); + } + }); + } else { + // No Turnstile configured, proceed without challenge + createTempUser(); + } } // if there is at least one window open (only non-Explorer windows), ask user for confirmation when navigating away from puter