Files
project.linkedcorp.net/CONFIGURACION.md
T
Milton Gonzalez 7557dffc52 feat: autorregistro con verificacion de correo + aprobacion, superadmin y SMTP
- POST /api/auth/register: primer usuario del sistema -> superadmin con sesion
  directa (bootstrap, sin correo ni aprobacion); los siguientes quedan
  pending_verification y reciben un correo con enlace de un solo uso (24h).
- GET /api/auth/verify-email: pasa a pending_approval y notifica in-app a los
  admin/superadmin activos.
- admin/superadmin aprueban (POST /api/users/:id/approve, eligen rol y
  departamento) o rechazan (POST /api/users/:id/reject, borra y audita el
  email) desde Organizacion -> Usuarios (nuevo badge de estado + acciones).
- login() da mensaje especifico segun el status de la cuenta en vez del
  generico "credenciales invalidas".
- Recuperacion de clave (forgot/reset-password): respuesta siempre generica,
  token de 1 hora de un solo uso.
- Nuevo modulo settings: SMTP configurable SOLO por superadmin desde
  Configuracion -> Correo (SMTP); clave cifrada AES-256-GCM (ENCRYPTION_KEY)
  en la tabla system_settings, nunca expuesta por la API. sendMail() degrada
  a modo dev (loguea en vez de enviar) si no hay SMTP configurado, y nunca
  deja que un fallo de envio tumbe al que lo llama.
- Migracion 002_registration_and_smtp.sql: rol superadmin, columnas de ciclo
  de vida en users (status, tokens), tabla system_settings, y promueve al
  usuario mas antiguo del sistema a superadmin.
- Fix: React.StrictMode disparaba el efecto de VerifyEmailPage dos veces; la
  segunda llamada (token ya consumido) mostraba "enlace invalido" pese a que
  la verificacion ya habia funcionado. Se agrega una guarda por token.
- Fix (deuda tecnica v1.0.0): se reordena el montaje de rutas en app.js —
  subtasksRoutes (mount generico en /api) va al final, para no interceptar
  con su requireAuth interno una request sin token dirigida a un router mas
  especifico registrado despues.
- Documentacion actualizada: AGENTS.md, SPEC.md, API.md, BASE_DE_DATOS.md,
  CONFIGURACION.md, ESTADO.md, CHANGELOG.md. Version 1.1.0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 23:28:46 -05:00

2.2 KiB

Configuracion - project.linkedcorp.net

Requisitos

  • Node.js: 20.x LTS
  • npm: 10.x
  • MariaDB: servidor dev 192.168.222.20 (ya existe la BD project_linkedcorp)

Variables principales

Usar backend/.env.example y frontend/.env.example como base.

  • copiar .env.example -> .env en cada servicio
  • completar .env real antes de pruebas de conexión
  • leer la configuración desde .env
  • versionar .env.example; nunca versionar .env

backend/.env:

PORT=4019
NODE_ENV=development

DB_HOST=192.168.222.20
DB_PORT=3306
DB_NAME=project_linkedcorp
DB_USER=project_linkedcorp
DB_PASSWORD=

JWT_SECRET=
JWT_EXPIRES=8h

# openssl rand -hex 32 — cifra secretos guardados en BD (hoy: la clave SMTP en system_settings)
ENCRYPTION_KEY=

CORS_ORIGIN=http://localhost:5196

STORAGE_ROOT=./storage

El SMTP real (para los correos de verificación/recuperación de clave) NO va en .env: lo carga el Superadministrador desde Configuración → Correo (SMTP) dentro de la app. Sin configurar, el backend degrada a modo dev: loguea el enlace en vez de enviarlo (no rompe el registro ni la recuperación).

frontend/.env:

VITE_API_URL=/api

Setup local

Backend

cd backend
npm install
npm run dev

Frontend

cd frontend
npm install
npm run dev

React + Vite — proxy de desarrollo y acceso desde el teléfono (frontend/vite.config.js): en dev, el frontend reenvía /api al backend (evita CORS) y escucha en 0.0.0.0 para probar desde el celular. En producción, cada servicio corre por separado (arquetipo B): el frontend sirve su propio dist y el backend expone /api; NPM enruta /api al backend en el dominio público.

export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',
    port: 5196,
    strictPort: true,
    proxy: { '/api': 'http://localhost:4019' },
  },
})

Verificaciones

  • Frontend responde en 5196 (http://192.168.222.20x:5196 o localhost:5196).
  • Backend responde en 4019 (curl http://localhost:4019/health).
  • Conexión a base válida (node -e "require('./src/config/db')" o el log de arranque del servidor).
  • .env.example alineado con el código (nuevas variables se agregan también ahí).