Compare commits
4 Commits
058e4781e6
...
6442251c2d
| Author | SHA1 | Date | |
|---|---|---|---|
| 6442251c2d | |||
| 03fc92b3fc | |||
| 400f677666 | |||
| aa41c7dd75 |
13
Cargo.lock
generated
13
Cargo.lock
generated
@@ -1350,6 +1350,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1711,6 +1712,18 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.4",
|
||||||
|
"js-sys",
|
||||||
|
"serde_core",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sysinfo = "0.30"
|
sysinfo = "0.30"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
uuid = { version = "1.0", features = ["v4", "serde"] }
|
||||||
tower-http = { version = "0.5", features = ["cors"] }
|
tower-http = { version = "0.5", features = ["cors"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use axum::{
|
|||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use sysinfo::System;
|
use sysinfo::System;
|
||||||
|
use uuid::Uuid;
|
||||||
use crate::orchestrator::{AppManager, LifecycleManager};
|
use crate::orchestrator::{AppManager, LifecycleManager};
|
||||||
use crate::models::{ServiceConfig, RestartPolicy, AppType};
|
use crate::models::{ServiceConfig, RestartPolicy, AppType};
|
||||||
use super::dto::*;
|
use super::dto::*;
|
||||||
@@ -158,11 +159,9 @@ pub async fn update_app_handler(
|
|||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| "production".to_string());
|
.unwrap_or_else(|| "production".to_string());
|
||||||
|
|
||||||
// Primero intentar hacer soft delete de la app anterior
|
// Actualizar la app existente (sin crear duplicados)
|
||||||
let _ = config_manager.soft_delete_app(&app_name, Some("Actualizada - versión anterior".to_string()));
|
let updated_app = crate::config::MonitoredApp {
|
||||||
|
id: String::new(), // Se preservará el ID original
|
||||||
// Luego agregar la nueva configuración
|
|
||||||
let monitored_app = crate::config::MonitoredApp {
|
|
||||||
name: config.app_name.clone(),
|
name: config.app_name.clone(),
|
||||||
service_name: service_name.clone(),
|
service_name: service_name.clone(),
|
||||||
path: config.working_directory.clone(),
|
path: config.working_directory.clone(),
|
||||||
@@ -172,7 +171,7 @@ pub async fn update_app_handler(
|
|||||||
mode,
|
mode,
|
||||||
user: config.user.clone(),
|
user: config.user.clone(),
|
||||||
service_file_path,
|
service_file_path,
|
||||||
registered_at: chrono::Local::now().to_rfc3339(),
|
registered_at: String::new(), // Se preservará la fecha original
|
||||||
deleted: false,
|
deleted: false,
|
||||||
deleted_at: None,
|
deleted_at: None,
|
||||||
deleted_reason: None,
|
deleted_reason: None,
|
||||||
@@ -181,7 +180,7 @@ pub async fn update_app_handler(
|
|||||||
created_at: None,
|
created_at: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match config_manager.add_app_full(monitored_app) {
|
match config_manager.update_app(&app_name, updated_app) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
logger.info("API", "✅ JSON actualizado");
|
logger.info("API", "✅ JSON actualizado");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,15 @@ use serde::{Serialize, Deserialize};
|
|||||||
use std::fs::{self, create_dir_all};
|
use std::fs::{self, create_dir_all};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, RwLock, OnceLock};
|
use std::sync::{Arc, RwLock, OnceLock};
|
||||||
|
use uuid::Uuid;
|
||||||
use crate::logger::get_logger;
|
use crate::logger::get_logger;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct MonitoredApp {
|
pub struct MonitoredApp {
|
||||||
|
/// ID único de la aplicación (UUID v4)
|
||||||
|
#[serde(default = "generate_uuid")]
|
||||||
|
pub id: String,
|
||||||
|
|
||||||
/// Nombre de la aplicación
|
/// Nombre de la aplicación
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
@@ -70,6 +75,10 @@ pub struct MonitoredApp {
|
|||||||
pub created_at: Option<String>,
|
pub created_at: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_uuid() -> String {
|
||||||
|
Uuid::new_v4().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
fn default_mode() -> String {
|
fn default_mode() -> String {
|
||||||
"production".to_string()
|
"production".to_string()
|
||||||
}
|
}
|
||||||
@@ -186,14 +195,20 @@ impl ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Agrega una app con información completa
|
/// Agrega una app con información completa
|
||||||
pub fn add_app_full(&self, app: MonitoredApp) -> Result<(), String> {
|
pub fn add_app_full(&self, mut app: MonitoredApp) -> Result<(), String> {
|
||||||
let mut config = self.config.write().unwrap();
|
let mut config = self.config.write().unwrap();
|
||||||
|
|
||||||
// Verificar si ya existe
|
// Verificar si ya existe una app ACTIVA con el mismo nombre
|
||||||
if config.apps.iter().any(|a| a.name == app.name) {
|
// (las apps eliminadas no cuentan, pueden tener el mismo nombre)
|
||||||
|
if config.apps.iter().any(|a| a.name == app.name && !a.deleted) {
|
||||||
return Err(format!("La app '{}' ya está siendo monitoreada", app.name));
|
return Err(format!("La app '{}' ya está siendo monitoreada", app.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Asegurar que tenga un UUID único
|
||||||
|
if app.id.is_empty() {
|
||||||
|
app.id = Uuid::new_v4().to_string();
|
||||||
|
}
|
||||||
|
|
||||||
config.apps.push(app);
|
config.apps.push(app);
|
||||||
|
|
||||||
// Guardar en disco
|
// Guardar en disco
|
||||||
@@ -210,6 +225,7 @@ impl ConfigManager {
|
|||||||
let registered_at = chrono::Local::now().to_rfc3339();
|
let registered_at = chrono::Local::now().to_rfc3339();
|
||||||
|
|
||||||
let app = MonitoredApp {
|
let app = MonitoredApp {
|
||||||
|
id: Uuid::new_v4().to_string(),
|
||||||
name,
|
name,
|
||||||
service_name,
|
service_name,
|
||||||
path: String::new(),
|
path: String::new(),
|
||||||
@@ -231,6 +247,45 @@ impl ConfigManager {
|
|||||||
self.add_app_full(app)
|
self.add_app_full(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Actualiza una app existente (sin crear duplicados)
|
||||||
|
pub fn update_app(&self, name: &str, updated_app: MonitoredApp) -> Result<(), String> {
|
||||||
|
let mut config = self.config.write().unwrap();
|
||||||
|
|
||||||
|
// Buscar la app activa con ese nombre
|
||||||
|
let app = config.apps.iter_mut().find(|a| a.name == name && !a.deleted);
|
||||||
|
|
||||||
|
match app {
|
||||||
|
Some(app) => {
|
||||||
|
// Preservar el ID original y la fecha de registro
|
||||||
|
let original_id = app.id.clone();
|
||||||
|
let original_registered_at = app.registered_at.clone();
|
||||||
|
|
||||||
|
// Actualizar todos los campos
|
||||||
|
app.name = updated_app.name;
|
||||||
|
app.service_name = updated_app.service_name;
|
||||||
|
app.path = updated_app.path;
|
||||||
|
app.port = updated_app.port;
|
||||||
|
app.entry_point = updated_app.entry_point;
|
||||||
|
app.node_bin = updated_app.node_bin;
|
||||||
|
app.mode = updated_app.mode;
|
||||||
|
app.user = updated_app.user;
|
||||||
|
app.service_file_path = updated_app.service_file_path;
|
||||||
|
app.environment = updated_app.environment;
|
||||||
|
|
||||||
|
// Mantener el ID original y fecha de registro
|
||||||
|
app.id = original_id;
|
||||||
|
app.registered_at = original_registered_at;
|
||||||
|
|
||||||
|
// Guardar en disco
|
||||||
|
match Self::save_config_to_file(&self.config_path, &config) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(format!("Error al guardar configuración: {}", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Err(format!("La app '{}' no se encontró", name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Realiza un soft delete: marca la app como eliminada pero mantiene el registro
|
/// Realiza un soft delete: marca la app como eliminada pero mantiene el registro
|
||||||
pub fn soft_delete_app(&self, name: &str, reason: Option<String>) -> Result<(), String> {
|
pub fn soft_delete_app(&self, name: &str, reason: Option<String>) -> Result<(), String> {
|
||||||
let mut config = self.config.write().unwrap();
|
let mut config = self.config.write().unwrap();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/// Módulo para descubrir servicios systemd existentes
|
/// Módulo para descubrir servicios systemd existentes
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use uuid::Uuid;
|
||||||
use crate::logger::get_logger;
|
use crate::logger::get_logger;
|
||||||
use crate::config::{get_config_manager, MonitoredApp};
|
use crate::config::{get_config_manager, MonitoredApp};
|
||||||
|
|
||||||
@@ -232,7 +233,8 @@ pub fn sync_discovered_services(services: Vec<DiscoveredService>) {
|
|||||||
detect_port_from_name(&service.app_name)
|
detect_port_from_name(&service.app_name)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verificar si ya existe en la configuración
|
// Verificar si ya existe una app ACTIVA en la configuración
|
||||||
|
// (get_apps() ya filtra las eliminadas, así que esto está bien)
|
||||||
let existing_apps = config_manager.get_apps();
|
let existing_apps = config_manager.get_apps();
|
||||||
let already_exists = existing_apps.iter().any(|app| app.name == service.app_name);
|
let already_exists = existing_apps.iter().any(|app| app.name == service.app_name);
|
||||||
|
|
||||||
@@ -248,6 +250,7 @@ pub fn sync_discovered_services(services: Vec<DiscoveredService>) {
|
|||||||
let registered_at = chrono::Local::now().to_rfc3339();
|
let registered_at = chrono::Local::now().to_rfc3339();
|
||||||
|
|
||||||
let app = MonitoredApp {
|
let app = MonitoredApp {
|
||||||
|
id: Uuid::new_v4().to_string(),
|
||||||
name: service.app_name.clone(),
|
name: service.app_name.clone(),
|
||||||
service_name,
|
service_name,
|
||||||
path: service.working_directory.unwrap_or_default(),
|
path: service.working_directory.unwrap_or_default(),
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ pub fn create_web_router() -> Router {
|
|||||||
.route("/clear-logs", post(clear_logs_handler))
|
.route("/clear-logs", post(clear_logs_handler))
|
||||||
.route("/health", get(health_handler))
|
.route("/health", get(health_handler))
|
||||||
.route("/api-docs", get(api_docs_handler))
|
.route("/api-docs", get(api_docs_handler))
|
||||||
|
.route("/terms", get(terms_handler))
|
||||||
|
.route("/privacy", get(privacy_handler))
|
||||||
.route("/install.sh", get(install_script_handler))
|
.route("/install.sh", get(install_script_handler))
|
||||||
// Archivos estáticos embebidos
|
// Archivos estáticos embebidos
|
||||||
.route("/static/icon/logo_telco128.png", get(logo_telco_handler))
|
.route("/static/icon/logo_telco128.png", get(logo_telco_handler))
|
||||||
@@ -138,6 +140,14 @@ async fn health_handler() -> Html<String> {
|
|||||||
Html(template.to_string())
|
Html(template.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn terms_handler() -> Html<&'static str> {
|
||||||
|
Html(include_str!("../web/terms.html"))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn privacy_handler() -> Html<&'static str> {
|
||||||
|
Html(include_str!("../web/privacy.html"))
|
||||||
|
}
|
||||||
|
|
||||||
async fn install_script_handler() -> ([(String, String); 2], String) {
|
async fn install_script_handler() -> ([(String, String); 2], String) {
|
||||||
let script = include_str!("../install-remote.sh");
|
let script = include_str!("../install-remote.sh");
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::logger::get_logger;
|
|||||||
use crate::config::{get_config_manager, MonitoredApp};
|
use crate::config::{get_config_manager, MonitoredApp};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub struct AppManager {
|
pub struct AppManager {
|
||||||
apps: Arc<DashMap<String, ServiceConfig>>,
|
apps: Arc<DashMap<String, ServiceConfig>>,
|
||||||
@@ -79,6 +80,7 @@ impl AppManager {
|
|||||||
.unwrap_or_else(|| "production".to_string());
|
.unwrap_or_else(|| "production".to_string());
|
||||||
|
|
||||||
let monitored_app = MonitoredApp {
|
let monitored_app = MonitoredApp {
|
||||||
|
id: Uuid::new_v4().to_string(),
|
||||||
name: config.app_name.clone(),
|
name: config.app_name.clone(),
|
||||||
service_name: config.service_name(),
|
service_name: config.service_name(),
|
||||||
path: config.working_directory.clone(),
|
path: config.working_directory.clone(),
|
||||||
|
|||||||
@@ -148,12 +148,44 @@ impl SystemCtl {
|
|||||||
match output {
|
match output {
|
||||||
Ok(out) => {
|
Ok(out) => {
|
||||||
let status_str = String::from_utf8_lossy(&out.stdout).trim().to_string();
|
let status_str = String::from_utf8_lossy(&out.stdout).trim().to_string();
|
||||||
ServiceStatus::from_str(&status_str)
|
let status = ServiceStatus::from_str(&status_str);
|
||||||
|
|
||||||
|
// Si está "activating", verificar si está en un loop de reinicios
|
||||||
|
if status == ServiceStatus::Activating {
|
||||||
|
if Self::is_in_restart_loop(service_name) {
|
||||||
|
return ServiceStatus::Failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status
|
||||||
}
|
}
|
||||||
Err(_) => ServiceStatus::Unknown,
|
Err(_) => ServiceStatus::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Verifica si un servicio está en un loop de reinicios (restart counter > 3)
|
||||||
|
fn is_in_restart_loop(service_name: &str) -> bool {
|
||||||
|
let output = Command::new("systemctl")
|
||||||
|
.arg("show")
|
||||||
|
.arg(service_name)
|
||||||
|
.arg("--property=NRestarts")
|
||||||
|
.output();
|
||||||
|
|
||||||
|
match output {
|
||||||
|
Ok(out) => {
|
||||||
|
let output_str = String::from_utf8_lossy(&out.stdout);
|
||||||
|
// Formato: NRestarts=48
|
||||||
|
if let Some(count_str) = output_str.trim().strip_prefix("NRestarts=") {
|
||||||
|
if let Ok(count) = count_str.parse::<u32>() {
|
||||||
|
return count > 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
Err(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_service_exists(service_name: &str) -> bool {
|
pub fn is_service_exists(service_name: &str) -> bool {
|
||||||
let output = Command::new("systemctl")
|
let output = Command::new("systemctl")
|
||||||
.arg("list-unit-files")
|
.arg("list-unit-files")
|
||||||
|
|||||||
@@ -238,11 +238,12 @@
|
|||||||
<!-- Tab Content: App Logs -->
|
<!-- Tab Content: App Logs -->
|
||||||
<div
|
<div
|
||||||
id="content-app-logs"
|
id="content-app-logs"
|
||||||
class="flex-1 bg-[#0a0f16] overflow-y-auto overflow-x-auto p-4 font-mono text-sm tab-content"
|
class="flex-1 bg-[#0a0f16] overflow-y-auto overflow-x-hidden p-4 font-mono text-sm tab-content"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="log-container"
|
id="log-container"
|
||||||
class="space-y-1 break-words overflow-wrap-anywhere"
|
class="space-y-1"
|
||||||
|
style="overflow-x: auto; min-width: 0;"
|
||||||
>
|
>
|
||||||
<!-- Welcome Message -->
|
<!-- Welcome Message -->
|
||||||
<div class="text-[#9dabb9] opacity-50">
|
<div class="text-[#9dabb9] opacity-50">
|
||||||
@@ -259,11 +260,12 @@
|
|||||||
<!-- Tab Content: System Errors -->
|
<!-- Tab Content: System Errors -->
|
||||||
<div
|
<div
|
||||||
id="content-system-errors"
|
id="content-system-errors"
|
||||||
class="hidden flex-1 bg-[#0a0f16] overflow-y-auto overflow-x-auto p-4 font-mono text-sm tab-content"
|
class="hidden flex-1 bg-[#0a0f16] overflow-y-auto overflow-x-hidden p-4 font-mono text-sm tab-content"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="system-errors-container"
|
id="system-errors-container"
|
||||||
class="space-y-1 break-words overflow-wrap-anywhere"
|
class="space-y-1"
|
||||||
|
style="overflow-x: auto; min-width: 0;"
|
||||||
>
|
>
|
||||||
<div class="text-[#9dabb9] opacity-50">
|
<div class="text-[#9dabb9] opacity-50">
|
||||||
<span class="text-yellow-400">⚠</span> Cargando logs
|
<span class="text-yellow-400">⚠</span> Cargando logs
|
||||||
@@ -446,11 +448,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logEntry.innerHTML = `
|
logEntry.style.whiteSpace = "pre";
|
||||||
<span class="text-[#9dabb9] opacity-50">[${timestamp}]</span>
|
logEntry.style.overflowX = "auto";
|
||||||
<span class="${color}">${icon}</span>
|
logEntry.innerHTML = `<span class="text-[#9dabb9] opacity-50">[${timestamp}]</span> <span class="${color}">${icon}</span> <span class="${color}">${escapeHtml(message)}</span>`;
|
||||||
<span class="${color}">${escapeHtml(message)}</span>
|
|
||||||
`;
|
|
||||||
|
|
||||||
logContainer.appendChild(logEntry);
|
logContainer.appendChild(logEntry);
|
||||||
|
|
||||||
@@ -506,12 +506,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearLogViewer() {
|
function clearLogViewer() {
|
||||||
|
if (currentTab === "app-logs") {
|
||||||
const logContainer = document.getElementById("log-container");
|
const logContainer = document.getElementById("log-container");
|
||||||
logContainer.innerHTML = `
|
logContainer.innerHTML = `<div class="text-[#9dabb9]"><span class="text-blue-400">ℹ</span> Log viewer cleared</div>`;
|
||||||
<div class="text-[#9dabb9]">
|
} else if (currentTab === "system-errors") {
|
||||||
<span class="text-blue-400">ℹ</span> Log viewer cleared
|
const errContainer = document.getElementById("system-errors-container");
|
||||||
</div>
|
errContainer.innerHTML = `<div class="text-[#9dabb9]"><span class="text-blue-400">ℹ</span> Historial de errores limpiado</div>`;
|
||||||
`;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tab switching
|
// Tab switching
|
||||||
|
|||||||
299
web/privacy.html
Normal file
299
web/privacy.html
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html class="dark" lang="es" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||||
|
<title>Política de Privacidad - SIAX Monitor</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/static/icon/favicon.svg" />
|
||||||
|
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<script>
|
||||||
|
tailwind.config = {
|
||||||
|
darkMode: "class",
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: "#137fec",
|
||||||
|
"background-light": "#f6f7f8",
|
||||||
|
"background-dark": "#101922",
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
display: ["Inter", "sans-serif"],
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
DEFAULT: "0.25rem",
|
||||||
|
lg: "0.5rem",
|
||||||
|
xl: "0.75rem",
|
||||||
|
full: "9999px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
}
|
||||||
|
.material-symbols-outlined {
|
||||||
|
font-variation-settings:
|
||||||
|
"FILL" 0,
|
||||||
|
"wght" 400,
|
||||||
|
"GRAD" 0,
|
||||||
|
"opsz" 24;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-background-dark font-display text-white min-h-screen flex flex-col">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="sticky top-0 z-50 w-full border-b border-solid border-[#283039] bg-background-dark/80 backdrop-blur-md px-4 md:px-10 py-3">
|
||||||
|
<div class="max-w-[1400px] mx-auto flex items-center justify-between">
|
||||||
|
<div class="flex items-center gap-4 text-white">
|
||||||
|
<div class="size-8 bg-primary rounded-lg flex items-center justify-center overflow-hidden">
|
||||||
|
<img src="/static/icon/logo.png" alt="Logo" class="w-full h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
<h2 class="text-white text-lg font-bold leading-tight tracking-[-0.015em]">SIAX Monitor</h2>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-6">
|
||||||
|
<nav class="hidden md:flex items-center gap-6">
|
||||||
|
<a class="text-[#9dabb9] text-sm font-medium hover:text-white transition-colors" href="/">Panel</a>
|
||||||
|
<a class="text-[#9dabb9] text-sm font-medium hover:text-white transition-colors" href="/logs">Registros</a>
|
||||||
|
<a class="text-[#9dabb9] text-sm font-medium hover:text-white transition-colors" href="/terms">Términos</a>
|
||||||
|
<a class="text-primary text-sm font-medium border-b-2 border-primary pb-1" href="/privacy">Privacidad</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<main class="flex-1 max-w-[860px] mx-auto w-full px-6 py-12">
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<div class="mb-10">
|
||||||
|
<div class="flex items-center gap-3 mb-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-3xl">shield</span>
|
||||||
|
<h1 class="text-3xl font-bold text-white">Política de Privacidad</h1>
|
||||||
|
</div>
|
||||||
|
<p class="text-[#9dabb9] text-sm">
|
||||||
|
Última actualización: <span class="text-white">21 de febrero de 2026</span>
|
||||||
|
</p>
|
||||||
|
<div class="mt-4 p-4 bg-green-500/10 border border-green-500/20 rounded-lg flex items-start gap-3">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[20px] mt-0.5">verified_user</span>
|
||||||
|
<p class="text-[#9dabb9] text-sm">
|
||||||
|
<strong class="text-white">SIAX Monitor no recopila ni transmite datos personales a servidores externos.</strong>
|
||||||
|
Todo el procesamiento ocurre localmente en tu infraestructura.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sections -->
|
||||||
|
<div class="space-y-8">
|
||||||
|
|
||||||
|
<!-- 1 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">01</span>
|
||||||
|
Responsable del Tratamiento
|
||||||
|
</h2>
|
||||||
|
<div class="space-y-2 text-sm text-[#9dabb9]">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">person</span>
|
||||||
|
<span><strong class="text-white">Responsable:</strong> Pablinux / Xsystem</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">location_on</span>
|
||||||
|
<span><strong class="text-white">País:</strong> Ecuador</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">mail</span>
|
||||||
|
<span>
|
||||||
|
<a href="mailto:pablinux@hotmail.es" class="text-primary hover:underline">pablinux@hotmail.es</a>
|
||||||
|
·
|
||||||
|
<a href="mailto:admin@telcotronics.com" class="text-primary hover:underline">admin@telcotronics.com</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 2 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">02</span>
|
||||||
|
Datos que Maneja el Software
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-4">
|
||||||
|
SIAX Monitor almacena localmente la siguiente información de configuración:
|
||||||
|
</p>
|
||||||
|
<div class="grid gap-3">
|
||||||
|
<div class="flex items-start gap-3 p-3 bg-[#0a0f16] rounded-lg">
|
||||||
|
<span class="material-symbols-outlined text-blue-400 text-[18px] mt-0.5">settings</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-white text-sm font-medium">Configuración de aplicaciones</p>
|
||||||
|
<p class="text-[#9dabb9] text-xs mt-0.5">Nombres, rutas, puertos y parámetros de inicio de las apps registradas.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start gap-3 p-3 bg-[#0a0f16] rounded-lg">
|
||||||
|
<span class="material-symbols-outlined text-yellow-400 text-[18px] mt-0.5">terminal</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-white text-sm font-medium">Logs del sistema</p>
|
||||||
|
<p class="text-[#9dabb9] text-xs mt-0.5">Registros de actividad de los servicios gestionados, almacenados localmente.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start gap-3 p-3 bg-[#0a0f16] rounded-lg">
|
||||||
|
<span class="material-symbols-outlined text-purple-400 text-[18px] mt-0.5">key</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-white text-sm font-medium">Variables de entorno</p>
|
||||||
|
<p class="text-[#9dabb9] text-xs mt-0.5">Variables de configuración de las aplicaciones, guardadas en archivos locales.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 3 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">03</span>
|
||||||
|
Datos que NO se Recopilan
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-3">
|
||||||
|
SIAX Monitor <strong class="text-white">no recopila, almacena ni transmite</strong>:
|
||||||
|
</p>
|
||||||
|
<ul class="space-y-2 text-sm text-[#9dabb9]">
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px]">check</span>
|
||||||
|
Datos personales de los usuarios de las aplicaciones gestionadas.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px]">check</span>
|
||||||
|
Información de telemetría o uso del software.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px]">check</span>
|
||||||
|
Cookies de seguimiento o identificadores de sesión persistentes.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px]">check</span>
|
||||||
|
Direcciones IP, datos de geolocalización o información del dispositivo.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px]">check</span>
|
||||||
|
Credenciales, contraseñas ni tokens de autenticación externos.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 4 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">04</span>
|
||||||
|
Almacenamiento y Seguridad
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
Toda la información gestionada por SIAX Monitor reside exclusivamente en el servidor
|
||||||
|
donde el software está instalado. La seguridad de dicha información depende de las
|
||||||
|
medidas de protección del sistema operativo y la red del usuario.
|
||||||
|
Recomendamos restringir el acceso a la interfaz web mediante firewall y autenticación
|
||||||
|
a nivel de red.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 5 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">05</span>
|
||||||
|
Terceros
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
SIAX Monitor no comparte, vende ni cede información a terceros. La interfaz web carga
|
||||||
|
recursos externos únicamente para estilos y fuentes (Tailwind CSS CDN, Google Fonts),
|
||||||
|
los cuales no reciben datos de configuración ni de logs.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 6 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">06</span>
|
||||||
|
Derechos del Usuario
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-3">
|
||||||
|
De conformidad con la legislación ecuatoriana aplicable, el usuario tiene derecho a:
|
||||||
|
</p>
|
||||||
|
<ul class="space-y-2 text-sm text-[#9dabb9]">
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[16px]">arrow_forward</span>
|
||||||
|
Acceder a los datos de configuración almacenados localmente.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[16px]">arrow_forward</span>
|
||||||
|
Rectificar o eliminar cualquier dato desde la propia interfaz del software.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[16px]">arrow_forward</span>
|
||||||
|
Solicitar información sobre el tratamiento de datos contactando al responsable.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 7 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">07</span>
|
||||||
|
Cambios en esta Política
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
Xsystem puede actualizar esta política de privacidad en cualquier momento. La fecha de
|
||||||
|
última actualización se indica al inicio del documento. Se notificará al usuario sobre
|
||||||
|
cambios relevantes a través de la interfaz del software o por correo electrónico.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 8 - Contact -->
|
||||||
|
<section class="border border-primary/30 rounded-xl p-6 bg-primary/5">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[20px]">mail</span>
|
||||||
|
Contacto
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-4">
|
||||||
|
Para ejercer tus derechos o realizar consultas sobre esta política:
|
||||||
|
</p>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">person</span>
|
||||||
|
<span class="text-sm text-[#9dabb9]">Desarrollador:
|
||||||
|
<a href="mailto:pablinux@hotmail.es" class="text-primary hover:underline">pablinux@hotmail.es</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">business</span>
|
||||||
|
<span class="text-sm text-[#9dabb9]">Empresa:
|
||||||
|
<a href="mailto:admin@telcotronics.com" class="text-primary hover:underline">admin@telcotronics.com</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">location_on</span>
|
||||||
|
<span class="text-sm text-[#9dabb9]">Ecuador</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer nav -->
|
||||||
|
<div class="mt-10 pt-6 border-t border-[#283039] flex items-center justify-between text-sm text-[#9dabb9]">
|
||||||
|
<span>© 2026 Xsystem / Pablinux. Todos los derechos reservados.</span>
|
||||||
|
<a href="/terms" class="text-primary hover:underline flex items-center gap-1">
|
||||||
|
<span class="material-symbols-outlined text-[16px]">gavel</span>
|
||||||
|
Términos y Condiciones
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
268
web/terms.html
Normal file
268
web/terms.html
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html class="dark" lang="es" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||||
|
<title>Términos y Condiciones - SIAX Monitor</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/static/icon/favicon.svg" />
|
||||||
|
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<script>
|
||||||
|
tailwind.config = {
|
||||||
|
darkMode: "class",
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: "#137fec",
|
||||||
|
"background-light": "#f6f7f8",
|
||||||
|
"background-dark": "#101922",
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
display: ["Inter", "sans-serif"],
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
DEFAULT: "0.25rem",
|
||||||
|
lg: "0.5rem",
|
||||||
|
xl: "0.75rem",
|
||||||
|
full: "9999px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
}
|
||||||
|
.material-symbols-outlined {
|
||||||
|
font-variation-settings:
|
||||||
|
"FILL" 0,
|
||||||
|
"wght" 400,
|
||||||
|
"GRAD" 0,
|
||||||
|
"opsz" 24;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-background-dark font-display text-white min-h-screen flex flex-col">
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="sticky top-0 z-50 w-full border-b border-solid border-[#283039] bg-background-dark/80 backdrop-blur-md px-4 md:px-10 py-3">
|
||||||
|
<div class="max-w-[1400px] mx-auto flex items-center justify-between">
|
||||||
|
<div class="flex items-center gap-4 text-white">
|
||||||
|
<div class="size-8 bg-primary rounded-lg flex items-center justify-center overflow-hidden">
|
||||||
|
<img src="/static/icon/logo.png" alt="Logo" class="w-full h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
<h2 class="text-white text-lg font-bold leading-tight tracking-[-0.015em]">SIAX Monitor</h2>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-6">
|
||||||
|
<nav class="hidden md:flex items-center gap-6">
|
||||||
|
<a class="text-[#9dabb9] text-sm font-medium hover:text-white transition-colors" href="/">Panel</a>
|
||||||
|
<a class="text-[#9dabb9] text-sm font-medium hover:text-white transition-colors" href="/logs">Registros</a>
|
||||||
|
<a class="text-primary text-sm font-medium border-b-2 border-primary pb-1" href="/terms">Términos</a>
|
||||||
|
<a class="text-[#9dabb9] text-sm font-medium hover:text-white transition-colors" href="/privacy">Privacidad</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<main class="flex-1 max-w-[860px] mx-auto w-full px-6 py-12">
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<div class="mb-10">
|
||||||
|
<div class="flex items-center gap-3 mb-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-3xl">gavel</span>
|
||||||
|
<h1 class="text-3xl font-bold text-white">Términos y Condiciones</h1>
|
||||||
|
</div>
|
||||||
|
<p class="text-[#9dabb9] text-sm">
|
||||||
|
Última actualización: <span class="text-white">21 de febrero de 2026</span>
|
||||||
|
</p>
|
||||||
|
<div class="mt-4 p-4 bg-primary/10 border border-primary/20 rounded-lg">
|
||||||
|
<p class="text-[#9dabb9] text-sm">
|
||||||
|
Al utilizar <strong class="text-white">SIAX Monitor</strong>, aceptas los presentes términos en su totalidad.
|
||||||
|
Si no estás de acuerdo con alguna parte, te pedimos que no uses el software.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sections -->
|
||||||
|
<div class="space-y-8">
|
||||||
|
|
||||||
|
<!-- 1 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">01</span>
|
||||||
|
Descripción del Software
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
<strong class="text-white">SIAX Monitor</strong> es una herramienta de monitoreo y gestión de aplicaciones
|
||||||
|
desarrollada por <strong class="text-white">Pablinux</strong> para <strong class="text-white">Xsystem</strong>,
|
||||||
|
con sede en Ecuador. Permite registrar, iniciar, detener y supervisar servicios del sistema operativo
|
||||||
|
a través de una interfaz web local. El software opera exclusivamente dentro de la infraestructura
|
||||||
|
del usuario y no transmite datos a servidores externos.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 2 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">02</span>
|
||||||
|
Licencia de Uso
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-3">
|
||||||
|
Se otorga una licencia personal, no exclusiva, no transferible y revocable para usar SIAX Monitor
|
||||||
|
en los entornos autorizados por Xsystem. Queda expresamente prohibido:
|
||||||
|
</p>
|
||||||
|
<ul class="space-y-2 text-sm text-[#9dabb9]">
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-red-400 text-[16px] mt-0.5">block</span>
|
||||||
|
Sublicenciar, vender o redistribuir el software sin autorización escrita.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-red-400 text-[16px] mt-0.5">block</span>
|
||||||
|
Modificar o crear trabajos derivados sin consentimiento del autor.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-red-400 text-[16px] mt-0.5">block</span>
|
||||||
|
Utilizar el software para fines ilegales o no autorizados.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-red-400 text-[16px] mt-0.5">block</span>
|
||||||
|
Realizar ingeniería inversa del código fuente.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 3 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">03</span>
|
||||||
|
Responsabilidades del Usuario
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-3">
|
||||||
|
El usuario es responsable de:
|
||||||
|
</p>
|
||||||
|
<ul class="space-y-2 text-sm text-[#9dabb9]">
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px] mt-0.5">check_circle</span>
|
||||||
|
Mantener la seguridad del servidor donde se ejecuta SIAX Monitor.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px] mt-0.5">check_circle</span>
|
||||||
|
Gestionar correctamente los permisos de acceso a la interfaz web.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px] mt-0.5">check_circle</span>
|
||||||
|
Realizar copias de seguridad de su configuración y datos.
|
||||||
|
</li>
|
||||||
|
<li class="flex items-start gap-2">
|
||||||
|
<span class="material-symbols-outlined text-green-400 text-[16px] mt-0.5">check_circle</span>
|
||||||
|
Usar el software conforme a las leyes vigentes en Ecuador y las aplicables en su jurisdicción.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 4 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">04</span>
|
||||||
|
Limitación de Responsabilidad
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
SIAX Monitor se proporciona <strong class="text-white">"tal cual"</strong>, sin garantías de ningún tipo,
|
||||||
|
expresas o implícitas. Xsystem y Pablinux no se hacen responsables por daños directos, indirectos,
|
||||||
|
incidentales o consecuentes que resulten del uso o la imposibilidad de uso del software, incluyendo
|
||||||
|
pero no limitándose a: pérdida de datos, interrupciones de servicio, o daños en el sistema operativo
|
||||||
|
derivados de configuraciones incorrectas.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 5 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">05</span>
|
||||||
|
Propiedad Intelectual
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
Todos los derechos de propiedad intelectual sobre SIAX Monitor, incluyendo su código fuente,
|
||||||
|
diseño, logotipos y documentación, son propiedad exclusiva de <strong class="text-white">Pablinux / Xsystem</strong>.
|
||||||
|
Quedan reservados todos los derechos no otorgados expresamente en estos términos.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 6 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">06</span>
|
||||||
|
Modificaciones
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
Xsystem se reserva el derecho de modificar estos términos en cualquier momento. Los cambios
|
||||||
|
serán comunicados a través de la propia interfaz del software o mediante correo electrónico.
|
||||||
|
El uso continuado del software tras la publicación de cambios constituye aceptación de los
|
||||||
|
nuevos términos.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 7 -->
|
||||||
|
<section class="border border-[#283039] rounded-xl p-6 bg-[#161f2a]">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="text-primary font-mono text-sm bg-primary/10 px-2 py-0.5 rounded">07</span>
|
||||||
|
Legislación Aplicable
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed">
|
||||||
|
Estos términos se rigen por las leyes vigentes en la <strong class="text-white">República del Ecuador</strong>.
|
||||||
|
Cualquier disputa derivada del uso de este software será sometida a la jurisdicción de los
|
||||||
|
tribunales competentes de Ecuador.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 8 - Contact -->
|
||||||
|
<section class="border border-primary/30 rounded-xl p-6 bg-primary/5">
|
||||||
|
<h2 class="text-white text-lg font-semibold mb-3 flex items-center gap-2">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[20px]">mail</span>
|
||||||
|
Contacto
|
||||||
|
</h2>
|
||||||
|
<p class="text-[#9dabb9] text-sm leading-relaxed mb-4">
|
||||||
|
Para cualquier consulta relacionada con estos términos, puedes contactarnos a través de:
|
||||||
|
</p>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">person</span>
|
||||||
|
<span class="text-sm text-[#9dabb9]">Desarrollador:
|
||||||
|
<a href="mailto:pablinux@hotmail.es" class="text-primary hover:underline">pablinux@hotmail.es</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">business</span>
|
||||||
|
<span class="text-sm text-[#9dabb9]">Empresa:
|
||||||
|
<a href="mailto:admin@telcotronics.com" class="text-primary hover:underline">admin@telcotronics.com</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="material-symbols-outlined text-primary text-[18px]">location_on</span>
|
||||||
|
<span class="text-sm text-[#9dabb9]">Ecuador</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer nav -->
|
||||||
|
<div class="mt-10 pt-6 border-t border-[#283039] flex items-center justify-between text-sm text-[#9dabb9]">
|
||||||
|
<span>© 2026 Xsystem / Pablinux. Todos los derechos reservados.</span>
|
||||||
|
<a href="/privacy" class="text-primary hover:underline flex items-center gap-1">
|
||||||
|
<span class="material-symbols-outlined text-[16px]">shield</span>
|
||||||
|
Política de Privacidad
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user