feat: rediseño UI completo + infra email + stats
This commit is contained in:
parent
93d75ddafe
commit
24401c0ee5
37 changed files with 2162 additions and 412 deletions
248
DOCS.txt
Normal file
248
DOCS.txt
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
══════════════════════════════════════════════════════════════════════
|
||||
RESETEA.NET — DOCUMENTACIÓN TÉCNICA
|
||||
Actualizado: 2026-04
|
||||
══════════════════════════════════════════════════════════════════════
|
||||
|
||||
|
||||
PUERTOS
|
||||
───────
|
||||
80 Nginx — HTTP (redirige a HTTPS automáticamente)
|
||||
443 Nginx — HTTPS (SSL/TLS, certificado Let's Encrypt)
|
||||
8787 Node.js/Express — Solo escucha en 127.0.0.1 (loopback, no expuesto)
|
||||
Nginx hace de proxy inverso: /api/* → 127.0.0.1:8787
|
||||
|
||||
⚠ El puerto 8787 NO debe abrirse en el firewall. Solo Nginx lo usa.
|
||||
|
||||
|
||||
ENDPOINTS DE LA API
|
||||
────────────────────
|
||||
Base: https://resetea.net/api/
|
||||
|
||||
POST /api/erase
|
||||
Descripción: Envía carta GDPR Art. 17 al DPO de la plataforma.
|
||||
Content-Type: application/json
|
||||
Rate limit: 10 peticiones / hora / IP
|
||||
Body:
|
||||
{
|
||||
"provider": "instagram", ← obligatorio
|
||||
"email": "tu@email.com",← obligatorio
|
||||
"nickname": "usuario123", ← opcional
|
||||
"phone": "+34 600...", ← opcional
|
||||
"address": "Calle...", ← opcional
|
||||
"extra": "Texto libre" ← opcional
|
||||
}
|
||||
Respuesta OK:
|
||||
{ "status": "ok", "message": "...", "reference": "abc123def456" }
|
||||
Respuesta proveedor sin email:
|
||||
{ "status": "use_form", "formUrl": "https://...", "reference": "..." }
|
||||
Respuesta error:
|
||||
{ "error": "descripción del error" }
|
||||
|
||||
GET /api/egosearch?q=<consulta>
|
||||
Descripción: Busca en la web menciones del término indicado.
|
||||
Rate limit: 8 peticiones / minuto / IP
|
||||
Parámetros:
|
||||
q (string, 2-150 chars) — nombre o alias a buscar
|
||||
Respuesta:
|
||||
{ "results": [ { "title", "url", "snippet", "domain", "engine" } ], "query", "total" }
|
||||
Nota: sin operadores especiales, la query se envuelve en comillas automáticamente.
|
||||
|
||||
GET /api/gmail/auth?provider=&name=&email=&...
|
||||
Descripción: Inicia flujo OAuth2 para enviar carta desde Gmail del usuario.
|
||||
Parámetros: provider, name, email (obligatorios) + nickname, phone, address, extra, requestType (opcionales)
|
||||
Respuesta: Redirect a Google OAuth2.
|
||||
Requiere: GOOGLE_CLIENT_ID y GOOGLE_CLIENT_SECRET en .env
|
||||
|
||||
GET /api/gmail/callback?code=&state=&error=
|
||||
Descripción: Callback OAuth2 de Google. Envía el email y descarta el token.
|
||||
Respuesta: Redirect a /plantillas.html?oauth=ok|cancelled|error|no_email
|
||||
|
||||
GET /api/health
|
||||
Descripción: Health check.
|
||||
Respuesta: { "status": "ok" }
|
||||
|
||||
|
||||
VARIABLES DE ENTORNO (.env en api/)
|
||||
─────────────────────────────────────
|
||||
Obligatorias:
|
||||
SALT Cadena aleatoria larga para hash de referencia de auditoría.
|
||||
Ejemplo: openssl rand -hex 32
|
||||
PORT Puerto del servidor Node.js. Por defecto: 8787
|
||||
|
||||
Opcionales — Gmail OAuth2 (sin esto el botón "Enviar desde mi Gmail" no funciona):
|
||||
GOOGLE_CLIENT_ID ID de cliente OAuth2 de Google Cloud Console
|
||||
GOOGLE_CLIENT_SECRET Secreto del cliente OAuth2
|
||||
GOOGLE_REDIRECT_URI URI de callback. Valor: https://resetea.net/api/gmail/callback
|
||||
|
||||
Opcionales — Google Custom Search (sin esto egosearch usa SearXNG):
|
||||
GOOGLE_API_KEY API Key de Google Cloud Console (Custom Search API habilitada)
|
||||
GOOGLE_CSE_ID ID del motor de búsqueda de Programmable Search Engine
|
||||
|
||||
Plantilla del archivo .env:
|
||||
SALT=<openssl rand -hex 32>
|
||||
PORT=8787
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
GOOGLE_REDIRECT_URI=https://resetea.net/api/gmail/callback
|
||||
GOOGLE_API_KEY=
|
||||
GOOGLE_CSE_ID=
|
||||
|
||||
|
||||
DEPENDENCIAS DEL BACKEND (npm)
|
||||
────────────────────────────────
|
||||
Producción (api/package.json):
|
||||
express ^4.19.2 Framework HTTP
|
||||
helmet ^7.1.0 Cabeceras de seguridad HTTP
|
||||
express-rate-limit ^7.3.1 Rate limiting por IP
|
||||
nodemailer ^6.9.13 Envío de emails via sendmail local
|
||||
googleapis ^144.0.0 Gmail API + OAuth2 (para envío desde Gmail del usuario)
|
||||
dotenv ^16.4.5 Carga de variables de entorno desde .env
|
||||
|
||||
Sin dependencias de frontend (HTML/CSS/JS puro, sin frameworks).
|
||||
|
||||
|
||||
SOFTWARE DEL SISTEMA NECESARIO
|
||||
────────────────────────────────
|
||||
Obligatorio:
|
||||
Node.js >= 18 Servidor backend
|
||||
npm >= 8 Gestor de paquetes Node
|
||||
Nginx Servidor web / proxy inverso
|
||||
Certbot (Let's Encrypt) Certificados SSL — certbot --nginx
|
||||
|
||||
Para el envío de emails (POST /api/erase):
|
||||
Un MTA (Mail Transfer Agent) local que provea /usr/sbin/sendmail.
|
||||
Opciones comunes:
|
||||
· Postfix: apt install postfix (recomendado, configurar como "Internet Site")
|
||||
· msmtp: apt install msmtp msmtp-mta (más simple, relay a servidor externo)
|
||||
· Exim4: apt install exim4
|
||||
|
||||
⚠ SIN MTA el endpoint POST /api/erase fallará silenciosamente.
|
||||
El binario /usr/sbin/sendmail debe existir en el sistema.
|
||||
Para verificar: which sendmail
|
||||
|
||||
Dominio de envío configurado en mailer.js:
|
||||
From: privacy@resetea.net
|
||||
El dominio resetea.net debe tener registros SPF/DKIM/DMARC correctos
|
||||
para que los emails no lleguen a spam.
|
||||
|
||||
|
||||
CONFIGURACIÓN DE NGINX
|
||||
───────────────────────
|
||||
Archivo: infra/nginx-resetea.conf
|
||||
Copiar en: /etc/nginx/sites-available/resetea.net
|
||||
Activar: ln -s /etc/nginx/sites-available/resetea.net /etc/nginx/sites-enabled/
|
||||
nginx -t && nginx -s reload
|
||||
|
||||
Lo que hace:
|
||||
· Puerto 80 → redirect 301 a HTTPS.
|
||||
· Puerto 443 → sirve public/ como estático.
|
||||
· /api/* → proxy a 127.0.0.1:8787 con X-Real-IP = $remote_addr.
|
||||
· Rate limit Nginx: 20 req/s por IP, burst 40 en /api/.
|
||||
· Headers de seguridad: HSTS, X-Frame-Options, CSP, Referrer-Policy,
|
||||
Permissions-Policy, COOP, X-Content-Type-Options.
|
||||
· Timeout proxy: read 15s, connect 5s.
|
||||
· server_tokens off (oculta versión de Nginx).
|
||||
|
||||
SSL (Let's Encrypt):
|
||||
certbot --nginx -d resetea.net
|
||||
Rutas de certificados:
|
||||
/etc/letsencrypt/live/resetea.net/fullchain.pem
|
||||
/etc/letsencrypt/live/resetea.net/privkey.pem
|
||||
|
||||
|
||||
FUENTES TIPOGRÁFICAS (public/fonts/)
|
||||
──────────────────────────────────────
|
||||
RECION.otf / RECION.ttf Títulos (h1, h2, h3, chips, logo)
|
||||
Italiana-Regular.ttf Alternativa serif
|
||||
CormorantGaramond-Regular.woff2 Cuerpo de texto elegante
|
||||
CormorantGaramond-Italic.woff2 Cursiva
|
||||
|
||||
|
||||
ARRANCAR EL BACKEND
|
||||
────────────────────
|
||||
cd /var/www/resetea.net/api
|
||||
npm install ← solo la primera vez o tras cambiar package.json
|
||||
node app.js ← arranque simple
|
||||
|
||||
Para producción (sin systemd todavía):
|
||||
npm install -g pm2
|
||||
pm2 start app.js --name resetea
|
||||
pm2 save
|
||||
pm2 startup ← genera el comando para arranque automático
|
||||
|
||||
Para crear un servicio systemd (recomendado):
|
||||
Crear /etc/systemd/system/resetea.service:
|
||||
[Unit]
|
||||
Description=RESETEA.NET backend
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/var/www/resetea.net/api
|
||||
ExecStart=/usr/bin/node app.js
|
||||
Restart=on-failure
|
||||
EnvironmentFile=/var/www/resetea.net/api/.env
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
systemctl enable resetea
|
||||
systemctl start resetea
|
||||
|
||||
|
||||
APIS EXTERNAS UTILIZADAS
|
||||
─────────────────────────
|
||||
SearXNG (instancias públicas — sin key, gratuito):
|
||||
Se usa como motor de búsqueda para egosurfing cuando no hay Google CSE.
|
||||
Instancias hardcodeadas en egosearch.js:
|
||||
https://searx.be
|
||||
https://priv.au
|
||||
https://search.mdosch.de
|
||||
https://searxng.site
|
||||
Se prueban en orden hasta obtener resultados. Timeout: 7s por instancia.
|
||||
|
||||
Google Custom Search API (opcional — mejora calidad de resultados):
|
||||
https://programmablesearchengine.google.com/
|
||||
https://console.cloud.google.com/ → Custom Search API
|
||||
Requiere: GOOGLE_API_KEY + GOOGLE_CSE_ID en .env
|
||||
|
||||
Google Gmail API + OAuth2 (opcional — envío desde Gmail del usuario):
|
||||
https://console.cloud.google.com/ → APIs y servicios → Gmail API
|
||||
Tipo de credencial: OAuth2, Aplicación web
|
||||
URI de redirección autorizado: https://resetea.net/api/gmail/callback
|
||||
Scope usado: https://www.googleapis.com/auth/gmail.send
|
||||
Requiere: GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET en .env
|
||||
El token es de un solo uso (access_type: 'online', no refresh token).
|
||||
|
||||
Let's Encrypt (Certbot):
|
||||
Renovación automática via cron o systemd timer.
|
||||
Verificar: certbot renew --dry-run
|
||||
|
||||
|
||||
ESTRUCTURA DE ARCHIVOS
|
||||
───────────────────────
|
||||
/var/www/resetea.net/
|
||||
public/
|
||||
index.html Panel principal
|
||||
concienciacion.html Derechos GDPR
|
||||
plantillas.html Generador de cartas (JS local)
|
||||
tipos.html Tipos de información personal
|
||||
egosurfing.html Guía OSINT + buscador integrado
|
||||
index.css Design system completo (tema cálido, caoba/salvia)
|
||||
fonts/ Tipografías locales
|
||||
api/
|
||||
app.js Entrada: Express + helmet + rate-limit + rutas
|
||||
routes/
|
||||
erase.js POST /api/erase — validación + envío GDPR
|
||||
egosearch.js GET /api/egosearch — búsqueda SearXNG/Google CSE
|
||||
gmail_oauth.js GET /api/gmail/auth y /callback — OAuth2 Gmail
|
||||
services/
|
||||
mailer.js Datos de 12 DPOs + plantilla carta Art.17 + nodemailer
|
||||
.env Variables de entorno (NO subir a git)
|
||||
package.json Dependencias npm
|
||||
infra/
|
||||
nginx-resetea.conf Config Nginx lista para copiar
|
||||
CONTEXT.txt Contexto del proyecto (este documento complementario)
|
||||
DOCS.txt Este archivo
|
||||
context_puppeteer.txt Diseño de automatización Puppeteer (pendiente)
|
||||
Loading…
Add table
Add a link
Reference in a new issue