El instalador exigía root o `sudo -n` (NOPASSWD), así que una cuenta con sudo
CON contraseña —el caso de los servidores Linux— no podía actualizarse desde el
panel. La contraseña guardada no ayudaba: se usa para autenticar SSH y a sudo
nunca se le entrega, por decisión de diseño contra el antipatrón de AServers
(`echo '{password}' | sudo -S`, que expone el secreto en argv).
En vez de rodear esa decisión, se quita la necesidad de privilegios. El agente
no necesita root para funcionar: su unit corre como el usuario que instala, y
las rutas de data_folder las escribe SQL Server, no él. install.sh solo pedía
privilegios por dos razones circunstanciales — el PREFIX por omisión en /opt y
el unit en /etc/systemd/system.
Modo nuevo `--user-service`: instala bajo el home y registra un unit de systemd
de usuario. Para sobrevivir al cierre de sesión intenta lingering y, si el
destino no lo permite, cae a @reboot en el crontab del usuario más un vigilante
cada 5 min que sustituye al Restart=always. Con eso, al panel le bastan el
usuario y la contraseña que ya tiene registrados.
Además, la sonda de elevación pasa a ser compartida entre instalar y verificar
(antes eran copias paralelas que ya diferían en la etiqueta) y distingue casos
que se reportaban idénticos:
- `requiretty` en el sudoers ya no se confunde con "sin privilegios": el remedio
es el opuesto, porque agregar NOPASSWD no lo arregla.
- Una regla NOPASSWD acotada a otros comandos se reporta como tal, con la lista.
- Verificar informa si la ruta es escribible y si la instalación sin privilegios
es viable en ese servidor, en vez de solo decir que faltan permisos.
Dos bugs encontrados al probarlo, ambos con prueba:
- `pgrep -f <ruta>` hacía match consigo mismo, porque la propia línea de cron
del vigilante contiene esa ruta. Sin el ancla `^`, el vigilante creía que el
agente corría y no lo rearrancaba nunca.
- `expectedStepCount` comparaba solo con 'service', así que la barra de una
instalación en modo usuario habría llegado al 100 % con un paso pendiente.
`resolveLinuxPrivilege` no tenía ninguna prueba; se agregan seis.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
isInsideWorkFolder miraba la relación en los dos sentidos, así que también
rechazaba que las carpetas de trabajo colgaran de la de instalación. Ese es el
layout NORMAL, no un error: constants.py del agente define
DIR_ENTRADA = APP_DIR / "Entrada", así que una instalación correcta en
/opt/cloudrestoreas reporta input_folder = /opt/cloudrestoreas/Entrada.
Efecto: ninguna instalación ni actualización podía pasar, en Linux ni en
Windows. Fallaba en resolveInstallPath —antes de abrir el run, así que no
quedaba nada en la bitácora— con un mensaje que decía justo lo contrario de lo
que ocurría: "la ruta está dentro de una carpeta de trabajo". Solo se libraban
las instalaciones fuera de la ruta por omisión, por accidente del nombre.
Se conserva el peligro que el guard existe para atajar: el binario dentro de
Entrada/Procesados, donde el agente lo tomaría por un respaldo a procesar.
La función no tenía ninguna prueba. Se agregan las dos direcciones, el caso
exacto, la normalización de separador/caja/barra final y el prefijo que no es
de carpeta (/srv/entradas vs /srv/entrada).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Un agente anterior a 1.1.0 no reporta su install_path, así que el panel caía al
default de plataforma y ACTUALIZAR abortaba cuando la instalación vivía en otra
carpeta (p. ej. C:\Aduanasoft\CloudRestoreAS-win). Era un huevo-y-gallina: la
ruta se empieza a reportar en 1.1.x, que es justo lo que no se podía instalar.
Se agrega la captura manual de la ruta por servidor. No hace falta esquema nuevo
ni lógica de resolución nueva: el upsert del estado ya usa
install_path = COALESCE(EXCLUDED.install_path, actual), así que el valor
capturado sobrevive los reportes sin ruta del agente viejo, y resolveInstallPath
y cras-verify ya leen esa misma columna. Cuando el servidor quede en 1.1.x su
propio reporte lo sustituye por la ruta real.
De paso, dos fallos de configuración que costaron el diagnóstico:
- GITEA_TOKEN con los `<>` de la plantilla se veía como un 401 opaco de Gitea,
idéntico al de un token revocado. Se valida la forma antes de llamar, el
aviso sale al cargar la pantalla y 401 y 403 dejan de colapsar al mismo
texto. Un rechazo ahora deja línea en los logs: no dejaba ninguna.
- PANEL_PUBLIC_URL sin el puerto apuntaba a otro servicio. Esa URL se siembra
en el config/.env del destino también al ACTUALIZAR, así que rompería un
agente que ya reportaba: se avisa y se aborta antes de tocar el servidor.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nuevo parametro anexo24c_cambio_sistema por nodo, editable desde el modal
de Gestion de Bases de Datos (checkbox "Presento aviso de cambio de sistema
(Anexo 24C)"). Solo cuando esta marcado Y el cliente esta inactivo, el login
de SCAII Web muestra la leyenda del SAT; el campo de fecha se habilita solo
si el checkbox esta activo.
- controldesk-pg.ts: anexo24c_cambio_sistema en ROW_DATABASE_NODE, insert y update.
- +page.server.ts: parseo del campo en createDatabase / updateDatabase.
- +page.svelte: checkbox en el modal + fecha condicionada al checkbox.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewed-on: #18
Co-authored-by: Galindo97 <agalindo@aduanasoft.com.mx>
Co-committed-by: Galindo97 <agalindo@aduanasoft.com.mx>
- Updated the alert handling logic to include a 'notFound' flag for databases that are not found on the server, allowing for clearer UI representation.
- Enriched alert data with client contact information by integrating the `lookupAlertClientData` function, ensuring alerts display relevant client details.
- Improved the display of alert dates in the UI to reflect the new 'notFound' status, enhancing user experience and clarity.
This update improves the accuracy and usability of the dashboard alerts.
Reviewed-on: #16
Co-authored-by: AlexeerCT <acazares@aduanasoft.com.mx>
Co-committed-by: AlexeerCT <acazares@aduanasoft.com.mx>
- Added new environment variables for deduplication and SQL Server password encryption.
- Updated docker-compose files to include SECRET_KEY and ENCRYPTION_KEY for compatibility with a24c.
- Enhanced the navigation structure to reflect changes in admin-only views and report access.
- Introduced new functions for handling SQL Server connections and database management, including parsing server addresses and listing user databases.
This update improves security and functionality related to database management and user access control.
Reviewed-on: #15
Co-authored-by: AlexeerCT <acazares@aduanasoft.com.mx>
Co-committed-by: AlexeerCT <acazares@aduanasoft.com.mx>
integraciones de panel de respaldos fallidos, asignacion masiva de restaurador, trackeo de baks para nuevo sistema de cloudrestore
Reviewed-on: #13
Co-authored-by: hreyes <hreyes@aduanasoft.com.mx>
Co-committed-by: hreyes <hreyes@aduanasoft.com.mx>
- Introduced new functions to download Excel reports for clients and users.
- Added UI elements for administrative users to trigger report downloads.
- Implemented error handling for report generation failures.
- Enhanced the existing portal user listing with node data for better reporting.
This update improves the reporting capabilities within the application, allowing for easier access to client and user data.
Reviewed-on: #12
Co-authored-by: AlexeerCT <acazares@aduanasoft.com.mx>
Co-committed-by: AlexeerCT <acazares@aduanasoft.com.mx>
La carga inicial del dashboard (/+page.server.ts) tardaba ~30s porque
loadSqlDashboardFromNodes recorría los nodos en serie y hacía 3 round-trips
secuenciales por nodo (métricas, alerta, historial) → N×3 viajes encadenados
a SQL Server remoto.
Cambios:
- Las 3 consultas por nodo ahora corren con Promise.all.
- Los nodos se procesan con concurrencia acotada (8) vía mapWithConcurrency;
la agregación se mantiene secuencial para conservar orden y evitar carreras.
- getMssqlPoolMaster cachea la *promesa* del pool y reserva el slot de forma
síncrona antes de cualquier await, evitando pools duplicados al paralelizar.
- En +page.server.ts: métricas SQL Server y catálogo PostgreSQL se cargan en
paralelo (Promise.allSettled); las 6 consultas de catálogo en Promise.all.
- Se elimina la consulta listDatabaseNodes() duplicada (se reusa la ya cargada).
- Hidratación de alertas y filtro de permisos paralelizados.
- Se quita un console.log de depuración por fila (estándar: sin logs sueltos).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewed-on: #11
Co-authored-by: AlexeerCT <acazares@aduanasoft.com.mx>
Co-committed-by: AlexeerCT <acazares@aduanasoft.com.mx>
togglePermission confiaba solo en res.ok de un fetch sin use:enhance, así que
ocultaba el fail(500) del action y pintaba "Con Acceso" en falso aunque el
INSERT tronara (42P10 por falta de UNIQUE en a24c).
- togglePermission: manda x-sveltekit-action, deserializa el ActionResult,
valida type === 'success', relee del servidor y muestra error si falla
- GET de permisos: cache-control no-store para evitar lecturas viejas
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewed-on: #10
Co-authored-by: AlexeerCT <acazares@aduanasoft.com.mx>
Co-committed-by: AlexeerCT <acazares@aduanasoft.com.mx>
- Updated the certificate and private key files with new content.
- Added additional Bash commands for OpenSSL operations to settings.local.json for enhanced functionality.
- Introduced a default database server address for improved user experience when creating database entries.
- Added a function to handle unique user violation messages for better error reporting.
- Updated form validation to require fewer fields, streamlining user input.
- Enhanced error handling in fetch requests to provide clearer feedback on server responses.
- Refactored database-related form handling to ensure consistent use of the default server address.
- Enhanced the backup server route to support streaming of large backup files using Node.js streams.
- Improved error handling for file access and added appropriate HTTP responses for missing parameters and inaccessible files.
- Updated response headers to include content length and type for better client handling.
- Added checks to ensure only regular files are processed in both the main and backup server routes.
- Improved error handling for invalid file parameters and inaccessible backup files, returning appropriate HTTP responses.
- Introduced fixed viewport height for tables to improve scrolling behavior.
- Added new state variables for managing visible rows in various tables.
- Implemented functions to dynamically fill scrollable areas until overflow.
- Updated effects to adjust visible rows based on active view, enhancing user experience.
- Refactored pagination logic to utilize visible row count instead of page numbers.
- Updated .env.example to consolidate SQL Server credentials under PANEL_MSSQL_* variables.
- Removed deprecated docker-compose.postgres.yml file.
- Adjusted docker-compose.yml to utilize new SQL Server credential structure.
- Enhanced README.md with Docker build and push instructions.
- Refined database schema in schema.sql to align with new user and permission structures.
- Updated init-database.js to reflect changes in user and session table names.
- Modified user management functions in users.ts to accommodate new database schema.
- Streamlined API routes to utilize PostgreSQL for user and database management.
- Improved error handling and logging in various server routes.
- Agregada configuración de servidor HTTPS con Express (server.js)
- Integración de PostgreSQL en docker-compose.yml con servicio dedicado
- Actualizado Dockerfile para optimizar build en Alpine Linux
- Configurado vite.config.ts con soporte HTTPS para desarrollo
- Agregados certificados SSL para HTTPS
- Actualizado svelte.config.js con configuración CSRF
- Ajustadas métricas de restauración en +page.server.ts para usar last_restore_date
- Agregado script npm start en package.json
- Instalado express como dependencia de producción
- Increased all sidebar navigation icons from text-sm to text-xl for better visibility
- Moved user information and logout button from header to sidebar footer
- Added user avatar with name and email in expanded sidebar state
- Collapsed sidebar shows avatar icon and logout icon button stacked vertically
- Simplified header by removing user badge and logout button
- Added version info (v1.0.0) in sidebar footer
- Improved responsive design for both collapsed and expanded states