Egosurfing: búsqueda real de huella digital con resultados top 5
Backend: - Nuevo route GET /api/egosearch con rate limit (8 req/min) - Usa Google Custom Search API si GOOGLE_API_KEY+CSE_ID configurados - Fallback a instancias públicas SearXNG con JSON API (sin API key) - Devuelve top 5: title, url, snippet, domain, engine Frontend egosurfing.html: - Barra de búsqueda prominente con 5 modos (nombre/email/usuario/teléfono/libre) - Resultados en cards: dominio, título, snippet, acciones (ver, RTBF, GDPR) - RTBF link contextual según el dominio del resultado - Google dorking rápido: plantillas con 1 clic que se lanzan al buscador - Herramientas complementarias: HIBP, TinEye, WhatsMyName, formularios RTBF Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7507b3b8e3
commit
f1d80dde13
4 changed files with 728 additions and 392 deletions
|
|
@ -14,3 +14,10 @@ GOOGLE_REDIRECT_URI=https://resetea.net/api/gmail/callback
|
|||
|
||||
# Puerto del servidor (por defecto 8787)
|
||||
PORT=8787
|
||||
|
||||
# Google Custom Search (egosurfing — opcional, mejora la calidad de resultados)
|
||||
# 1. Ve a https://programmablesearchengine.google.com/ → crear motor
|
||||
# 2. Activa "Buscar en toda la web" y copia el ID (cx)
|
||||
# 3. En https://console.cloud.google.com/ activa "Custom Search API" y crea una API Key
|
||||
GOOGLE_API_KEY=
|
||||
GOOGLE_CSE_ID=
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const rateLimit = require('express-rate-limit');
|
|||
|
||||
const eraseRoute = require('./routes/erase');
|
||||
const gmailOAuth = require('./routes/gmail_oauth');
|
||||
const egosearch = require('./routes/egosearch');
|
||||
|
||||
const app = express();
|
||||
|
||||
|
|
@ -30,8 +31,16 @@ const emailLimit = rateLimit({
|
|||
message: { error: 'Demasiadas solicitudes de envío. Espera antes de reintentar.' }
|
||||
});
|
||||
|
||||
// ── Rate limits específicos ───────────────────────────────────────
|
||||
const searchLimit = rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minuto
|
||||
max: 8,
|
||||
message: { error: 'Demasiadas búsquedas. Espera un momento.' }
|
||||
});
|
||||
|
||||
// ── Rutas ────────────────────────────────────────────────────────
|
||||
app.post('/api/erase', emailLimit, eraseRoute);
|
||||
app.get('/api/egosearch', searchLimit, egosearch);
|
||||
app.get('/api/gmail/auth', emailLimit, gmailOAuth.authInit);
|
||||
app.get('/api/gmail/callback', gmailOAuth.authCallback);
|
||||
|
||||
|
|
|
|||
107
api/routes/egosearch.js
Normal file
107
api/routes/egosearch.js
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
'use strict';
|
||||
|
||||
/* ── Instancias públicas SearXNG con JSON API (fallback si no hay Google CSE) ── */
|
||||
const SEARX_INSTANCES = [
|
||||
'https://searx.be',
|
||||
'https://priv.au',
|
||||
'https://search.mdosch.de',
|
||||
'https://searxng.site',
|
||||
];
|
||||
|
||||
async function searchSearX(instance, query) {
|
||||
const url = `${instance}/search?` + new URLSearchParams({
|
||||
q: query,
|
||||
format: 'json',
|
||||
categories: 'general',
|
||||
language: 'es-ES',
|
||||
});
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
'User-Agent': 'resetea.net/1.0 (egosurfing privacy tool)',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
signal: AbortSignal.timeout(7000),
|
||||
});
|
||||
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const data = await res.json();
|
||||
return (data.results || []).map(r => ({
|
||||
title: r.title || '',
|
||||
url: r.url || '',
|
||||
snippet: r.content || '',
|
||||
engine: r.engine || 'web',
|
||||
}));
|
||||
}
|
||||
|
||||
async function searchGoogle(query) {
|
||||
const url = 'https://www.googleapis.com/customsearch/v1?' + new URLSearchParams({
|
||||
key: process.env.GOOGLE_API_KEY,
|
||||
cx: process.env.GOOGLE_CSE_ID,
|
||||
q: query,
|
||||
num: 10,
|
||||
hl: 'es',
|
||||
});
|
||||
|
||||
const res = await fetch(url, { signal: AbortSignal.timeout(7000) });
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({}));
|
||||
throw new Error(err.error?.message || `HTTP ${res.status}`);
|
||||
}
|
||||
const data = await res.json();
|
||||
return (data.items || []).map(item => ({
|
||||
title: item.title || '',
|
||||
url: item.link || '',
|
||||
snippet: item.snippet || '',
|
||||
engine: 'google',
|
||||
}));
|
||||
}
|
||||
|
||||
function domainOf(rawUrl) {
|
||||
try { return new URL(rawUrl).hostname.replace(/^www\./, ''); }
|
||||
catch { return ''; }
|
||||
}
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
const { q } = req.query;
|
||||
|
||||
if (!q || q.trim().length < 2)
|
||||
return res.status(400).json({ error: 'Introduce al menos 2 caracteres.' });
|
||||
|
||||
if (q.trim().length > 300)
|
||||
return res.status(400).json({ error: 'Búsqueda demasiado larga.' });
|
||||
|
||||
/* Si la query no tiene operadores especiales la ponemos entre comillas
|
||||
para forzar coincidencia exacta (ideal para nombre/email/alias). */
|
||||
const query = /[:"()]/.test(q) ? q.trim() : `"${q.trim()}"`;
|
||||
|
||||
let raw = [];
|
||||
|
||||
try {
|
||||
if (process.env.GOOGLE_API_KEY && process.env.GOOGLE_CSE_ID) {
|
||||
raw = await searchGoogle(query);
|
||||
} else {
|
||||
for (const inst of SEARX_INSTANCES) {
|
||||
try {
|
||||
raw = await searchSearX(inst, query);
|
||||
if (raw.length) break;
|
||||
} catch (e) {
|
||||
console.warn(`[egosearch] ${inst} falló:`, e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[egosearch] error final:', e.message);
|
||||
return res.status(502).json({ error: 'El servicio de búsqueda no está disponible ahora. Inténtalo de nuevo.' });
|
||||
}
|
||||
|
||||
const results = raw.slice(0, 5).map(r => ({
|
||||
title: r.title,
|
||||
url: r.url,
|
||||
snippet: r.snippet,
|
||||
domain: domainOf(r.url),
|
||||
engine: r.engine,
|
||||
}));
|
||||
|
||||
res.json({ results, query, total: raw.length });
|
||||
};
|
||||
|
|
@ -4,9 +4,296 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>RESETEA.NET · Egosurfing</title>
|
||||
<meta name="description"
|
||||
content="Egosurfing para auditoría de privacidad: dónde aparece tu nombre, alias, email, teléfono y contenido. OSINT ético orientado a autocomprobación.">
|
||||
<meta name="description" content="Busca tu nombre, alias, email o teléfono en la web y descubre dónde aparece tu información personal.">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
<style>
|
||||
/* ── Egosurfing-specific ── */
|
||||
.ego-hero {
|
||||
padding: 3rem 0 2.5rem;
|
||||
background: var(--bg);
|
||||
text-align: center;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.ego-hero h1 {
|
||||
font-size: clamp(2.4rem, 6vw, 4.2rem);
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
.ego-hero .sub {
|
||||
color: var(--muted);
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* ── Barra de búsqueda ── */
|
||||
.search-wrap {
|
||||
max-width: 680px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.search-bar {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
background: var(--surface);
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-md);
|
||||
transition: border-color 150ms ease, box-shadow 150ms ease;
|
||||
}
|
||||
.search-bar:focus-within {
|
||||
border-color: var(--caoba);
|
||||
box-shadow: 0 0 0 3px rgba(123,63,46,0.12), var(--shadow-md);
|
||||
}
|
||||
.search-input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 1rem 1.2rem;
|
||||
font-size: 1.1rem;
|
||||
background: transparent;
|
||||
color: var(--text);
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
}
|
||||
.search-input::placeholder { color: var(--subtle); }
|
||||
.search-btn {
|
||||
background: var(--caoba);
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 0 1.6rem;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 140ms ease;
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.search-btn:hover { background: var(--caoba-mid); }
|
||||
.search-btn:disabled { background: var(--border-dark); cursor: not-allowed; }
|
||||
|
||||
/* ── Modos de búsqueda ── */
|
||||
.search-modes {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
margin-top: 0.9rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.mode-btn {
|
||||
padding: 0.3rem 0.8rem;
|
||||
border-radius: 6px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
background: var(--surface);
|
||||
color: var(--muted);
|
||||
border: 1px solid var(--border);
|
||||
transition: all 120ms ease;
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
}
|
||||
.mode-btn.active, .mode-btn:hover {
|
||||
background: var(--caoba-lt);
|
||||
color: var(--caoba);
|
||||
border-color: var(--caoba);
|
||||
}
|
||||
.mode-hint {
|
||||
font-size: 0.78rem;
|
||||
color: var(--subtle);
|
||||
margin-top: 0.6rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ── Resultados ── */
|
||||
.results-section {
|
||||
padding: 2.5rem 0 3rem;
|
||||
background: var(--surface2);
|
||||
}
|
||||
.results-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.results-header h2 { margin-bottom: 0; }
|
||||
.results-query {
|
||||
font-size: 0.88rem;
|
||||
color: var(--muted);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 1.3rem 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-sm);
|
||||
transition: box-shadow 180ms ease, transform 180ms ease;
|
||||
}
|
||||
.result-card:hover {
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.result-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
margin-bottom: 0.4rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.result-domain {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
padding: 0.18rem 0.55rem;
|
||||
border-radius: 5px;
|
||||
background: var(--surface2);
|
||||
color: var(--muted);
|
||||
border: 1px solid var(--border);
|
||||
text-transform: lowercase;
|
||||
}
|
||||
.result-engine {
|
||||
font-size: 0.7rem;
|
||||
color: var(--subtle);
|
||||
}
|
||||
.result-title {
|
||||
font-family: 'Recion', 'Georgia', serif;
|
||||
font-size: 1.1rem;
|
||||
color: var(--caoba);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
margin-bottom: 0.35rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.result-title:hover { text-decoration: underline; color: var(--caoba-mid); }
|
||||
.result-url {
|
||||
font-size: 0.74rem;
|
||||
color: var(--sage);
|
||||
word-break: break-all;
|
||||
margin-bottom: 0.5rem;
|
||||
display: block;
|
||||
}
|
||||
.result-snippet {
|
||||
font-size: 0.9rem;
|
||||
color: var(--muted);
|
||||
line-height: 1.55;
|
||||
margin-bottom: 0.9rem;
|
||||
}
|
||||
.result-actions {
|
||||
display: flex;
|
||||
gap: 0.4rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.result-action {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.28rem 0.75rem;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all 120ms ease;
|
||||
font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
background: none;
|
||||
}
|
||||
.result-action--rtbf {
|
||||
background: var(--caoba-lt);
|
||||
color: var(--caoba);
|
||||
border-color: #e0c4b8;
|
||||
}
|
||||
.result-action--rtbf:hover { background: #e8cfc6; border-color: var(--caoba); }
|
||||
.result-action--gdpr {
|
||||
background: var(--sage-lt);
|
||||
color: var(--sage);
|
||||
border-color: #c0d9c8;
|
||||
}
|
||||
.result-action--gdpr:hover { background: #d2eeda; border-color: var(--sage); }
|
||||
.result-action--visit {
|
||||
background: var(--surface2);
|
||||
color: var(--muted);
|
||||
border-color: var(--border);
|
||||
}
|
||||
.result-action--visit:hover { background: var(--border); color: var(--text); }
|
||||
|
||||
/* ── Estado vacío / carga / error ── */
|
||||
.search-state {
|
||||
text-align: center;
|
||||
padding: 3rem 1rem;
|
||||
color: var(--muted);
|
||||
}
|
||||
.search-state .state-icon {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
.search-state h3 { color: var(--text); margin-bottom: 0.4rem; }
|
||||
.spinner {
|
||||
width: 36px; height: 36px;
|
||||
border: 3px solid var(--border);
|
||||
border-top-color: var(--caoba);
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
margin: 0 auto 1rem;
|
||||
}
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
|
||||
/* ── Modos de búsqueda predefinidos ── */
|
||||
.dork-section { padding: 2.5rem 0; }
|
||||
.dork-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-top: 1.5rem; }
|
||||
.dork-card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 1.1rem 1.2rem;
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.dork-card h3 { font-size: 1rem; margin-bottom: 0.6rem; }
|
||||
.dork-query {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
padding: 0.35rem 0;
|
||||
border-bottom: 1px solid var(--surface2);
|
||||
font-size: 0.82rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.dork-query:last-child { border-bottom: none; }
|
||||
.dork-query code {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--caoba);
|
||||
background: var(--caoba-lt);
|
||||
padding: 0.1rem 0.35rem;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
}
|
||||
.dork-run {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: 4px;
|
||||
transition: all 120ms ease;
|
||||
flex-shrink: 0;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
.dork-run:hover { background: var(--surface2); color: var(--text); }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.dork-grid { grid-template-columns: 1fr; }
|
||||
.results-header { flex-direction: column; gap: 0.4rem; }
|
||||
}
|
||||
@media (max-width: 540px) {
|
||||
.search-btn { padding: 0 1rem; font-size: 0.85rem; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
@ -20,11 +307,10 @@
|
|||
<div class="brand-tag">Privacidad sin custodios</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav" aria-label="Navegación principal">
|
||||
<a class="nav-btn" href="tipos.html">Tipos de información</a>
|
||||
<a class="nav-btn" href="concienciacion.html">Concienciación</a>
|
||||
<a class="nav-btn" href="index.html">Resetea</a>
|
||||
<a class="nav-btn" href="tipos.html">Tipos de info</a>
|
||||
<a class="nav-btn" href="concienciacion.html">Concienciación</a>
|
||||
<a class="nav-btn nav-btn--primary" href="egosurfing.html">Egosurfing</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
|
@ -32,227 +318,110 @@
|
|||
|
||||
<main>
|
||||
|
||||
<section class="hero">
|
||||
<div class="container hero-inner">
|
||||
<div class="hero-text">
|
||||
<h1>Egosurfing<br>Auditoría OSINT de tu huella.</h1>
|
||||
<p>
|
||||
El objetivo no es “investigar a otros”, sino <strong>identificar tu exposición</strong>
|
||||
(nombre, alias, email, teléfono, fotos, documentos, perfiles, directorios).
|
||||
Con esto decides qué borrar, qué desindexar y qué blindar.
|
||||
</p>
|
||||
<!-- ══ HERO / BUSCADOR ══════════════════════════════════════════ -->
|
||||
<section class="ego-hero">
|
||||
<div class="container">
|
||||
<h1>Egosurfing</h1>
|
||||
<p class="sub">Descubre en qué páginas aparece tu información personal.</p>
|
||||
|
||||
<div class="hero-actions">
|
||||
<a class="btn primary" href="#checklist">Checklist</a>
|
||||
<a class="btn ghost" href="#dorking">Google dorking (privacidad)</a>
|
||||
<div class="search-wrap">
|
||||
<div class="search-bar">
|
||||
<input type="text" id="ego-input" class="search-input"
|
||||
placeholder="Tu nombre, alias, email o teléfono…"
|
||||
autocomplete="off" spellcheck="false" maxlength="200">
|
||||
<button class="search-btn" id="ego-btn">Buscar</button>
|
||||
</div>
|
||||
|
||||
<div class="notice">
|
||||
<strong>Uso ético y seguro:</strong><br>
|
||||
Estas técnicas están pensadas para <strong>autocomprobación</strong> y
|
||||
control de reputación. Evita búsquedas invasivas sobre terceros
|
||||
y respeta términos de servicio y legislación.
|
||||
<div class="search-modes">
|
||||
<button class="mode-btn active" data-mode="nombre">Nombre</button>
|
||||
<button class="mode-btn" data-mode="email">Email</button>
|
||||
<button class="mode-btn" data-mode="usuario">Usuario/Alias</button>
|
||||
<button class="mode-btn" data-mode="telefono">Teléfono</button>
|
||||
<button class="mode-btn" data-mode="libre">Búsqueda libre</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-card" aria-label="Resumen rápido">
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="stat-num">4</div>
|
||||
<div class="stat-label">Ejes</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-num">∞</div>
|
||||
<div class="stat-label">Pivotes</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-num">1</div>
|
||||
<div class="stat-label">Meta</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="steps">
|
||||
<li><span>1</span> Identificadores</li>
|
||||
<li><span>2</span> Perfiles</li>
|
||||
<li><span>3</span> Brokers/Indexadores</li>
|
||||
</ul>
|
||||
<p class="mode-hint" id="mode-hint">Se busca entre comillas para coincidencia exacta.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="checklist" class="panel">
|
||||
<!-- ══ RESULTADOS ════════════════════════════════════════════════ -->
|
||||
<section class="results-section" id="results-section" hidden>
|
||||
<div class="container">
|
||||
<h2>Checklist de pivotes (tu “llavero” de búsqueda)</h2>
|
||||
<p class="section-desc">
|
||||
Antes de buscar, define tus pivotes. Cada pivot debe probarse con y sin comillas,
|
||||
con variantes y con contexto (ciudad, empresa, nickname, etc.).
|
||||
</p>
|
||||
|
||||
<div class="grid">
|
||||
<div class="group">
|
||||
<h3>Identificadores directos</h3>
|
||||
<div class="item"><label><input type="checkbox"> Nombre + apellidos (variantes / tildes)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Alias/nick habitual(es)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Email(s) actual(es) y antiguo(s)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Teléfono(s) (con prefijo y sin)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Ciudad / barrio / provincia (si aplica)</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Contexto útil</h3>
|
||||
<div class="item"><label><input type="checkbox"> Empresa/sector y cargos</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Centros (estudios, eventos, clubes)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Proyectos, repos, nicks en dev</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Fotos públicas (avatares, thumbnails)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Documentos publicados (PDF, docx)</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Metadatos y correlación</h3>
|
||||
<div class="item"><label><input type="checkbox"> Usernames repetidos en plataformas</label></div>
|
||||
<div class="item"><label><input type="checkbox"> URLs antiguas (blogs, perfiles, directorios)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Bio/“about” (frases únicas)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Emails “enmascarados” o aliases</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Fotos con EXIF (si hubo subidas)</label></div>
|
||||
</div>
|
||||
<div class="results-header">
|
||||
<h2>Resultados</h2>
|
||||
<span class="results-query" id="results-query"></span>
|
||||
</div>
|
||||
<div id="results-list"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="osint" class="info alt">
|
||||
<!-- ══ GOOGLE DORKING RÁPIDO ════════════════════════════════════ -->
|
||||
<section class="dork-section info" id="dorking">
|
||||
<div class="container">
|
||||
<h2>OSINT: buscadores, directorios y herramientas (orientado a autocomprobación)</h2>
|
||||
<p>
|
||||
Lista práctica de recursos habituales. Algunas plataformas cambian o restringen acceso;
|
||||
usa siempre canales oficiales y respeta ToS.
|
||||
<h2>Google dorking — haz clic para buscar</h2>
|
||||
<p class="section-desc">
|
||||
Introduce tus datos en el buscador de arriba y usa estas queries avanzadas.
|
||||
Haz clic en "Buscar" para lanzarlas directamente.
|
||||
</p>
|
||||
|
||||
<div class="grid" style="margin-top: 1.5rem;">
|
||||
<div class="group">
|
||||
<h3>Directorios OSINT (curados)</h3>
|
||||
<p class="section-desc">
|
||||
Catálogos amplios para navegar por categorías: redes, personas, imágenes, dominios, etc.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Awesome OSINT (GitHub)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://github.com/jivoi/awesome-osint">Abrir</a>
|
||||
<div class="dork-grid">
|
||||
|
||||
<div class="dork-card">
|
||||
<h3>Nombre completo</h3>
|
||||
<div class="dork-query">
|
||||
<code>"NOMBRE APELLIDOS"</code>
|
||||
<button class="dork-run" data-template='"NOMBRE APELLIDOS"'>Buscar</button>
|
||||
</div>
|
||||
<div class="dork-query">
|
||||
<code>"NOMBRE" filetype:pdf</code>
|
||||
<button class="dork-run" data-template='"NOMBRE" filetype:pdf'>Buscar</button>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> OSINT Tools Directory</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://think-pol.com/tools">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> IntelTechniques (recursos OSINT)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://inteltechniques.com/">Abrir</a>
|
||||
<div class="dork-query">
|
||||
<code>"NOMBRE" site:linkedin.com</code>
|
||||
<button class="dork-run" data-template='"NOMBRE" site:linkedin.com'>Buscar</button>
|
||||
</div>
|
||||
<div class="dork-query">
|
||||
<code>"NOMBRE" site:facebook.com</code>
|
||||
<button class="dork-run" data-template='"NOMBRE" site:facebook.com'>Buscar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Enumeración de usernames</h3>
|
||||
<p class="section-desc">
|
||||
Útil para saber si tu nick existe en otros sitios (reutilización de alias).
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> WhatsMyName</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://whatsmyname.app/">Abrir</a>
|
||||
<div class="dork-card">
|
||||
<h3>Email y teléfono</h3>
|
||||
<div class="dork-query">
|
||||
<code>"EMAIL"</code>
|
||||
<button class="dork-run" data-template='"EMAIL"'>Buscar</button>
|
||||
</div>
|
||||
<div class="dork-query">
|
||||
<code>"EMAIL" -site:gmail.com</code>
|
||||
<button class="dork-run" data-template='"EMAIL" -site:gmail.com'>Buscar</button>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> Sherlock (CLI)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://github.com/sherlock-project/sherlock">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> Namechk (disponibilidad de usuario)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://namechk.com/">Abrir</a>
|
||||
<div class="dork-query">
|
||||
<code>"TELEFONO"</code>
|
||||
<button class="dork-run" data-template='"TELEFONO"'>Buscar</button>
|
||||
</div>
|
||||
<div class="dork-query">
|
||||
<code>"TELEFONO" filetype:pdf</code>
|
||||
<button class="dork-run" data-template='"TELEFONO" filetype:pdf'>Buscar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Emails, brechas y exposición</h3>
|
||||
<p class="section-desc">
|
||||
Diagnóstico de filtraciones asociadas a tu email (si aplica, con cuidado).
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Have I Been Pwned</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://haveibeenpwned.com/">Abrir</a>
|
||||
<div class="dork-card">
|
||||
<h3>Usuario / alias</h3>
|
||||
<div class="dork-query">
|
||||
<code>"ALIAS" site:twitter.com</code>
|
||||
<button class="dork-run" data-template='"ALIAS" site:twitter.com'>Buscar</button>
|
||||
</div>
|
||||
<div class="dork-query">
|
||||
<code>"ALIAS" site:instagram.com</code>
|
||||
<button class="dork-run" data-template='"ALIAS" site:instagram.com'>Buscar</button>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> Firefox Monitor</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://monitor.mozilla.org/">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Personas y perfiles públicos</h3>
|
||||
<p class="section-desc">
|
||||
Búsqueda de perfiles públicos y menciones en la web abierta.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Social Searcher</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://www.social-searcher.com/">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> Pipl (enfoque people search; suele ser comercial)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://pipl.com/">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> DuckDuckGo / Brave Search (alternativas)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://duckduckgo.com/">DuckDuckGo</a>
|
||||
<a target="_blank" rel="noopener" href="https://search.brave.com/">Brave</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Imágenes y “reverse image search”</h3>
|
||||
<p class="section-desc">
|
||||
Encuentra reusos de tus fotos/avatares o imágenes asociadas.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Google Images</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://images.google.com/">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> Bing Visual Search</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://www.bing.com/visualsearch">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> TinEye</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://tineye.com/">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> Yandex Images (cobertura diferente)</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://yandex.com/images/">Abrir</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Repositorios y dev</h3>
|
||||
<p class="section-desc">
|
||||
Exposición por commits, issues, gists y perfiles de desarrollador.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> GitHub</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://github.com/search">Buscar</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item"><label><input type="checkbox"> GitLab</label>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://gitlab.com/search">Buscar</a>
|
||||
<div class="dork-query">
|
||||
<code>"ALIAS" site:reddit.com</code>
|
||||
<button class="dork-run" data-template='"ALIAS" site:reddit.com'>Buscar</button>
|
||||
</div>
|
||||
<div class="dork-query">
|
||||
<code>"ALIAS" site:github.com</code>
|
||||
<button class="dork-run" data-template='"ALIAS" site:github.com'>Buscar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -260,175 +429,61 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<section id="dorking" class="info">
|
||||
<!-- ══ HERRAMIENTAS OSINT ════════════════════════════════════════ -->
|
||||
<section class="info alt">
|
||||
<div class="container">
|
||||
<h2>Google dorking (orientado a privacidad y autodiagnóstico)</h2>
|
||||
<p>
|
||||
Aquí solo incluimos consultas útiles para encontrar <strong>tu propia exposición</strong>
|
||||
(perfiles, documentos públicos, menciones, duplicados, indexación). Evitamos queries
|
||||
orientadas a vulnerabilidades o intrusión.
|
||||
</p>
|
||||
<h2>Herramientas complementarias</h2>
|
||||
<div class="grid" style="margin-top:1.3rem">
|
||||
|
||||
<div class="grid" style="margin-top: 1.5rem;">
|
||||
<div class="group">
|
||||
<h3>Base</h3>
|
||||
<p class="section-desc">Sustituye: <strong>NOMBRE</strong>, <strong>ALIAS</strong>, <strong>EMAIL</strong>, <strong>TEL</strong>.</p>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE APELLIDOS"</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "ALIAS" (con comillas)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "EMAIL"</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "TEL" (con prefijo y sin)</label></div>
|
||||
<h3>Brechas y email</h3>
|
||||
<div class="item">
|
||||
<label>Have I Been Pwned</label>
|
||||
<div class="actions"><a href="https://haveibeenpwned.com/" target="_blank" rel="noopener">Verificar</a></div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>Firefox Monitor</label>
|
||||
<div class="actions"><a href="https://monitor.mozilla.org/" target="_blank" rel="noopener">Verificar</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Documentos públicos</h3>
|
||||
<p class="section-desc">Detecta PDFs/Docs con tu nombre, CVs, listados, actas, etc.</p>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" filetype:pdf</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" filetype:doc OR filetype:docx</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" filetype:xls OR filetype:xlsx</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "EMAIL" filetype:pdf</label></div>
|
||||
<h3>Usernames</h3>
|
||||
<div class="item">
|
||||
<label>WhatsMyName</label>
|
||||
<div class="actions"><a href="https://whatsmyname.app/" target="_blank" rel="noopener">Buscar</a></div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>Namechk</label>
|
||||
<div class="actions"><a href="https://namechk.com/" target="_blank" rel="noopener">Buscar</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Perfiles en redes</h3>
|
||||
<p class="section-desc">Localiza perfiles y menciones públicas por dominio.</p>
|
||||
<div class="item"><label><input type="checkbox"> site:linkedin.com/in "NOMBRE"</label></div>
|
||||
<div class="item"><label><input type="checkbox"> site:twitter.com "ALIAS"</label></div>
|
||||
<div class="item"><label><input type="checkbox"> site:instagram.com "ALIAS"</label></div>
|
||||
<div class="item"><label><input type="checkbox"> site:facebook.com "NOMBRE"</label></div>
|
||||
<h3>Imágenes</h3>
|
||||
<div class="item">
|
||||
<label>TinEye (búsqueda inversa)</label>
|
||||
<div class="actions"><a href="https://tineye.com/" target="_blank" rel="noopener">Abrir</a></div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>Yandex Images</label>
|
||||
<div class="actions"><a href="https://yandex.com/images/" target="_blank" rel="noopener">Abrir</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Menciones y citas</h3>
|
||||
<p class="section-desc">Ideal para entrevistas, notas de prensa, eventos, ponencias.</p>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" AND ("entrevista" OR "ponencia" OR "congreso")</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" AND ("CV" OR "curriculum" OR "biografía")</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" -site:tuweb.com</label></div>
|
||||
<h3>Desindexación</h3>
|
||||
<div class="item">
|
||||
<label>Google — Derecho al olvido</label>
|
||||
<div class="actions"><a href="https://reportcontent.google.com/forms/rtbf" target="_blank" rel="noopener">Formulario</a></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Fotos</h3>
|
||||
<p class="section-desc">Encuentra páginas donde tu imagen o nombre se asocia.</p>
|
||||
<div class="item"><label><input type="checkbox"> "NOMBRE" (jpg OR jpeg OR png)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> "ALIAS" (avatar OR "profile picture")</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Operadores útiles (legibles)</h3>
|
||||
<p class="section-desc">Combinables para refinar sin “modo intrusión”.</p>
|
||||
<div class="item"><label><input type="checkbox"> site: (restringe a un dominio)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> filetype: (tipo de fichero)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> intitle: (título de página)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> inurl: (URL contiene)</label></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="terceros" class="info alt">
|
||||
<div class="container">
|
||||
<h2>Terceros por vertical (dónde se generan “copias” de ti)</h2>
|
||||
<p>
|
||||
Muchas veces tu exposición no viene “solo” de redes sociales. Viene de
|
||||
<strong>terceros</strong> (proveedores, socios, analítica, brokers, agregadores,
|
||||
directorios sectoriales) que crean perfiles y vínculos.
|
||||
</p>
|
||||
|
||||
<div class="grid" style="margin-top: 1.5rem;">
|
||||
<div class="group">
|
||||
<h3>Redes sociales & AdTech</h3>
|
||||
<p class="section-desc">
|
||||
Pixel/tags, SDKs en apps, conversion APIs, audiencias, lookalikes, atribución.
|
||||
El identificador suele ser email/teléfono “hasheado” + device ID.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Permisos de apps / SDKs</label></div>
|
||||
<div class="item"><label><input type="checkbox"> “Contact discovery” (agenda subida)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Píxeles en tiendas, newsletters, medios</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Salud & fitness</h3>
|
||||
<p class="section-desc">
|
||||
Apps de salud, wearables, gimnasios, seguros, farmacias, nutrición.
|
||||
Suelen acumular hábitos, ubicación, rutinas, y “metas” personales.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Apps / wearables (cuentas y permisos)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Servicios de citas médicas / portales</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Newsletters / comunidades</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Bancos & pagos</h3>
|
||||
<p class="section-desc">
|
||||
Datos regulados, pero existen “capas” alrededor: fintechs, pasarelas,
|
||||
scoring, antifraude, comercios y programas de fidelización.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Cuentas fintech / wallets</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Pasarelas y recibos en comercios</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Emails transaccionales (exposición indirecta)</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Comercio & e-commerce</h3>
|
||||
<p class="section-desc">
|
||||
Direcciones, teléfonos, preferencias, devoluciones, reseñas, tickets.
|
||||
Mucho se replica a marketing, logística y atención al cliente.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Marketplaces (perfil público y reseñas)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Logística (tracking y etiquetas)</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Programas de fidelización</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Deporte & eventos</h3>
|
||||
<p class="section-desc">
|
||||
Entradas, acreditaciones, listas de participantes, fotos oficiales,
|
||||
redes del evento, sponsors, plataformas de registro.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Fotos y listados de participantes</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Plataformas de ticketing</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Patrocinadores / partners</label></div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h3>Data brokers / people search</h3>
|
||||
<p class="section-desc">
|
||||
Agregan datos y los re-venden. Si tu objetivo es “desaparecer”, esta capa
|
||||
suele requerir opt-outs repetidos y verificación.
|
||||
</p>
|
||||
<div class="item"><label><input type="checkbox"> Solicitudes opt-out / supresión</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Desindexación de resultados replicados</label></div>
|
||||
<div class="item"><label><input type="checkbox"> Vigilancia continua (auditoría periódica)</label></div>
|
||||
<div class="actions">
|
||||
<a target="_blank" rel="noopener" href="https://incogni.com/">Incogni (referencia de mercado)</a>
|
||||
<a target="_blank" rel="noopener" href="https://joindeleteme.com/sites-we-remove-from/">DeleteMe (lista pública)</a>
|
||||
<div class="item">
|
||||
<label>Bing — Eliminar contenido</label>
|
||||
<div class="actions"><a href="https://www.bing.com/webmasters/tools/content-removal" target="_blank" rel="noopener">Formulario</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="notice" style="margin-top: 1.5rem;">
|
||||
<strong>Nota operativa:</strong><br>
|
||||
Muchos brokers esconden las páginas de opt-out o las entierran en políticas.
|
||||
Cuando estés listo para “Resetea”, conviene mantener un catálogo propio
|
||||
de enlaces oficiales y plantillas.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="cierre" class="info">
|
||||
<div class="container">
|
||||
<h2>Resultado esperado del egosurfing</h2>
|
||||
<p>
|
||||
Al finalizar, deberías tener una lista simple:
|
||||
<strong>(1) dónde apareces</strong>, <strong>(2) qué identificador lo vincula</strong>,
|
||||
<strong>(3) si es origen o copia</strong>, <strong>(4) la acción</strong>
|
||||
(borrar en origen, solicitar supresión, desindexar, o dejar).
|
||||
</p>
|
||||
<p style="margin-top: 0.8rem;">
|
||||
Cuando quieras, convertimos este diagnóstico en un flujo “Resetea” por pasos
|
||||
(sin automatización peligrosa, con seguridad por defecto).
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -436,11 +491,169 @@
|
|||
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<p>
|
||||
RESETEA.NET · Egosurfing · Estático · Sin cookies
|
||||
</p>
|
||||
<p>RESETEA.NET · Egosurfing · Sin cookies · Sin almacenamiento de búsquedas</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
/* ── Modos de búsqueda ──────────────────────────────────────── */
|
||||
const MODES = {
|
||||
nombre: { hint: 'Se busca entre comillas para coincidencia exacta.', placeholder: 'Nombre Apellido…' },
|
||||
email: { hint: 'Se busca el email exacto en la web abierta.', placeholder: 'tu@correo.com…' },
|
||||
usuario: { hint: 'Se busca el alias exacto en redes y webs.', placeholder: '@usuario o alias…' },
|
||||
telefono: { hint: 'Se busca el número en la web (con y sin prefijo).', placeholder: '+34 612 345 678…' },
|
||||
libre: { hint: 'Búsqueda libre: usa operadores como site:, filetype:…', placeholder: '"término" site:dominio.com…' },
|
||||
};
|
||||
|
||||
let currentMode = 'nombre';
|
||||
|
||||
const modeBtns = document.querySelectorAll('.mode-btn');
|
||||
const modeHint = document.getElementById('mode-hint');
|
||||
const egoInput = document.getElementById('ego-input');
|
||||
const egoBtn = document.getElementById('ego-btn');
|
||||
const resultsSec = document.getElementById('results-section');
|
||||
const resultsQuery = document.getElementById('results-query');
|
||||
const resultsList = document.getElementById('results-list');
|
||||
|
||||
modeBtns.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
currentMode = btn.dataset.mode;
|
||||
modeBtns.forEach(b => b.classList.toggle('active', b === btn));
|
||||
modeHint.textContent = MODES[currentMode].hint;
|
||||
egoInput.placeholder = MODES[currentMode].placeholder;
|
||||
egoInput.focus();
|
||||
});
|
||||
});
|
||||
|
||||
egoInput.addEventListener('keydown', e => { if (e.key === 'Enter') doSearch(); });
|
||||
egoBtn.addEventListener('click', doSearch);
|
||||
|
||||
/* ── Dorking rápido ─────────────────────────────────────────── */
|
||||
document.querySelectorAll('.dork-run').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const val = egoInput.value.trim();
|
||||
if (!val) { egoInput.focus(); egoInput.placeholder = '← Primero introduce tu dato aquí'; return; }
|
||||
|
||||
/* Rellena el template con el valor del input */
|
||||
const template = btn.dataset.template;
|
||||
const query = template
|
||||
.replace('NOMBRE APELLIDOS', val)
|
||||
.replace('NOMBRE', val)
|
||||
.replace('ALIAS', val)
|
||||
.replace('EMAIL', val)
|
||||
.replace('TELEFONO', val);
|
||||
|
||||
egoInput.value = query;
|
||||
currentMode = 'libre';
|
||||
modeBtns.forEach(b => b.classList.toggle('active', b.dataset.mode === 'libre'));
|
||||
modeHint.textContent = MODES.libre.hint;
|
||||
doSearch();
|
||||
});
|
||||
});
|
||||
|
||||
/* ── Búsqueda ───────────────────────────────────────────────── */
|
||||
async function doSearch() {
|
||||
const raw = egoInput.value.trim();
|
||||
if (!raw) { egoInput.focus(); return; }
|
||||
|
||||
resultsSec.hidden = false;
|
||||
resultsList.innerHTML = `
|
||||
<div class="search-state">
|
||||
<div class="spinner"></div>
|
||||
<p>Buscando en la web…</p>
|
||||
</div>`;
|
||||
resultsQuery.textContent = '';
|
||||
egoBtn.disabled = true;
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/egosearch?' + new URLSearchParams({ q: raw }));
|
||||
const data = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
showError(data.error || 'Error desconocido.');
|
||||
return;
|
||||
}
|
||||
|
||||
resultsQuery.textContent = data.query;
|
||||
renderResults(data.results);
|
||||
|
||||
} catch {
|
||||
showError('Error de red. Comprueba tu conexión e inténtalo de nuevo.');
|
||||
} finally {
|
||||
egoBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function renderResults(results) {
|
||||
if (!results || results.length === 0) {
|
||||
resultsList.innerHTML = `
|
||||
<div class="search-state">
|
||||
<div class="state-icon">🔍</div>
|
||||
<h3>Sin resultados visibles</h3>
|
||||
<p>No se encontraron menciones públicas. Eso es una buena señal.<br>
|
||||
Prueba variantes de tu nombre o usa los dorks de abajo.</p>
|
||||
</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
resultsList.innerHTML = results.map((r, i) => {
|
||||
const rtbfUrl = rtbfLink(r.url);
|
||||
return `
|
||||
<div class="result-card">
|
||||
<div class="result-top">
|
||||
<span class="result-domain">${esc(r.domain || '—')}</span>
|
||||
<span class="result-engine">vía ${esc(r.engine || 'web')}</span>
|
||||
</div>
|
||||
<a class="result-title" href="${esc(r.url)}" target="_blank" rel="noopener noreferrer">
|
||||
${esc(r.title) || '(sin título)'}
|
||||
</a>
|
||||
<span class="result-url">${esc(r.url)}</span>
|
||||
${r.snippet ? `<p class="result-snippet">${esc(r.snippet)}</p>` : ''}
|
||||
<div class="result-actions">
|
||||
<a class="result-action result-action--visit" href="${esc(r.url)}" target="_blank" rel="noopener noreferrer">
|
||||
Ver página
|
||||
</a>
|
||||
${rtbfUrl ? `<a class="result-action result-action--rtbf" href="${rtbfUrl}" target="_blank" rel="noopener noreferrer">
|
||||
Solicitar eliminación
|
||||
</a>` : ''}
|
||||
<a class="result-action result-action--gdpr" href="plantillas.html" target="_blank">
|
||||
Carta GDPR
|
||||
</a>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function rtbfLink(url) {
|
||||
try {
|
||||
const host = new URL(url).hostname;
|
||||
if (host.includes('google.')) return 'https://reportcontent.google.com/forms/rtbf';
|
||||
if (host.includes('bing.')) return 'https://www.bing.com/webmasters/tools/content-removal';
|
||||
if (host.includes('yahoo.')) return 'https://io.help.yahoo.com/contact/index?page=contact';
|
||||
} catch {}
|
||||
/* Para cualquier otro dominio: derecho al olvido Google */
|
||||
return 'https://reportcontent.google.com/forms/rtbf';
|
||||
}
|
||||
|
||||
function showError(msg) {
|
||||
resultsList.innerHTML = `
|
||||
<div class="search-state">
|
||||
<div class="state-icon">⚠️</div>
|
||||
<h3>Error en la búsqueda</h3>
|
||||
<p>${esc(msg)}</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function esc(str) {
|
||||
return String(str ?? '')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue