Skip to content

Commit ff1dfa1

Browse files
authored
Merge pull request #4 from manghidev/changes
feat: improve error handling and add fallback for serial generation
2 parents 80af5fb + b812457 commit ff1dfa1

File tree

1 file changed

+124
-13
lines changed

1 file changed

+124
-13
lines changed

js/app.js

Lines changed: 124 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const translations = {
1212
initialMessage: "Haz clic en \"Generar Serial\"",
1313
generating: "Generando...",
1414
errorPrefix: "Error:",
15-
errorMessage: "Asegúrate de que tu navegador soporta Web Crypto API y los valores son válidos.",
15+
errorMessage: "Intenta recargar la página o usa un navegador más reciente.",
1616
copyError: "No se pudo copiar el serial. Por favor, cópialo manualmente.",
1717
generatorTab: "Generar Serial",
1818
decoderTab: "Decodificar Fecha",
@@ -36,7 +36,7 @@ const translations = {
3636
initialMessage: "Click \"Generate Serial\"",
3737
generating: "Generating...",
3838
errorPrefix: "Error:",
39-
errorMessage: "Make sure your browser supports Web Crypto API and the values are valid.",
39+
errorMessage: "Try refreshing the page or use a more recent browser.",
4040
copyError: "Could not copy the serial. Please copy it manually.",
4141
generatorTab: "Generate Serial",
4242
decoderTab: "Decode Date",
@@ -81,6 +81,11 @@ async function generateHighEntropySerialNumber(
8181
totalRandomLength = 24,
8282
prefix = null
8383
) {
84+
// Verificar si Web Crypto API está disponible
85+
if (!window.crypto || !window.crypto.getRandomValues) {
86+
throw new Error('Web Crypto API no está disponible en este navegador');
87+
}
88+
8489
// Validaciones y Ajustes de Parámetros
8590
const validatedSegmentLength = Math.max(1, Math.min(12, segmentLength));
8691
const validatedTotalRandomLength = Math.max(6, Math.min(50, totalRandomLength));
@@ -96,8 +101,13 @@ async function generateHighEntropySerialNumber(
96101

97102
const getSecureRandomByte = () => {
98103
if (byteBufferIndex >= BYTE_BUFFER_SIZE) {
99-
window.crypto.getRandomValues(byteBuffer);
100-
byteBufferIndex = 0;
104+
try {
105+
window.crypto.getRandomValues(byteBuffer);
106+
byteBufferIndex = 0;
107+
} catch (error) {
108+
console.error('Error con getRandomValues:', error);
109+
throw new Error('No se pudieron generar valores aleatorios seguros');
110+
}
101111
}
102112
return byteBuffer[byteBufferIndex++];
103113
};
@@ -142,6 +152,61 @@ async function generateHighEntropySerialNumber(
142152
return finalSerialParts.join('-');
143153
}
144154

155+
// Función de respaldo usando Math.random() si Web Crypto API falla
156+
function generateFallbackSerialNumber(
157+
segmentLength = 6,
158+
totalRandomLength = 24,
159+
prefix = null
160+
) {
161+
console.warn('Usando generador de respaldo con Math.random()');
162+
163+
// Validaciones y Ajustes de Parámetros
164+
const validatedSegmentLength = Math.max(1, Math.min(12, segmentLength));
165+
const validatedTotalRandomLength = Math.max(6, Math.min(50, totalRandomLength));
166+
167+
// Configuración de Caracteres
168+
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
169+
const charsLength = chars.length;
170+
171+
// 1. Generar la Parte de la Marca de Tiempo
172+
const timestampPart = Date.now().toString(36).toUpperCase();
173+
174+
// 2. Generar los Caracteres Aleatorios usando Math.random()
175+
let rawRandomChars = '';
176+
for (let i = 0; i < validatedTotalRandomLength; i++) {
177+
const randomIndex = Math.floor(Math.random() * charsLength);
178+
rawRandomChars += chars[randomIndex];
179+
}
180+
181+
// 3. Formato de la Parte Aleatoria con Guiones
182+
let formattedRandomPart = '';
183+
let currentPos = 0;
184+
185+
while (currentPos < validatedTotalRandomLength) {
186+
const remainingLength = validatedTotalRandomLength - currentPos;
187+
const currentSegmentLength = Math.min(validatedSegmentLength, remainingLength);
188+
189+
formattedRandomPart += rawRandomChars.substring(currentPos, currentPos + currentSegmentLength);
190+
currentPos += currentSegmentLength;
191+
192+
if (currentPos < validatedTotalRandomLength) {
193+
formattedRandomPart += '-';
194+
}
195+
}
196+
197+
// 4. Construir el Serial Final
198+
const finalSerialParts = [];
199+
200+
if (prefix && String(prefix).trim().length > 0) {
201+
finalSerialParts.push(String(prefix).toUpperCase().trim());
202+
}
203+
204+
finalSerialParts.push(timestampPart);
205+
finalSerialParts.push(formattedRandomPart);
206+
207+
return finalSerialParts.join('-');
208+
}
209+
145210
// Función para decodificar la fecha de un serial
146211
function decodeSerialTimestamp(serial) {
147212
if (!serial || typeof serial !== 'string') {
@@ -298,25 +363,59 @@ function updateUI() {
298363

299364
// Función para manejar la generación del serial
300365
async function handleGenerateSerial() {
366+
console.log('handleGenerateSerial called'); // Debug
367+
301368
const t = translations[currentLanguage];
302369
const serialOutput = document.getElementById('serialOutput');
303370
const copyButton = document.getElementById('copyButton');
304371

372+
if (!serialOutput) {
373+
console.error('serialOutput element not found');
374+
return;
375+
}
376+
377+
if (!copyButton) {
378+
console.error('copyButton element not found');
379+
return;
380+
}
381+
305382
serialOutput.textContent = t.generating;
306383
serialOutput.style.color = '#72ef72'; // Resetear color a verde
307384
copyButton.classList.remove('copied'); // Asegurar que el botón de copiar no esté en estado "copiado"
308385
copyButton.textContent = t.copyButton; // Resetear texto del botón de copiar
309386

310387
try {
311-
const segmentLen = parseInt(document.getElementById('segmentLength').value);
312-
const totalRandomLen = parseInt(document.getElementById('totalRandomLength').value);
313-
const prefixVal = document.getElementById('prefix').value.trim();
314-
315-
const generatedSerial = await generateHighEntropySerialNumber(
316-
segmentLen,
317-
totalRandomLen,
318-
prefixVal
319-
);
388+
const segmentLenElement = document.getElementById('segmentLength');
389+
const totalRandomLenElement = document.getElementById('totalRandomLength');
390+
const prefixElement = document.getElementById('prefix');
391+
392+
if (!segmentLenElement || !totalRandomLenElement || !prefixElement) {
393+
throw new Error('No se pudieron encontrar los elementos del formulario');
394+
}
395+
396+
const segmentLen = parseInt(segmentLenElement.value) || 6;
397+
const totalRandomLen = parseInt(totalRandomLenElement.value) || 24;
398+
const prefixVal = prefixElement.value.trim();
399+
400+
console.log('Generating serial with params:', { segmentLen, totalRandomLen, prefixVal }); // Debug
401+
402+
let generatedSerial;
403+
try {
404+
generatedSerial = await generateHighEntropySerialNumber(
405+
segmentLen,
406+
totalRandomLen,
407+
prefixVal
408+
);
409+
} catch (cryptoError) {
410+
console.warn('Web Crypto API falló, usando método de respaldo:', cryptoError);
411+
generatedSerial = generateFallbackSerialNumber(
412+
segmentLen,
413+
totalRandomLen,
414+
prefixVal
415+
);
416+
}
417+
418+
console.log('Generated serial:', generatedSerial); // Debug
320419

321420
currentSerial = generatedSerial;
322421
serialOutput.textContent = generatedSerial;
@@ -351,6 +450,18 @@ function copyToClipboard() {
351450

352451
// Inicialización cuando el DOM esté listo
353452
document.addEventListener('DOMContentLoaded', () => {
453+
console.log('DOM Content Loaded'); // Debug
454+
455+
// Verificar que todos los elementos críticos existan
456+
const requiredElements = ['title', 'generateButton', 'serialOutput', 'copyButton'];
457+
const missingElements = requiredElements.filter(id => !document.getElementById(id));
458+
459+
if (missingElements.length > 0) {
460+
console.error('Elementos críticos faltantes:', missingElements);
461+
alert('Error: La página no se cargó correctamente. Elementos faltantes: ' + missingElements.join(', '));
462+
return;
463+
}
464+
354465
// Cargar preferencias del localStorage
355466
const savedLanguage = localStorage.getItem('preferredLanguage') || 'en-US';
356467
const savedTab = localStorage.getItem('preferredTab') || 'generator';

0 commit comments

Comments
 (0)