resetea.net/public/egosurfing.html
hacklab b5ae0ceb29 UI: panel horizontal con tabs + OSINT dorking profesional (95 dorks)
- index.html: sustituye grid de bloques por 6 tabs horizontales
  (Cuentas base / Redes sociales / Mensajería / Streaming / Buscadores / Data brokers)
  con items como tarjetas en grid responsive
- egosurfing.html: dorking expandido de 12 dorks a ~95 organizados en
  10 categorías OSINT profesionales (nombre, email, teléfono, alias,
  data brokers, pastes/brechas, registros oficiales, perfil profesional,
  geolocalización, archivo histórico) con sistema de tabs dinámico
- erase.js: límites de longitud en campos opcionales (nickname 100,
  phone 30, address 300, extra 500) + type-check explícito en email

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 17:21:56 +02:00

853 lines
33 KiB
HTML

<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>RESETEA.NET · Egosurfing</title>
<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); } }
/* ── OSINT Dorking panel ── */
.dork-section { padding: 2.5rem 0 3rem; }
.dork-tip {
font-size: 0.82rem;
color: var(--muted);
background: var(--caoba-lt);
border-left: 3px solid var(--caoba);
padding: 0.55rem 1rem;
border-radius: 0 8px 8px 0;
margin-top: 0.9rem;
}
/* Tabs de categoría */
.dork-tabs {
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
border-bottom: 2px solid var(--border);
padding-bottom: 0;
margin: 1.2rem 0 0;
}
.dtab {
padding: 0.45rem 0.85rem;
border: 1px solid transparent;
border-bottom: none;
border-radius: 7px 7px 0 0;
background: none;
color: var(--muted);
font-size: 0.75rem;
font-weight: 600;
cursor: pointer;
transition: all 120ms ease;
font-family: system-ui, sans-serif;
white-space: nowrap;
position: relative;
bottom: -2px;
letter-spacing: 0.01em;
}
.dtab:hover { background: var(--surface2); color: var(--text); }
.dtab.active {
background: var(--surface2);
border-color: var(--border);
border-bottom-color: var(--surface2);
color: var(--caoba);
}
/* Grid de dorks */
.dork-pane { display: none; padding-top: 1.1rem; }
.dork-pane.active { display: block; }
.dork-items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
gap: 0.55rem;
}
.dork-item {
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto auto;
gap: 0.2rem 0.5rem;
padding: 0.6rem 0.8rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 9px;
box-shadow: var(--shadow-sm);
transition: box-shadow 150ms ease, border-color 150ms ease;
}
.dork-item:hover { box-shadow: var(--shadow-md); border-color: var(--border-dark); }
.dork-item-desc {
font-size: 0.76rem;
color: var(--text);
font-weight: 600;
grid-column: 1;
grid-row: 1;
align-self: center;
}
.dork-item-query {
font-family: 'Courier New', monospace;
font-size: 0.72rem;
color: var(--caoba);
background: var(--caoba-lt);
padding: 0.12rem 0.4rem;
border-radius: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
grid-column: 1;
grid-row: 2;
display: block;
}
.dork-run-btn {
grid-column: 2;
grid-row: 1 / 3;
align-self: center;
padding: 0.3rem 0.7rem;
border-radius: 6px;
border: 1px solid var(--border);
background: var(--surface2);
color: var(--muted);
font-size: 0.72rem;
font-weight: 600;
cursor: pointer;
white-space: nowrap;
transition: all 120ms ease;
font-family: system-ui, sans-serif;
}
.dork-run-btn:hover {
background: var(--caoba-lt);
border-color: var(--caoba);
color: var(--caoba);
}
@media (max-width: 720px) {
.dork-items { grid-template-columns: 1fr; }
.dork-tabs { gap: 0.2rem; }
.dtab { font-size: 0.68rem; padding: 0.35rem 0.6rem; }
.results-header { flex-direction: column; gap: 0.4rem; }
}
@media (max-width: 540px) {
.search-btn { padding: 0 1rem; font-size: 0.85rem; }
}
</style>
</head>
<body>
<header class="topbar">
<div class="container topbar-inner">
<div class="brand">
<div class="brand-logo">R</div>
<div class="brand-text">
<div class="brand-name">RESETEA<span>.NET</span></div>
<div class="brand-tag">Privacidad sin custodios</div>
</div>
</div>
<nav class="nav" aria-label="Navegación principal">
<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>
</header>
<main>
<!-- ══ 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="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="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>
<p class="mode-hint" id="mode-hint">Se busca entre comillas para coincidencia exacta.</p>
</div>
</div>
</section>
<!-- ══ RESULTADOS ════════════════════════════════════════════════ -->
<section class="results-section" id="results-section" hidden>
<div class="container">
<div class="results-header">
<h2>Resultados</h2>
<span class="results-query" id="results-query"></span>
</div>
<div id="results-list"></div>
</div>
</section>
<!-- ══ OSINT DORKING PROFESIONAL ════════════════════════════════ -->
<section class="dork-section info" id="dorking">
<div class="container">
<h2>OSINT dorking avanzado</h2>
<p class="section-desc">
Queries profesionales organizadas por categoría. Escribe tu dato en el buscador
y lanza cualquier query directamente. Los placeholders se sustituyen con tu input.
</p>
<div class="dork-tip">
Escribe tu nombre, email, alias o teléfono en el buscador de arriba antes de lanzar un dork.
</div>
<div class="dork-tabs" id="dork-tabs"></div>
<div id="dork-panes"></div>
</div>
</section>
<!-- ══ HERRAMIENTAS OSINT ════════════════════════════════════════ -->
<section class="info alt">
<div class="container">
<h2>Herramientas complementarias</h2>
<div class="grid" style="margin-top:1.3rem">
<div class="group">
<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>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>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>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="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>
</section>
</main>
<footer class="footer">
<div class="container">
<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);
/* ── OSINT Dorking — categorías ──────────────────────────────── */
const DORK_CATEGORIES = [
{
id: 'nombre', label: 'Nombre',
dorks: [
{ desc: 'Coincidencia exacta', tpl: '"NOMBRE APELLIDOS"' },
{ desc: 'Documentos PDF', tpl: '"NOMBRE APELLIDOS" filetype:pdf' },
{ desc: 'Documentos Word', tpl: '"NOMBRE APELLIDOS" filetype:doc OR filetype:docx' },
{ desc: 'Hojas de cálculo', tpl: '"NOMBRE APELLIDOS" filetype:xls OR filetype:xlsx OR filetype:csv' },
{ desc: 'Currículum / CV', tpl: '"NOMBRE APELLIDOS" (curriculum OR resume OR CV) filetype:pdf' },
{ desc: 'LinkedIn', tpl: '"NOMBRE APELLIDOS" site:linkedin.com' },
{ desc: 'Facebook', tpl: '"NOMBRE APELLIDOS" site:facebook.com' },
{ desc: 'Instagram', tpl: '"NOMBRE APELLIDOS" site:instagram.com' },
{ desc: 'X / Twitter', tpl: '"NOMBRE APELLIDOS" site:x.com OR site:twitter.com' },
{ desc: 'Actas y registros públicos', tpl: '"NOMBRE APELLIDOS" (acta OR padrón OR registro OR certificado)' },
{ desc: 'Noticias y prensa', tpl: '"NOMBRE APELLIDOS" (noticia OR periódico OR diario OR prensa)' },
{ desc: 'Foros y comunidades', tpl: '"NOMBRE APELLIDOS" (foro OR opinión OR comentario OR review)' },
]
},
{
id: 'email', label: 'Email',
dorks: [
{ desc: 'Exposición directa', tpl: '"EMAIL"' },
{ desc: 'Excluir webmail oficial', tpl: '"EMAIL" -site:gmail.com -site:outlook.com -site:yahoo.com' },
{ desc: 'En documentos PDF', tpl: '"EMAIL" filetype:pdf' },
{ desc: 'En bases de datos expuestas', tpl: '"EMAIL" filetype:sql OR filetype:txt OR filetype:log' },
{ desc: 'En Pastebin', tpl: '"EMAIL" site:pastebin.com' },
{ desc: 'En código fuente (GitHub)', tpl: '"EMAIL" site:github.com' },
{ desc: 'En Reddit / foros', tpl: '"EMAIL" site:reddit.com OR site:forocoches.com' },
{ desc: 'Brechas y filtraciones', tpl: '"EMAIL" (breach OR leak OR dump OR filtración OR hack)' },
{ desc: 'Registros corporativos', tpl: '"EMAIL" (empresa OR DPO OR privacidad OR contacto OR directorio)' },
]
},
{
id: 'telefono', label: 'Teléfono',
dorks: [
{ desc: 'Número exacto', tpl: '"TELEFONO"' },
{ desc: 'Directorios españoles', tpl: '"TELEFONO" site:paginas-amarillas.es OR site:11888.es OR site:axesor.es' },
{ desc: 'En documentos PDF', tpl: '"TELEFONO" filetype:pdf' },
{ desc: 'Vinculado a WhatsApp', tpl: '"TELEFONO" (WhatsApp OR wa.me OR chat)' },
{ desc: 'Vinculado a Telegram', tpl: '"TELEFONO" (Telegram OR t.me)' },
{ desc: 'Anuncios y clasificados', tpl: '"TELEFONO" site:milanuncios.com OR site:wallapop.com OR site:vibbo.com' },
{ desc: 'Registros de empresa', tpl: '"TELEFONO" (empresa OR autónomo OR contacto OR DPO)' },
{ desc: 'Reportes de fraude', tpl: '"TELEFONO" (fraude OR estafa OR scam OR spam OR phishing)' },
]
},
{
id: 'alias', label: 'Usuario / Alias',
dorks: [
{ desc: 'X / Twitter', tpl: '"ALIAS" site:x.com OR site:twitter.com' },
{ desc: 'Instagram', tpl: '"ALIAS" site:instagram.com' },
{ desc: 'Reddit', tpl: '"ALIAS" site:reddit.com' },
{ desc: 'GitHub', tpl: '"ALIAS" site:github.com' },
{ desc: 'Twitch', tpl: '"ALIAS" site:twitch.tv' },
{ desc: 'YouTube', tpl: '"ALIAS" site:youtube.com' },
{ desc: 'TikTok', tpl: '"ALIAS" site:tiktok.com' },
{ desc: 'Discord (servidores públicos)',tpl: '"ALIAS" site:discord.com OR site:discord.gg' },
{ desc: 'Steam', tpl: '"ALIAS" site:steamcommunity.com' },
{ desc: 'Mastodon / Fediverse', tpl: '"ALIAS" site:mastodon.social OR inurl:"/@ALIAS"' },
{ desc: 'Foros y comunidades', tpl: '"ALIAS" (foro OR forum OR usuario OR member OR miembro)' },
{ desc: 'LinkedIn', tpl: '"ALIAS" site:linkedin.com' },
]
},
{
id: 'brokers', label: 'Data brokers',
dorks: [
{ desc: 'Spokeo', tpl: '"NOMBRE APELLIDOS" site:spokeo.com' },
{ desc: 'Whitepages', tpl: '"NOMBRE APELLIDOS" site:whitepages.com' },
{ desc: 'Pipl', tpl: '"NOMBRE APELLIDOS" site:pipl.com' },
{ desc: '192.com', tpl: '"NOMBRE APELLIDOS" site:192.com' },
{ desc: 'Intelius', tpl: '"NOMBRE APELLIDOS" site:intelius.com' },
{ desc: 'Radaris', tpl: '"NOMBRE APELLIDOS" site:radaris.com' },
{ desc: 'PeekYou', tpl: '"NOMBRE APELLIDOS" site:peekyou.com' },
{ desc: 'BeenVerified', tpl: '"NOMBRE APELLIDOS" site:beenverified.com' },
{ desc: 'TruthFinder', tpl: '"NOMBRE APELLIDOS" site:truthfinder.com' },
{ desc: 'Directorios españoles', tpl: '"NOMBRE APELLIDOS" site:paginas-blancas.es OR site:11811.es' },
]
},
{
id: 'pastes', label: 'Pastes / Brechas',
dorks: [
{ desc: 'Email en Pastebin', tpl: '"EMAIL" site:pastebin.com' },
{ desc: 'Nombre en Pastebin', tpl: '"NOMBRE APELLIDOS" site:pastebin.com' },
{ desc: 'Servicios de paste alt.', tpl: '"EMAIL" site:justpaste.it OR site:rentry.co OR site:ghostbin.com' },
{ desc: 'SQL dumps expuestos', tpl: '"EMAIL" filetype:sql (INSERT OR dump OR database OR table)' },
{ desc: 'Credenciales expuestas', tpl: '"EMAIL" (password OR passwd OR contraseña OR hash OR credential)' },
{ desc: 'Logs de acceso expuestos', tpl: '"EMAIL" filetype:log (login OR access OR auth OR failed)' },
{ desc: 'Ficheros de texto con datos', tpl: '"EMAIL" filetype:txt (username OR user OR email OR password)' },
{ desc: 'Nombre en filtraciones', tpl: '"NOMBRE APELLIDOS" (filtración OR brecha OR RGPD OR datos personales)' },
]
},
{
id: 'registros', label: 'Registros oficiales',
dorks: [
{ desc: 'BOE (España)', tpl: '"NOMBRE APELLIDOS" site:boe.es' },
{ desc: 'BORME — Registro Mercantil', tpl: '"NOMBRE APELLIDOS" site:boe.es/borme' },
{ desc: 'Registradores.org', tpl: '"NOMBRE APELLIDOS" site:registradores.org' },
{ desc: 'AEAT — Agencia Tributaria', tpl: '"NOMBRE APELLIDOS" site:agenciatributaria.gob.es' },
{ desc: 'Actos administrativos', tpl: '"NOMBRE APELLIDOS" (acto administrativo OR notificación OR resolución OR sanción)' },
{ desc: 'Organismos públicos', tpl: '"NOMBRE APELLIDOS" site:.gob.es OR site:.gov.es' },
{ desc: 'Donaciones y financiación', tpl: '"NOMBRE APELLIDOS" (donante OR donación OR financiación OR partido político)' },
{ desc: 'Catastro y propiedades', tpl: '"NOMBRE APELLIDOS" (catastro OR propiedad OR inmueble OR hipoteca OR finca)' },
]
},
{
id: 'profesional', label: 'Perfil profesional',
dorks: [
{ desc: 'LinkedIn — perfil', tpl: '"NOMBRE APELLIDOS" site:linkedin.com/in' },
{ desc: 'CV y portfolio online', tpl: '"NOMBRE APELLIDOS" (curriculum OR CV OR portfolio OR resume) site:.es' },
{ desc: 'Publicaciones académicas', tpl: '"NOMBRE APELLIDOS" site:researchgate.net OR site:academia.edu' },
{ desc: 'Google Scholar', tpl: '"NOMBRE APELLIDOS" site:scholar.google.com' },
{ desc: 'Ponencias y conferencias', tpl: '"NOMBRE APELLIDOS" (ponencia OR conferencia OR speaker OR charla)' },
{ desc: 'Cargo directivo', tpl: '"NOMBRE APELLIDOS" (CEO OR director OR administrador OR socio OR gerente)' },
{ desc: 'Menciones en medios', tpl: '"NOMBRE APELLIDOS" (entrevista OR declaraciones OR portavoz)' },
{ desc: 'GitHub / proyectos técnicos', tpl: '"NOMBRE APELLIDOS" site:github.com OR site:gitlab.com' },
{ desc: 'Stack Overflow', tpl: '"NOMBRE APELLIDOS" site:stackoverflow.com OR site:stackexchange.com' },
]
},
{
id: 'geo', label: 'Geolocalización',
dorks: [
{ desc: 'Check-ins y ubicaciones', tpl: '"ALIAS" (check-in OR checkin OR ubicación OR location OR foursquare)' },
{ desc: 'Dirección en documentos', tpl: '"NOMBRE APELLIDOS" (calle OR dirección OR address OR código postal)' },
{ desc: 'Reseñas en Google Maps', tpl: '"NOMBRE APELLIDOS" (reseña OR review) site:maps.google.com' },
{ desc: 'Airbnb / alojamiento', tpl: '"NOMBRE APELLIDOS" site:airbnb.es OR (anfitrión OR host "NOMBRE APELLIDOS")' },
{ desc: 'Inmuebles y propiedades', tpl: '"NOMBRE APELLIDOS" (venta OR alquiler OR inmueble OR piso OR local)' },
{ desc: 'Fotos con geotag (Flickr)', tpl: '"ALIAS" site:flickr.com (geo OR location OR map OR GPS)' },
{ desc: 'Marcadores sociales', tpl: '"ALIAS" (foursquare OR swarm OR yelp OR tripadvisor)' },
]
},
{
id: 'archivo', label: 'Archivo histórico',
dorks: [
{ desc: 'Wayback Machine — nombre', tpl: 'site:web.archive.org "NOMBRE APELLIDOS"' },
{ desc: 'Wayback Machine — email', tpl: 'site:web.archive.org "EMAIL"' },
{ desc: 'Caché de buscadores', tpl: 'cache:"NOMBRE APELLIDOS"' },
{ desc: 'Contenido eliminado', tpl: '"NOMBRE APELLIDOS" (eliminado OR borrado OR deactivated OR removed)' },
{ desc: 'Menciones anteriores a 2020', tpl: '"NOMBRE APELLIDOS" before:2020-01-01' },
{ desc: 'Alias en URL de perfil', tpl: 'inurl:"ALIAS" (about OR bio OR perfil OR contacto OR me)' },
{ desc: 'Página personal / about', tpl: '"NOMBRE APELLIDOS" inurl:about OR inurl:bio OR inurl:me' },
{ desc: 'Dominio propio', tpl: 'site:"ALIAS".com OR site:"ALIAS".es OR site:"ALIAS".net' },
]
},
];
/* ── Renderizar tabs y panes ─────────────────────────────────── */
(function initDorks() {
const tabsEl = document.getElementById('dork-tabs');
const panesEl = document.getElementById('dork-panes');
DORK_CATEGORIES.forEach((cat, i) => {
/* Tab */
const tab = document.createElement('button');
tab.className = 'dtab' + (i === 0 ? ' active' : '');
tab.textContent = cat.label;
tab.dataset.cat = i;
tabsEl.appendChild(tab);
/* Pane */
const pane = document.createElement('div');
pane.className = 'dork-pane' + (i === 0 ? ' active' : '');
pane.id = 'dpane-' + i;
const grid = document.createElement('div');
grid.className = 'dork-items';
cat.dorks.forEach(d => {
const item = document.createElement('div');
item.className = 'dork-item';
item.innerHTML = `
<span class="dork-item-desc">${esc(d.desc)}</span>
<code class="dork-item-query">${esc(d.tpl)}</code>
<button class="dork-run-btn" data-template="${esc(d.tpl)}">Buscar</button>`;
grid.appendChild(item);
});
pane.appendChild(grid);
panesEl.appendChild(pane);
});
/* Tab switching */
tabsEl.addEventListener('click', e => {
const tab = e.target.closest('.dtab');
if (!tab) return;
document.querySelectorAll('.dtab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.dork-pane').forEach(p => p.classList.remove('active'));
tab.classList.add('active');
document.getElementById('dpane-' + tab.dataset.cat).classList.add('active');
});
/* Lanzar dork al hacer clic en Buscar */
panesEl.addEventListener('click', e => {
const btn = e.target.closest('.dork-run-btn');
if (!btn) return;
const val = egoInput.value.trim();
if (!val) { egoInput.focus(); egoInput.setAttribute('placeholder', '← Introduce tu dato primero'); return; }
const query = btn.dataset.template
.replace(/NOMBRE APELLIDOS/g, val)
.replace(/NOMBRE/g, val)
.replace(/ALIAS/g, val)
.replace(/EMAIL/g, val)
.replace(/TELEFONO/g, 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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
</script>
</body>
</html>