══════════════════════════════════════════════════════════════════════ 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= 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= 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)