mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-22 21:26:04 +00:00
Update initgui.js
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test (18.x) (push) Has been cancelled
test / test (20.x) (push) Has been cancelled
test / test (22.x) (push) Has been cancelled
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test (18.x) (push) Has been cancelled
test / test (20.x) (push) Has been cancelled
test / test (22.x) (push) Has been cancelled
This commit is contained in:
+257
-37
@@ -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 = `
|
||||
<div id="${modalId}" class="modal" style="
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10000;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
">
|
||||
<div class="modal-content" style="
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
">
|
||||
<div class="modal-header" style="margin-bottom: 20px;">
|
||||
<img src="${window.icons['logo-white.svg']}" style="
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 auto 15px;
|
||||
display: block;
|
||||
padding: 10px;
|
||||
background-color: #3b82f6;
|
||||
border-radius: 8px;
|
||||
">
|
||||
<h2 style="
|
||||
margin: 0;
|
||||
color: #1f2937;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
">Welcome to Puter</h2>
|
||||
<p style="
|
||||
margin: 10px 0 0 0;
|
||||
color: #6b7280;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
">Please complete the security verification to continue</p>
|
||||
</div>
|
||||
|
||||
<div class="turnstile-container" style="
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 20px 0;
|
||||
min-height: 80px;
|
||||
align-items: center;
|
||||
">
|
||||
<div id="turnstile-widget-${modalId}" class="cf-turnstile" data-sitekey="${siteKey}"></div>
|
||||
</div>
|
||||
|
||||
<div class="loading-state" style="
|
||||
display: none;
|
||||
margin: 20px 0;
|
||||
color: #6b7280;
|
||||
font-size: 14px;
|
||||
">
|
||||
<div style="
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid #e5e7eb;
|
||||
border-radius: 50%;
|
||||
border-top: 2px solid #3b82f6;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
"></div>
|
||||
Setting up your account...
|
||||
</div>
|
||||
|
||||
<div class="error-message" style="
|
||||
display: none;
|
||||
color: #dc2626;
|
||||
font-size: 14px;
|
||||
margin-top: 15px;
|
||||
padding: 10px;
|
||||
background-color: #fef2f2;
|
||||
border: 1px solid #fecaca;
|
||||
border-radius: 6px;
|
||||
"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
// 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('<span style="-webkit-font-smoothing: antialiased;">Setting up your <a href="https://puter.com" target="_blank">Puter.com</a> account for secure AI and Cloud features</span>');
|
||||
}
|
||||
// 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('<span style="-webkit-font-smoothing: antialiased;">Setting up your <a href="https://puter.com" target="_blank">Puter.com</a> account for secure AI and Cloud features</span>');
|
||||
}
|
||||
|
||||
$.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
|
||||
|
||||
Reference in New Issue
Block a user