Remove captcha from frotnend (#1335)

This commit is contained in:
Nariman Jelveh
2025-07-04 16:31:42 -07:00
committed by GitHub
parent f3c658c011
commit 3eef18c578
6 changed files with 0 additions and 680 deletions

View File

@@ -1,287 +0,0 @@
/**
* Copyright (C) 2024-present Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* CaptchaView - A component for displaying and handling captcha challenges
*
* @param {Object} options - Configuration options
* @param {HTMLElement} options.container - The container element to attach the captcha to
* @param {Function} options.onReady - Callback when the captcha is ready
* @param {Function} options.onError - Callback for handling errors
* @param {boolean} options.required - Whether captcha is required (will not display if false)
* @param {Function} options.onRequiredChange - Callback when the required status changes
* @returns {Object} - Methods to interact with the captcha
*/
function CaptchaView(options = {}) {
// Internal state
const state = {
token: null,
image: null,
answer: '',
loading: false,
error: null,
container: options.container || document.createElement('div'),
required: options.required !== undefined ? options.required : true, // Default to required
initialized: false
};
// Create the initial DOM structure
const init = () => {
const container = state.container;
container.classList.add('captcha-view-container');
container.style.marginTop = '20px';
container.style.marginBottom = '20px';
// Add container CSS
container.style.display = state.required ? 'flex' : 'none';
container.style.flexDirection = 'column';
container.style.gap = '10px';
state.initialized = true;
// Render the initial HTML
render();
// Only fetch captcha if required
if (state.required) {
refresh();
}
};
// Set whether captcha is required
const setRequired = (required) => {
if (state.required === required) return; // No change
state.required = required;
if (state.initialized) {
// Update display
state.container.style.display = required ? 'flex' : 'none';
// If becoming required and no captcha loaded, fetch one
if (required && !state.token) {
refresh();
}
// Notify of change if callback provided
if (typeof options.onRequiredChange === 'function') {
options.onRequiredChange(required);
}
}
};
// Render the captcha HTML
const render = () => {
const container = state.container;
// Clear the container
container.innerHTML = '';
// Label
const label = document.createElement('label');
label.textContent = i18n('captcha_verification');
label.setAttribute('for', `captcha-input-${Date.now()}`);
container.appendChild(label);
// Captcha wrapper
const captchaWrapper = document.createElement('div');
captchaWrapper.classList.add('captcha-wrapper');
captchaWrapper.style.display = 'flex';
captchaWrapper.style.flexDirection = 'column';
captchaWrapper.style.gap = '10px';
container.appendChild(captchaWrapper);
// Captcha image and refresh button container
const imageContainer = document.createElement('div');
imageContainer.style.display = 'flex';
imageContainer.style.alignItems = 'stretch';
imageContainer.style.justifyContent = 'space-between';
imageContainer.style.gap = '10px';
imageContainer.style.border = '1px solid #ced7e1';
imageContainer.style.borderRadius = '4px';
imageContainer.style.padding = '10px';
captchaWrapper.appendChild(imageContainer);
// Captcha image
const imageElement = document.createElement('div');
imageElement.classList.add('captcha-image');
if (state.loading) {
imageElement.innerHTML = '<div style="display:flex;justify-content:center;align-items:center;height:50px;"><span style="font-size:14px;">Loading captcha...</span></div>';
} else if (state.error) {
imageElement.innerHTML = `<div style="color:red;padding:10px;">${state.error}</div>`;
} else if (state.image) {
imageElement.innerHTML = state.image;
// Make SVG responsive
const svgElement = imageElement.querySelector('svg');
if (svgElement) {
svgElement.style.width = '100%';
svgElement.style.height = 'auto';
}
} else {
imageElement.innerHTML = '<div style="display:flex;justify-content:center;align-items:center;height:50px;"><span style="font-size:14px;">No captcha loaded</span></div>';
}
imageContainer.appendChild(imageElement);
// Refresh button
const refreshButton = document.createElement('button');
refreshButton.classList.add('button', 'button-small');
refreshButton.innerHTML = '<i class="fas fa-sync-alt">⟳</i>';
refreshButton.setAttribute('title', i18n('refresh_captcha'));
refreshButton.style.minWidth = '30px';
refreshButton.style.fontSize = '30px';
refreshButton.style.height = 'auto';
refreshButton.style.marginBottom = '4px';
refreshButton.setAttribute('type', 'button');
refreshButton.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
refresh();
});
imageContainer.appendChild(refreshButton);
// Input field
const inputField = document.createElement('input');
inputField.id = `captcha-input-${Date.now()}`;
inputField.classList.add('captcha-input');
inputField.type = 'text';
inputField.placeholder = i18n('enter_captcha_text');
inputField.setAttribute('autocomplete', 'off');
inputField.setAttribute('spellcheck', 'false');
inputField.setAttribute('autocorrect', 'off');
inputField.setAttribute('autocapitalize', 'off');
inputField.value = state.answer || '';
inputField.addEventListener('input', (e) => {
state.answer = e.target.value;
});
// Prevent Enter key from triggering refresh and allow it to submit the form
inputField.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
// Don't prevent default here - let Enter bubble up to the form
// Just make sure we don't refresh the captcha
e.stopPropagation();
}
});
captchaWrapper.appendChild(inputField);
// Helper text
const helperText = document.createElement('div');
helperText.classList.add('captcha-helper-text');
helperText.style.fontSize = '12px';
helperText.style.color = '#666';
helperText.textContent = i18n('captcha_case_sensitive');
captchaWrapper.appendChild(helperText);
};
// Fetch a new captcha
const refresh = async () => {
// Skip if not required
if (!state.required) {
return;
}
try {
state.loading = true;
state.error = null;
render();
const response = await fetch(window.gui_origin + '/api/captcha/generate');
if (!response.ok) {
throw new Error(`Failed to load captcha: ${response.status}`);
}
const data = await response.json();
state.token = data.token;
state.image = data.image;
state.loading = false;
render();
if (typeof options.onReady === 'function') {
options.onReady();
}
} catch (error) {
state.loading = false;
state.error = error.message || 'Failed to load captcha';
render();
if (typeof options.onError === 'function') {
options.onError(error);
}
}
};
// Public API
const api = {
/**
* Get the current captcha token
* @returns {string} The captcha token
*/
getToken: () => state.token,
/**
* Get the current captcha answer
* @returns {string} The user's answer
*/
getAnswer: () => state.answer,
/**
* Reset the captcha - clear answer and get a new challenge
*/
reset: () => {
state.answer = '';
refresh();
},
/**
* Get the container element
* @returns {HTMLElement} The container element
*/
getElement: () => state.container,
/**
* Check if captcha is required
* @returns {boolean} Whether captcha is required
*/
isRequired: () => state.required,
/**
* Set whether captcha is required
* @param {boolean} required - Whether captcha is required
*/
setRequired: setRequired
};
// Set initial required state from options
if (options.required !== undefined) {
state.required = options.required;
}
// Initialize the component
init();
return api;
}
export default CaptchaView;

