From a02d7956cabaa64f584f484f8cd28964ea4c71a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:05:26 +0000 Subject: [PATCH 1/8] Initial plan From c2eac955fe318b87128437563673116fddeb69ee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:09:54 +0000 Subject: [PATCH 2/8] Implement onboarding flow with database config and admin persona creation Co-authored-by: naielv <109038805+naielv@users.noreply.github.com> --- src/page/login.js | 172 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/src/page/login.js b/src/page/login.js index 80bce35..a070335 100644 --- a/src/page/login.js +++ b/src/page/login.js @@ -1,7 +1,169 @@ PAGES.login = { Esconder: true, Title: "Login", + onboarding: function (step) { + // Multi-step onboarding flow + step = step || 'config'; + + if (step === 'config') { + // Step 1: "Configuraci贸n de datos" + var field_couch = safeuuid(); + var field_couch_dbname = safeuuid(); + var field_couch_user = safeuuid(); + var field_couch_pass = safeuuid(); + var field_secret = safeuuid(); + var btn_existing_server = safeuuid(); + var btn_new_server = safeuuid(); + var btn_skip = safeuuid(); + var div_server_config = safeuuid(); + + container.innerHTML = ` +

隆Bienvenido a TeleSec! 馃帀

+

Paso 1: Configuraci贸n de datos

+

Para comenzar, elige c贸mo quieres configurar tu base de datos:

+
+ + + +
+ + `; + + document.getElementById(btn_existing_server).onclick = () => { + document.getElementById(div_server_config).style.display = 'block'; + }; + + document.getElementById(btn_new_server).onclick = () => { + window.open('https://tech.eus/telesec-signup.php', '_blank'); + toastr.info('Una vez creado el servidor, vuelve aqu铆 y con茅ctate usando el bot贸n "Conectar a un servidor existente"'); + }; + + document.getElementById(btn_skip).onclick = () => { + // Continue to persona creation without server config + location.hash = '#login,onboarding-persona'; + }; + + document.getElementById(btn_skip + '-save').onclick = () => { + var url = document.getElementById(field_couch).value.trim(); + var dbname = document.getElementById(field_couch_dbname).value.trim(); + var user = document.getElementById(field_couch_user).value.trim(); + var pass = document.getElementById(field_couch_pass).value; + var secret = document.getElementById(field_secret).value || ''; + + if (!url) { + toastr.error('Por favor ingresa un servidor CouchDB'); + return; + } + + localStorage.setItem('TELESEC_COUCH_URL', 'https://' + url); + localStorage.setItem('TELESEC_COUCH_DBNAME', dbname); + localStorage.setItem('TELESEC_COUCH_USER', user); + localStorage.setItem('TELESEC_COUCH_PASS', pass); + if (secret) { + localStorage.setItem('TELESEC_SECRET', secret.toUpperCase()); + SECRET = secret.toUpperCase(); + } + + try { + DB.init({ secret: SECRET, remoteServer: 'https://' + url, username: user, password: pass, dbname: dbname || undefined }); + toastr.success('Servidor configurado correctamente'); + // Continue to persona creation + setTimeout(() => { + location.hash = '#login,onboarding-persona'; + }, 500); + } catch (e) { + toastr.error('Error al configurar el servidor: ' + (e.message || e)); + } + }; + + } else if (step === 'persona') { + // Step 2: "Crea una persona" + var field_nombre = safeuuid(); + var btn_crear = safeuuid(); + + container.innerHTML = ` +

隆Bienvenido a TeleSec! 馃帀

+

Paso 2: Crea tu cuenta de administrador

+

Para continuar, necesitas crear una cuenta personal con permisos de administrador.

+
+ +

鈩癸笍 Esta cuenta tendr谩 todos los permisos de administrador y podr谩s gestionar la aplicaci贸n completamente.

+ +
+ `; + + document.getElementById(btn_crear).onclick = () => { + var nombre = document.getElementById(field_nombre).value.trim(); + if (!nombre) { + toastr.error('Por favor ingresa tu nombre'); + return; + } + + // Create persona with all admin permissions from PERMS object + var allPerms = Object.keys(PERMS).join(',') + ','; + var personaId = 'admin-' + Date.now(); + var persona = { + Nombre: nombre, + Roles: allPerms, + Region: '', + Monedero_Balance: 0, + markdown: 'Cuenta de administrador creada durante el onboarding' + }; + + DB.put('personas', personaId, persona).then(() => { + toastr.success('隆Cuenta creada exitosamente! 馃帀'); + localStorage.setItem('TELESEC_ONBOARDING_COMPLETE', 'true'); + localStorage.setItem('TELESEC_ADMIN_ID', personaId); + + // Auto-login + SUB_LOGGED_IN_ID = personaId; + SUB_LOGGED_IN_DETAILS = persona; + SUB_LOGGED_IN = true; + SetPages(); + + setTimeout(() => { + location.hash = '#index'; + location.reload(); + }, 800); + }).catch((e) => { + toastr.error('Error creando cuenta: ' + (e.message || e)); + }); + }; + } + }, edit: function (mid) { + // Handle onboarding routes + if (mid === 'onboarding-config') { + PAGES.login.onboarding('config'); + return; + } + if (mid === 'onboarding-persona') { + PAGES.login.onboarding('persona'); + return; + } + // Setup form to configure CouchDB remote and initial group/secret var field_couch = safeuuid(); var field_couch_dbname = safeuuid(); @@ -189,6 +351,16 @@ PAGES.login = { }; }, index: function (mid) { + // Check if onboarding is needed + var onboardingComplete = localStorage.getItem('TELESEC_ONBOARDING_COMPLETE'); + var hasPersonas = Object.keys(SC_Personas).length > 0; + + // If no personas exist and onboarding not complete, redirect to onboarding + if (!hasPersonas && !onboardingComplete && !AC_BYPASS) { + location.hash = '#login,onboarding-config'; + return; + } + var field_persona = safeuuid(); var btn_guardar = safeuuid(); var btn_reload = safeuuid(); From bf9ba4ceef0538ac8f1e995d668cb1e52a19c5b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:12:11 +0000 Subject: [PATCH 3/8] Improve onboarding: use safeuuid() and avoid unnecessary reload Co-authored-by: naielv <109038805+naielv@users.noreply.github.com> --- src/page/login.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/page/login.js b/src/page/login.js index a070335..76dd390 100644 --- a/src/page/login.js +++ b/src/page/login.js @@ -123,7 +123,7 @@ PAGES.login = { // Create persona with all admin permissions from PERMS object var allPerms = Object.keys(PERMS).join(',') + ','; - var personaId = 'admin-' + Date.now(); + var personaId = safeuuid('admin-'); var persona = { Nombre: nombre, Roles: allPerms, @@ -144,9 +144,9 @@ PAGES.login = { SetPages(); setTimeout(() => { - location.hash = '#index'; - location.reload(); - }, 800); + open_page('index'); + setUrlHash('index'); + }, 500); }).catch((e) => { toastr.error('Error creando cuenta: ' + (e.message || e)); }); From 1e5de2c686217b884acff82c87abe4f902c6841e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:13:53 +0000 Subject: [PATCH 4/8] Use open_page() consistently for proper navigation cleanup Co-authored-by: naielv <109038805+naielv@users.noreply.github.com> --- src/page/login.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/page/login.js b/src/page/login.js index 76dd390..545eac1 100644 --- a/src/page/login.js +++ b/src/page/login.js @@ -60,7 +60,8 @@ PAGES.login = { document.getElementById(btn_skip).onclick = () => { // Continue to persona creation without server config - location.hash = '#login,onboarding-persona'; + open_page('login,onboarding-persona'); + setUrlHash('login,onboarding-persona'); }; document.getElementById(btn_skip + '-save').onclick = () => { @@ -89,7 +90,8 @@ PAGES.login = { toastr.success('Servidor configurado correctamente'); // Continue to persona creation setTimeout(() => { - location.hash = '#login,onboarding-persona'; + open_page('login,onboarding-persona'); + setUrlHash('login,onboarding-persona'); }, 500); } catch (e) { toastr.error('Error al configurar el servidor: ' + (e.message || e)); @@ -357,7 +359,8 @@ PAGES.login = { // If no personas exist and onboarding not complete, redirect to onboarding if (!hasPersonas && !onboardingComplete && !AC_BYPASS) { - location.hash = '#login,onboarding-config'; + open_page('login,onboarding-config'); + setUrlHash('login,onboarding-config'); return; } From f472baacf60ee5172b77e1b4c43e915cf8e254c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:15:34 +0000 Subject: [PATCH 5/8] Fix URL protocol handling to support both HTTP and HTTPS Co-authored-by: naielv <109038805+naielv@users.noreply.github.com> --- src/page/login.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/page/login.js b/src/page/login.js index 545eac1..b0fb40b 100644 --- a/src/page/login.js +++ b/src/page/login.js @@ -76,7 +76,13 @@ PAGES.login = { return; } - localStorage.setItem('TELESEC_COUCH_URL', 'https://' + url); + // Normalize URL: add https:// if no protocol specified + var normalizedUrl = url; + if (!/^https?:\/\//i.test(url)) { + normalizedUrl = 'https://' + url; + } + + localStorage.setItem('TELESEC_COUCH_URL', normalizedUrl); localStorage.setItem('TELESEC_COUCH_DBNAME', dbname); localStorage.setItem('TELESEC_COUCH_USER', user); localStorage.setItem('TELESEC_COUCH_PASS', pass); @@ -86,7 +92,7 @@ PAGES.login = { } try { - DB.init({ secret: SECRET, remoteServer: 'https://' + url, username: user, password: pass, dbname: dbname || undefined }); + DB.init({ secret: SECRET, remoteServer: normalizedUrl, username: user, password: pass, dbname: dbname || undefined }); toastr.success('Servidor configurado correctamente'); // Continue to persona creation setTimeout(() => { From d6809e51d1832f393420682b60f11abfc05ffc97 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 15:09:00 +0000 Subject: [PATCH 6/8] Fix infinite recursion by allowing onboarding routes without login Co-authored-by: naielv <109038805+naielv@users.noreply.github.com> --- src/app_logic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app_logic.js b/src/app_logic.js index 0f0c56d..07744be 100644 --- a/src/app_logic.js +++ b/src/app_logic.js @@ -20,7 +20,7 @@ function open_page(params) { EventListeners.Custom.forEach(ev => ev()); EventListeners.Custom = []; - if (SUB_LOGGED_IN != true && params != "login,setup") { + if (SUB_LOGGED_IN != true && params != "login,setup" && !params.startsWith("login,onboarding")) { PAGES["login"].index(); return; } From b0160b3b66babc0632a8f47743a10dfa56827630 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 15:20:00 +0000 Subject: [PATCH 7/8] Add button disable, persona detection, and mandatory encryption password Co-authored-by: naielv <109038805+naielv@users.noreply.github.com> --- src/page/login.js | 71 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/src/page/login.js b/src/page/login.js index b0fb40b..b229a91 100644 --- a/src/page/login.js +++ b/src/page/login.js @@ -41,8 +41,8 @@ PAGES.login = { -