Seguridad
Ruta:
/owner/settings/securityGestiona la seguridad de tu cuenta y revisa accesos.
Vista general
Sección titulada «Vista general»La pantalla de Seguridad permite configurar opciones de protección de tu cuenta y revisar el historial de accesos.
Secciones principales:
| Sección | Descripción |
|---|---|
| Correo de recuperación | Configura un email alternativo para recuperar tu cuenta |
| Registros de acceso | Historial de inicios y cierres de sesión |
Acceso restringido: Solo propietarios del negocio tienen acceso a esta configuración.
Funciones
Sección titulada «Funciones»| Función | Descripción | Documentación |
|---|---|---|
| Configurar email de recuperación | Añade un correo alternativo para recuperación | Ver |
| Recuperar contraseña | Restablece tu contraseña mediante email | Ver |
| Ver registros de acceso | Consulta historial de inicios de sesión | Ver |
| Filtrar registros | Filtra accesos por tipo de evento o usuario | Ver |
Seguridad de sesión
Sección titulada «Seguridad de sesión»Factux implementa múltiples capas de seguridad para proteger tu sesión:
Gestión automática de sesión
Sección titulada «Gestión automática de sesión»| Característica | Descripción |
|---|---|
| Refresco automático | La sesión se refresca cada 30 minutos |
| Verificación al volver | Al regresar a la pestaña se verifica la sesión |
| Detección de expiración | Redirige automáticamente al login si expira |
| Limpieza segura | Los tokens se eliminan de forma segura al cerrar |
Tiempo de sesión
Sección titulada «Tiempo de sesión»- Duración máxima: 1 hora sin actividad
- Refresco preventivo: Cuando quedan menos de 5 minutos
- Verificación mínima: No más frecuente que cada 5 segundos
- Notificación: Toast informativo antes de redirigir
Estados de seguridad
Sección titulada «Estados de seguridad»┌────────────────┐│ Sin protección │ (sin email de recuperación)└───────┬────────┘ │ Configurar┌───────▼────────┐│ Protegido │ (email de recuperación activo)└───────┬────────┘ │ Necesita recuperación┌───────▼────────┐│ Recuperando │ (token enviado, válido 24h)└───────┬────────┘ │ Cambiar contraseña┌───────▼────────┐│ Acceso OK │ (contraseña actualizada)└────────────────┘Referencia técnica
Sección titulada «Referencia técnica»Detalles técnicos
Tablas de base de datos
Sección titulada «Tablas de base de datos»Tablas principales
| Tabla | Columnas principales | FK |
|---|---|---|
profiles | user_id, recovery_email | auth.users |
user_access_logs | id, user_id, business_id, user_name, user_email, user_type, event_type, login_at, ip_address, user_agent, session_id | auth.users, businesses |
security_audit_log | id, user_id, event_type, event_data, ip_address, user_agent, resource_type, resource_id, severity, timestamp | auth.users |
password_reset_tokens | id, user_id, email, token, expires_at, used_at | auth.users |
Tipos de datos:
interface UserAccessLog { id: string; user_id: string; business_id?: string; user_name: string; user_email: string; user_type: 'owner' | 'manager' | 'employee' | 'advisor' | 'admin' | 'support'; event_type: 'login' | 'logout'; login_at: string; // timestamp ip_address?: string; user_agent?: string; session_id?: string;}
interface SecurityAuditLog { id: string; user_id?: string; event_type: string; // session_start, unauthorized_access_attempt, etc. event_data: Record<string, any>; ip_address?: string; user_agent?: string; resource_type?: string; resource_id?: string; severity: 'info' | 'warning' | 'critical'; timestamp: string;}
interface PasswordResetToken { id: string; user_id: string; email: string; token: string; expires_at: string; used_at?: string; created_at: string;}Políticas RLS
Sección titulada «Políticas RLS»Políticas de seguridad
| Tabla | Política | Regla |
|---|---|---|
profiles | profiles_read_own | Solo lectura de perfil propio |
profiles | profiles_update_own | Solo actualización de perfil propio |
user_access_logs | users_view_own_access_logs | Solo logs propios o de negocios asociados |
security_audit_log | users_view_own_audit_logs | Solo logs propios |
Edge Functions
Sección titulada «Edge Functions»Funciones de autenticación
| Función | Trigger | Descripción |
|---|---|---|
send-password-reset-email | Recuperación contraseña | Envía email con token vía SendGrid |
update-password-with-token | Cambio contraseña | Valida token y actualiza contraseña |
track-auth-events | Login/logout | Registra eventos de autenticación |
Detalles de send-password-reset-email:
// Parámetrosinterface ResetPasswordRequest { email: string; sendToRecoveryEmail?: boolean; // enviar a email de recuperación}
// Proceso// 1. Busca usuario por email// 2. Si sendToRecoveryEmail=true, obtiene recovery_email de profiles// 3. Genera token UUID seguro// 4. Guarda token en password_reset_tokens (válido 24h)// 5. Envía email con enlace de reset// 6. Retorna success con mensaje personalizado
// Template SendGrid: d-b937c4c6573a49c3bd745df56b5cb2e6Detalles de track-auth-events:
// Parámetrosinterface AuthEvent { event: string; // user.login.failed email: string; ip_address?: string; user_agent?: string; error_message?: string;}
// Registra intentos fallidos de login para seguridadComponentes React
Sección titulada «Componentes React»Componentes de seguridad
| Componente | Ruta | Propósito |
|---|---|---|
RecoveryEmailSettings | /src/features/settings/components/RecoveryEmailSettings.tsx | Gestión de email de recuperación |
AccessLogsTable | /src/panels/admin/components/AccessLogsTable.tsx | Tabla de registros de acceso |
SessionRecovery | /src/components/auth/SessionRecovery.tsx | Manejo de sesiones expiradas |
Schema de validación:
const recoveryEmailSchema = z.object({ recovery_email: z .string() .email("Introduce un correo electrónico válido") .or(z.literal("")),});Hooks personalizados
Sección titulada «Hooks personalizados»Hook de sesión
useSessionKeepAlive — /src/hooks/useSessionKeepAlive.ts
Mantiene la sesión activa y detecta sesiones expiradas.
Funcionalidades:
- Refresca la sesión cada 30 minutos
- Verifica la sesión cuando el usuario regresa a la pestaña
- Verifica al recuperar conexión a internet
- Refresca preventivo cuando quedan menos de 5 min de expiración
- Limita verificaciones a 1 cada 5 segundos mínimo
- Redirige al login con toast informativo si expira
Triggers de verificación:
initial_mount— Al montar el componenteperiodic_refresh— Cada 30 minutosvisibility_change— Al volver a la pestañawindow_focus— Al enfocar la ventanaonline— Al recuperar conexión
Queries de diagnóstico
Sección titulada «Queries de diagnóstico»Consultas útiles
Accesos recientes de un usuario:
SELECT * FROM user_access_logsWHERE user_id = '<user_id>'ORDER BY login_at DESCLIMIT 50;Accesos por negocio:
SELECT ual.*, b.name as business_nameFROM user_access_logs ualLEFT JOIN businesses b ON ual.business_id = b.idWHERE ual.business_id = '<business_id>'ORDER BY ual.login_at DESC;Accesos sospechosos (múltiples IPs):
SELECT user_email, COUNT(DISTINCT ip_address) as different_ips, COUNT(*) as total_loginsFROM user_access_logsWHERE login_at >= NOW() - INTERVAL '24 hours' AND event_type = 'login'GROUP BY user_emailHAVING COUNT(DISTINCT ip_address) > 3ORDER BY different_ips DESC;Eventos de seguridad críticos:
SELECT * FROM security_audit_logWHERE severity = 'critical' AND timestamp >= NOW() - INTERVAL '7 days'ORDER BY timestamp DESC;Tokens de recuperación activos:
SELECT prt.*, p.first_name, p.last_nameFROM password_reset_tokens prtJOIN profiles p ON prt.user_id = p.user_idWHERE prt.expires_at > NOW() AND prt.used_at IS NULLORDER BY prt.created_at DESC;Email de recuperación configurados:
SELECT user_id, recovery_email, created_atFROM profilesWHERE recovery_email IS NOT NULLORDER BY created_at DESC;Funciones de base de datos
Sección titulada «Funciones de base de datos»Funciones de seguridad
log_security_event — Registra eventos de seguridad en audit log
-- Parámetrosp_event_type TEXT, -- Tipo de eventop_resource_type TEXT, -- Tipo de recurso afectadop_resource_id TEXT, -- ID del recursop_event_data JSONB, -- Datos adicionalesp_severity TEXT DEFAULT 'info', -- info, warning, criticalp_ip_address TEXT, -- IP del eventop_user_agent TEXT -- User agent
-- UsoSELECT log_security_event( 'unauthorized_access_attempt', 'invoice', 'invoice-id-123', '{"attempted_action": "delete"}'::jsonb, 'warning', '192.168.1.1', 'Mozilla/5.0...');cleanup_expired_password_tokens — Limpia tokens expirados
-- Elimina tokens expirados o usados hace más de 7 días-- Ejecuta automáticamente vía cronSELECT cleanup_expired_password_tokens();get_user_by_email — Busca usuario por email (SECURITY DEFINER)
-- Solo accesible por service_role para password resetSELECT * FROM get_user_by_email('usuario@ejemplo.com');Mejores prácticas de seguridad
Sección titulada «Mejores prácticas de seguridad»Para usuarios
Sección titulada «Para usuarios»- Configura un email de recuperación diferente al principal
- Revisa periódicamente los registros de acceso
- Notifica accesos sospechosos si ves IPs desconocidas
- Usa contraseñas robustas con mayúsculas, números y símbolos
- Cierra sesión en dispositivos compartidos
Para soporte técnico
Sección titulada «Para soporte técnico»- Monitorea eventos críticos en
security_audit_log - Verifica intentos fallidos repetidos de login
- Revisa tokens activos antes de depurar problemas de recuperación
- Audita accesos desde múltiples IPs en corto tiempo
- Mantén logs de eventos de seguridad para análisis
Tour guiado
Sección titulada «Tour guiado»Factux incluye un tour interactivo que se activa automáticamente la primera vez que visitas la pantalla de Seguridad.
Pasos del tour:
- Cabecera — Introducción a la gestión de seguridad
- Email de recuperación — Cómo configurar un email alternativo
- Registros de acceso — Detectar accesos sospechosos
Archivo de configuración: /src/features/tours/config/settings-security.tour.ts