View File

@@ -28,8 +28,6 @@ import JustHTML from './Components/JustHTML.js';
import StepView from './Components/StepView.js';
import Button from './Components/Button.js';
import RecoveryCodeEntryView from './Components/RecoveryCodeEntryView.js';
import CaptchaView from './Components/CaptchaView.js'
import { isCaptchaRequired } from '../helpers/captchaHelper.js';
async function UIWindowLogin(options){
options = options ?? {};
@@ -40,10 +38,6 @@ async function UIWindowLogin(options){
return new Promise(async (resolve) => {
const internal_id = window.uuidv4();
// Check if captcha is required for login
const captchaRequired = await isCaptchaRequired('login');
console.log('Login captcha required:', captchaRequired);
let h = ``;
h += `<div style="max-width:100%; width:100%; height:100%; min-height:0; box-sizing:border-box; display:flex; flex-direction:column; justify-content:flex-start; align-items:stretch; padding:0; overflow:auto; color:var(--color-text);">`;
// logo
@@ -77,10 +71,6 @@ async function UIWindowLogin(options){
<img class="toggle-show-password-icon" src="${options.show_password ? window.icons["eye-closed.svg"] : window.icons["eye-open.svg"]}" width="20" height="20">
</span>`;
h += `</div>`;
// captcha placeholder - will be replaced with actual captcha component
h += `<div class="captcha-container"></div>`;
// captcha-specific error message
h += `<div class="captcha-error-msg" style="color: #e74c3c; font-size: 12px; margin-top: 5px; display: none;" aria-live="polite"></div>`;
// login
h += `<button type="submit" class="login-btn button button-primary button-block button-normal">${i18n('log_in')}</button>`;
// password recovery
@@ -141,46 +131,6 @@ async function UIWindowLogin(options){
}
})
// Initialize the captcha component with the required state
const captchaContainer = $(el_window).find('.captcha-container')[0];
const captcha = CaptchaView({
container: captchaContainer,
required: captchaRequired,
});
// Function to show captcha-specific error
const showCaptchaError = (message) => {
// Hide the general error message if shown
$(el_window).find('.login-error-msg').hide();
// Show captcha-specific error
const captchaError = $(el_window).find('.captcha-error-msg');
captchaError.html(message);
captchaError.fadeIn();
// Add visual indication of error to captcha container
$(captchaContainer).addClass('error');
$(captchaContainer).css('border', '1px solid #e74c3c');
$(captchaContainer).css('border-radius', '4px');
$(captchaContainer).css('padding', '10px');
// Focus on the captcha input for better UX
setTimeout(() => {
const captchaInput = $(captchaContainer).find('.captcha-input');
if (captchaInput.length) {
captchaInput.focus();
}
}, 100);
};
// Function to clear captcha errors
const clearCaptchaError = () => {
$(el_window).find('.captcha-error-msg').hide();
$(captchaContainer).removeClass('error');
$(captchaContainer).css('border', '');
$(captchaContainer).css('padding', '');
};
$(el_window).find('.forgot-password-link').on('click', function(e){
UIWindowRecoverPassword({
window_options: {
@@ -197,7 +147,6 @@ async function UIWindowLogin(options){
// Clear previous error states
$(el_window).find('.login-error-msg').hide();
clearCaptchaError();
const email_username = $(el_window).find('.email_or_username').val();
const password = $(el_window).find('.password').val();
@@ -215,61 +164,17 @@ async function UIWindowLogin(options){
return;
}
// Get captcha token and answer if required
let captchaToken = null;
let captchaAnswer = null;
if (captcha.isRequired()) {
captchaToken = captcha.getToken();
captchaAnswer = captcha.getAnswer();
// Validate captcha if it's required
if (!captcha || !captchaContainer) {
$(el_window).find('.login-error-msg').html(i18n('captcha_system_error') || 'Verification system error. Please refresh the page.');
$(el_window).find('.login-error-msg').fadeIn();
return;
}
if (!captchaToken) {
showCaptchaError(i18n('captcha_load_error') || 'Could not load verification code. Please refresh the page or try again later.');
return;
}
if (!captchaAnswer) {
showCaptchaError(i18n('captcha_required') || 'Please enter the verification code');
return;
}
if (captchaAnswer.trim().length < 3) {
showCaptchaError(i18n('captcha_too_short') || 'Verification code answer is too short.');
return;
}
if (captchaAnswer.trim().length > 12) {
showCaptchaError(i18n('captcha_too_long') || 'Verification code answer is too long.');
return;
}
}
// Prepare data for the request
let data;
if(window.is_email(email_username)){
data = JSON.stringify({
email: email_username,
password: password,
...(captchaToken && captchaAnswer ? {
captchaToken: captchaToken,
captchaAnswer: captchaAnswer
} : {})
});
} else {
data = JSON.stringify({
username: email_username,
password: password,
...(captchaToken && captchaAnswer ? {
captchaToken: captchaToken,
captchaAnswer: captchaAnswer
} : {})
});
}
@@ -485,31 +390,11 @@ async function UIWindowLogin(options){
// Handle captcha-specific errors
const errorText = err.responseText || '';
const errorStatus = err.status || 0;
// Try to parse error as JSON
try {
const errorJson = JSON.parse(errorText);
// Check for specific error codes
if (errorJson.code === 'captcha_required') {
// If captcha is now required but wasn't before, update the component
if (!captcha.isRequired()) {
captcha.setRequired(true);
showCaptchaError(i18n('captcha_now_required') || 'Verification is now required. Please complete the verification below.');
} else {
showCaptchaError(i18n('captcha_required') || 'Please enter the verification code');
}
return;
}
if (errorJson.code === 'captcha_invalid' || errorJson.code === 'captcha_error') {
showCaptchaError(i18n('captcha_invalid') || 'Invalid verification code');
// Refresh the captcha if it's invalid
captcha.reset();
return;
}
// If it's a message in the JSON, use that
if (errorJson.message) {
$(el_window).find('.login-error-msg').html(errorJson.message);
@@ -520,33 +405,6 @@ async function UIWindowLogin(options){
// Not JSON, continue with text analysis
}
// Check for specific captcha errors using more robust detection for text responses
if (
errorText.includes('captcha_required') ||
errorText.includes('Captcha verification required') ||
(errorText.includes('captcha') && errorText.includes('required'))
) {
// If captcha is now required but wasn't before, update the component
if (!captcha.isRequired()) {
captcha.setRequired(true);
showCaptchaError(i18n('captcha_now_required') || 'Verification is now required. Please complete the verification below.');
} else {
showCaptchaError(i18n('captcha_required') || 'Please enter the verification code');
}
return;
}
if (
errorText.includes('captcha_invalid') ||
errorText.includes('Invalid captcha') ||
(errorText.includes('captcha') && (errorText.includes('invalid') || errorText.includes('incorrect')))
) {
showCaptchaError(i18n('captcha_invalid') || 'Invalid verification code');
// Refresh the captcha if it's invalid
captcha.reset();
return;
}
// Fall back to original error handling
const $errorMessage = $(el_window).find('.login-error-msg');
if (err.status === 404) {

View File

@@ -21,8 +21,6 @@ import UIWindow from './UIWindow.js'
import UIWindowLogin from './UIWindowLogin.js'
import UIWindowEmailConfirmationRequired from './UIWindowEmailConfirmationRequired.js'
import check_password_strength from '../helpers/check_password_strength.js'
import CaptchaView from './Components/CaptchaView.js'
import { isCaptchaRequired } from '../helpers/captchaHelper.js'
function UIWindowSignup(options){
options = options ?? {};
@@ -34,10 +32,6 @@ function UIWindowSignup(options){
return new Promise(async (resolve) => {
const internal_id = window.uuidv4();
// Check if captcha is required for signup
const captchaRequired = await isCaptchaRequired('signup');
console.log('Signup captcha required:', captchaRequired);
let h = '';
h += `<div style="margin: 0 auto; max-width: 500px; min-width: 400px;">`;
// logo
@@ -82,10 +76,6 @@ function UIWindowSignup(options){
<img class="toggle-show-password-icon" src="${options.show_password ? window.icons["eye-closed.svg"] : window.icons["eye-open.svg"]}" width="20" height="20">
</span>`;
h += `</div>`;
// captcha placeholder - will be replaced with actual captcha component
h += `<div class="captcha-container"></div>`;
// captcha-specific error message
h += `<div class="captcha-error-msg" style="color: #e74c3c; font-size: 12px; margin-top: 5px; display: none;" aria-live="polite"></div>`;
// bot trap - if this value is submitted server will ignore the request
h += `<input type="text" name="p102xyzname" class="p102xyzname" value="">`;
@@ -143,13 +133,6 @@ function UIWindowSignup(options){
}
})
// Initialize the captcha component with the required state
const captchaContainer = $(el_window).find('.captcha-container')[0];
const captcha = CaptchaView({
container: captchaContainer,
required: captchaRequired
});
$(el_window).find('.login-c2a-clickable').on('click', async function(e){
$('.login-c2a-clickable').parents('.window').close();
const login = await UIWindowLogin({
@@ -164,43 +147,9 @@ function UIWindowSignup(options){
resolve(true);
})
// Function to show captcha-specific error
const showCaptchaError = (message) => {
// Hide the general error message if shown
$(el_window).find('.signup-error-msg').hide();
// Show captcha-specific error
const captchaError = $(el_window).find('.captcha-error-msg');
captchaError.html(message);
captchaError.fadeIn();
// Add visual indication of error to captcha container
$(captchaContainer).addClass('error');
$(captchaContainer).css('border', '1px solid #e74c3c');
$(captchaContainer).css('border-radius', '4px');
$(captchaContainer).css('padding', '10px');
// Focus on the captcha input for better UX
setTimeout(() => {
const captchaInput = $(captchaContainer).find('.captcha-input');
if (captchaInput.length) {
captchaInput.focus();
}
}, 100);
};
// Function to clear captcha errors
const clearCaptchaError = () => {
$(el_window).find('.captcha-error-msg').hide();
$(captchaContainer).removeClass('error');
$(captchaContainer).css('border', '');
$(captchaContainer).css('padding', '');
};
$(el_window).find('.signup-btn').on('click', function(e){
// Clear previous error states
$(el_window).find('.signup-error-msg').hide();
clearCaptchaError();
//Username
let username = $(el_window).find('.username').val();
@@ -255,46 +204,6 @@ function UIWindowSignup(options){
$(el_window).find('.signup-error-msg').html(i18n('passwords_do_not_match'));
$(el_window).find('.signup-error-msg').fadeIn();
return;
}
// Get captcha token and answer if required
let captchaToken = null;
let captchaAnswer = null;
if (captcha.isRequired()) {
captchaToken = captcha.getToken();
captchaAnswer = captcha.getAnswer();
// Check if the captcha component is properly loaded
if (!captcha || !captchaContainer) {
$(el_window).find('.signup-error-msg').html(i18n('captcha_system_error') || 'Verification system error. Please refresh the page.');
$(el_window).find('.signup-error-msg').fadeIn();
return;
}
// Check if captcha token exists
if (!captchaToken) {
showCaptchaError(i18n('captcha_load_error') || 'Could not load verification code. Please refresh the page or try again later.');
return;
}
// Check if the answer is provided
if (!captchaAnswer) {
showCaptchaError(i18n('captcha_required'));
return;
}
// Check if answer meets minimum length requirement
if (captchaAnswer.trim().length < 3) {
showCaptchaError(i18n('captcha_too_short') || 'Verification code answer is too short.');
return;
}
// Check if answer meets maximum length requirement
if (captchaAnswer.trim().length > 12) {
showCaptchaError(i18n('captcha_too_long') || 'Verification code answer is too long.');
return;
}
}
//xyzname
@@ -316,10 +225,6 @@ function UIWindowSignup(options){
referrer: options.referrer ?? window.referrerStr,
send_confirmation_code: options.send_confirmation_code,
p102xyzname: p102xyzname,
...(captchaToken && captchaAnswer ? {
captchaToken: captchaToken,
captchaAnswer: captchaAnswer
} : {})
};
$.ajax({
@@ -352,32 +257,12 @@ function UIWindowSignup(options){
// Process error response
const errorText = err.responseText || '';
const errorStatus = err.status || 0;
// Handle JSON error response
try {
// Try to parse error as JSON
const errorJson = JSON.parse(errorText);
// Check for specific error codes
if (errorJson.code === 'captcha_required') {
// If captcha is now required but wasn't before, update the component
if (!captcha.isRequired()) {
captcha.setRequired(true);
showCaptchaError(i18n('captcha_now_required') || 'Verification is now required. Please complete the verification below.');
} else {
showCaptchaError(i18n('captcha_required') || 'Please enter the verification code');
}
return;
}
if (errorJson.code === 'captcha_invalid' || errorJson.code === 'captcha_error') {
showCaptchaError(i18n('captcha_invalid') || 'Invalid verification code');
// Refresh the captcha if it's invalid
captcha.reset();
return;
}
// Handle timeout specifically
if (errorJson?.code === 'response_timeout' || errorText.includes('timeout')) {
$(el_window).find('.signup-error-msg').html(i18n('server_timeout') || 'The server took too long to respond. Please try again.');
@@ -394,27 +279,6 @@ function UIWindowSignup(options){
} catch (e) {
// Not JSON, continue with text analysis
}
// Check for specific captcha errors using more robust detection for text responses
if (
errorText.includes('captcha_required') ||
errorText.includes('Captcha verification required') ||
(errorText.includes('captcha') && errorText.includes('required'))
) {
showCaptchaError(i18n('captcha_required'));
return;
}
if (
errorText.includes('captcha_invalid') ||
errorText.includes('Invalid captcha') ||
(errorText.includes('captcha') && (errorText.includes('invalid') || errorText.includes('incorrect')))
) {
showCaptchaError(i18n('captcha_invalid'));
// Refresh the captcha if it's invalid
captcha.reset();
return;
}
// Default general error handling
$(el_window).find('.signup-error-msg').html(errorText || i18n('signup_error') || 'An error occurred during signup. Please try again.');

View File

@@ -1,87 +0,0 @@
/**
* Copyright (C) 2024-present Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Cache for captcha requirements to avoid repeated API calls
*/
let captchaRequirementsCache = null;
/**
* Checks if captcha is required for a specific action
*
* This function first checks GUI parameters, then falls back to the /whoarewe endpoint
*
* @param {string} actionType - The type of action (e.g., 'login', 'signup')
* @returns {Promise<boolean>} - Whether captcha is required for this action
*/
async function isCaptchaRequired(actionType) {
console.log('CAPTCHA DIAGNOSTIC (Client): isCaptchaRequired called for', actionType);
// Check if we have the info in GUI parameters
if (window.gui_params?.captchaRequired?.[actionType] !== undefined) {
console.log(`CAPTCHA DIAGNOSTIC (Client): Requirement for ${actionType} from GUI params:`, window.gui_params.captchaRequired[actionType]);
console.log('CAPTCHA DIAGNOSTIC (Client): Full gui_params.captchaRequired =', JSON.stringify(window.gui_params.captchaRequired));
return window.gui_params.captchaRequired[actionType];
}
// If not in GUI params, check the cache
if (captchaRequirementsCache && captchaRequirementsCache.captchaRequired?.[actionType] !== undefined) {
console.log(`CAPTCHA DIAGNOSTIC (Client): Requirement for ${actionType} from cache:`, captchaRequirementsCache.captchaRequired[actionType]);
console.log('CAPTCHA DIAGNOSTIC (Client): Full cache =', JSON.stringify(captchaRequirementsCache.captchaRequired));
return captchaRequirementsCache.captchaRequired[actionType];
}
// If not in cache, fetch from the /whoarewe endpoint
try {
console.log(`CAPTCHA DIAGNOSTIC (Client): Fetching from /whoarewe for ${actionType}`);
const response = await fetch(window.api_origin + '/whoarewe');
if (!response.ok) {
console.warn(`CAPTCHA DIAGNOSTIC (Client): Failed to get requirements: ${response.status}`);
return true; // Default to requiring captcha if we can't determine
}
const data = await response.json();
console.log(`CAPTCHA DIAGNOSTIC (Client): /whoarewe response:`, data);
// Cache the result
captchaRequirementsCache = data;
// Return the requirement or default to true if not specified
const result = data.captchaRequired?.[actionType] ?? true;
console.log(`CAPTCHA DIAGNOSTIC (Client): Final result for ${actionType}:`, result);
return result;
} catch (error) {
console.error('CAPTCHA DIAGNOSTIC (Client): Error checking requirements:', error);
return true; // Default to requiring captcha on error
}
}
/**
* Invalidates the captcha requirements cache
* This is useful when the requirements might have changed
*/
function invalidateCaptchaRequirementsCache() {
captchaRequirementsCache = null;
}
export {
isCaptchaRequired,
invalidateCaptchaRequirementsCache
};

View File

@@ -417,20 +417,6 @@ const en = {
'billing.expanded': 'Expanded',
'billing.accelerated': 'Accelerated',
'billing.enjoy_msg': 'Enjoy %% of Cloud Storage plus other benefits.',
// Captcha related strings
'captcha_verification': 'Verification Code',
'enter_captcha_text': 'Enter the text you see above',
'refresh_captcha': 'Get a new code',
'captcha_case_sensitive': 'Please enter the characters exactly as they appear. Case sensitive.',
'captcha_required': 'Please complete the verification code.',
'captcha_now_required': 'Verification is now required. Please complete the verification below.',
'captcha_invalid': 'Incorrect verification code. Please try again.',
'captcha_expired': 'Verification code has expired. Please try a new one.',
'captcha_system_error': 'Verification system error. Please refresh the page.',
'captcha_load_error': 'Could not load verification code. Please refresh the page or try again later.',
'captcha_too_short': 'Verification code answer is too short.',
'captcha_too_long': 'Verification code answer is too long.',
'too_many_attempts': 'Too many attempts. Please try again later.',
'server_timeout': 'The server took too long to respond. Please try again.',
'signup_error': 'An error occurred during signup. Please try again.'

View File

@@ -20,8 +20,6 @@
window.puter_gui_enabled = true;
import { isCaptchaRequired } from './helpers/captchaHelper.js';
/**
* Initializes and configures the GUI (Graphical User Interface) settings based on the provided options.
*
@@ -61,18 +59,6 @@ window.gui = async (options) => {
window.disable_temp_users = options.disable_temp_users ?? false;
window.co_isolation_enabled = options.co_isolation_enabled;
// Preload captcha requirements if not already in GUI parameters
if (!options.captchaRequired) {
// Start loading in the background, but don't await
// This way we don't delay the GUI initialization
Promise.all([
isCaptchaRequired('login'),
isCaptchaRequired('signup')
]).catch(err => {
console.warn('Failed to preload captcha requirements:', err);
});
}
// DEV: Load the initgui.js file if we are in development mode
if(!window.gui_env || window.gui_env === "dev"){
await window.loadScript('/sdk/puter.dev.js');