CRITICAL fixes: - Restrict X-View-Tenant impersonation to global admin only (was any admin) - Add authorization to subscription endpoints (was open to any user) - Make webhook signature verification mandatory (was skippable) - Remove databaseName from JWT payload (resolve server-side with cache) - Reduce body size limit from 1GB to 10MB (50MB for bulk CFDI) - Restrict .env file permissions to 600 HIGH fixes: - Add authorization to SAT cron endpoints (global admin only) - Add Content-Security-Policy and Permissions-Policy headers - Centralize isGlobalAdmin() utility with caching - Add rate limiting on auth endpoints (express-rate-limit) - Require authentication on logout endpoint MEDIUM fixes: - Replace Math.random() with crypto.randomBytes for temp passwords - Remove console.log of temporary passwords in production - Remove DB credentials from admin notification email - Add escapeHtml() to email templates (prevent HTML injection) - Add file size validation on FIEL upload (50KB max) - Require TLS for SMTP connections - Normalize email to lowercase before uniqueness check - Remove hardcoded default for FIEL_ENCRYPTION_KEY Also includes: - Complete production deployment documentation - API reference documentation - Security audit report with remediation details - Updated README with v0.5.0 changelog - New client admin email template - Utility scripts (create-carlos, test-emails) - PM2 ecosystem config updates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6.5 KiB
API Reference - Horux360
Base URL: https://horuxfin.com/api
Autenticación
Todos los endpoints (excepto auth) requieren header:
Authorization: Bearer <accessToken>
Rate Limits (por IP)
| Endpoint | Límite | Ventana |
|---|---|---|
POST /auth/login |
10 requests | 15 minutos |
POST /auth/register |
3 requests | 1 hora |
POST /auth/refresh |
20 requests | 15 minutos |
General /api/* |
30 requests/s | burst 50 |
Auth (/api/auth)
POST /auth/register
Registra nueva empresa y usuario admin. Provisiona base de datos dedicada.
Body:
{
"empresa": { "nombre": "Mi Empresa", "rfc": "ABC123456789" },
"usuario": { "nombre": "Juan", "email": "juan@empresa.com", "password": "min8chars" }
}
Response: { accessToken, refreshToken, user: UserInfo }
POST /auth/login
{ "email": "usuario@empresa.com", "password": "..." }
Response: { accessToken, refreshToken, user: UserInfo }
POST /auth/refresh
{ "refreshToken": "..." }
Response: { accessToken, refreshToken }
POST /auth/logout (requiere auth)
{ "refreshToken": "..." }
GET /auth/me (requiere auth)
Response: UserInfo
Dashboard (/api/dashboard)
GET /dashboard/kpis?año=2026&mes=3
KPIs principales: ingresos, egresos, utilidad, margen, IVA balance, conteo de CFDIs.
GET /dashboard/ingresos-egresos?año=2026
Datos mensuales de ingresos/egresos para gráfica anual.
GET /dashboard/resumen-fiscal?año=2026&mes=3
IVA por pagar, IVA a favor, ISR, declaraciones pendientes, próxima obligación.
GET /dashboard/alertas?limit=5
Alertas activas no resueltas, ordenadas por prioridad.
CFDI (/api/cfdi)
GET /cfdi?page=1&limit=20&tipo=ingreso&search=...
Lista paginada de CFDIs con filtros.
GET /cfdi/resumen
Resumen de conteo por tipo y estado.
GET /cfdi/emisores
Lista de emisores únicos.
GET /cfdi/receptores
Lista de receptores únicos.
GET /cfdi/:id
Detalle de un CFDI.
GET /cfdi/:id/xml
XML original del CFDI.
POST /cfdi
Crear un CFDI individual. Sujeto a límite de plan.
POST /cfdi/bulk
Carga masiva de CFDIs. Body limit: 50MB. Sujeto a límite de plan.
DELETE /cfdi/:id
Eliminar un CFDI.
Impuestos (/api/impuestos)
GET /impuestos/iva?año=2026
Datos mensuales de IVA (trasladado, acreditable, resultado, acumulado).
Alertas (/api/alertas)
GET /alertas
POST /alertas
PUT /alertas/:id
DELETE /alertas/:id
PATCH /alertas/:id/read
PATCH /alertas/:id/resolve
Calendario (/api/calendario)
GET /calendario?año=2026&mes=3
POST /calendario
PUT /calendario/:id
DELETE /calendario/:id
Reportes (/api/reportes)
GET /reportes/flujo-efectivo?año=2026
GET /reportes/impuestos?año=2026
GET /reportes/forecasting?año=2026
GET /reportes/concentrado?año=2026
Export (/api/export)
GET /export/cfdis?format=excel&tipo=ingreso
Exporta CFDIs a Excel o CSV.
FIEL (/api/fiel)
POST /fiel/upload
{
"cerFile": "<base64>",
"keyFile": "<base64>",
"password": "..."
}
- Archivos max 50KB cada uno
- Password max 256 caracteres
GET /fiel/status
Estado actual de la FIEL configurada.
DELETE /fiel
Eliminar credenciales FIEL.
SAT Sync (/api/sat)
POST /sat/sync
Iniciar sincronización manual.
{ "type": "daily", "dateFrom": "2026-01-01", "dateTo": "2026-01-31" }
GET /sat/sync/status
Estado actual de sincronización.
GET /sat/sync/history?page=1&limit=10
Historial de sincronizaciones.
GET /sat/sync/:id
Detalle de un job de sincronización.
POST /sat/sync/:id/retry
Reintentar un job fallido.
GET /sat/cron (admin global)
Info del job programado.
POST /sat/cron/run (admin global)
Ejecutar sincronización global manualmente.
Usuarios (/api/usuarios)
GET /usuarios
Usuarios del tenant actual.
GET /usuarios/all (admin global)
Todos los usuarios de todas las empresas.
POST /usuarios
Invitar usuario (genera password temporal con crypto.randomBytes).
{ "email": "nuevo@empresa.com", "nombre": "María", "role": "contador" }
PUT /usuarios/:id
Actualizar usuario (nombre, role, active).
DELETE /usuarios/:id
PUT /usuarios/:id/global (admin global)
Actualizar usuario de cualquier empresa.
DELETE /usuarios/:id/global (admin global)
Tenants / Clientes (/api/tenants) (admin global)
GET /tenants
Lista de todos los tenants/clientes.
POST /tenants
Crear nuevo tenant. Provisiona base de datos. Envía email al admin.
{
"nombre": "Empresa Nueva",
"rfc": "ENE123456789",
"plan": "business",
"adminNombre": "Pedro",
"adminEmail": "pedro@nueva.com"
}
PUT /tenants/:id
Actualizar tenant (plan, limits, active).
DELETE /tenants/:id
Soft delete — renombra la base de datos a *_deleted_*.
Suscripciones (/api/subscriptions) (admin global)
GET /subscriptions/:tenantId
Suscripción activa del tenant.
POST /subscriptions/:tenantId/generate-link
Generar link de pago MercadoPago.
POST /subscriptions/:tenantId/mark-paid
Marcar como pagado manualmente.
{ "amount": 999 }
GET /subscriptions/:tenantId/payments
Historial de pagos.
Webhooks (/api/webhooks)
POST /webhooks/mercadopago
Webhook de MercadoPago. Requiere headers:
x-signature: Firma HMAC-SHA256x-request-id: ID del request
Roles y Permisos
| Rol | Descripción | Acceso |
|---|---|---|
admin |
Administrador del tenant | Todo dentro de su tenant + invitar usuarios |
contador |
Contador | CFDI, impuestos, reportes, dashboard |
visor |
Solo lectura | Dashboard, CFDI (solo ver), reportes |
Admin Global
El admin del tenant con RFC CAS2408138W2 tiene acceso adicional:
- Gestión de todos los tenants
- Suscripciones
- SAT cron
- Impersonación via
X-View-Tenantheader - Bypass de plan limits al impersonar
Tipos Compartidos (@horux/shared)
UserInfo
interface UserInfo {
id: string;
email: string;
nombre: string;
role: 'admin' | 'contador' | 'visor';
tenantId: string;
tenantName: string;
tenantRfc: string;
plan: string;
}
JWTPayload
interface JWTPayload {
userId: string;
email: string;
role: Role;
tenantId: string;
iat?: number;
exp?: number;
}