feat(browser): auto-commit con 178 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-20 18:22:23 +02:00
parent 7d100e7f3e
commit 763e06c127
178 changed files with 19917 additions and 317 deletions
+102
View File
@@ -0,0 +1,102 @@
# Capability: browser-profiles
Catálogo operativo de los perfiles del navegador Chromium para investigaciones
multicuenta OSINT. Por cada perfil de Chromium (un `--profile-directory` dentro
de un user-data-dir) guarda **qué correo/cuentas usar, propósito, persona e
identidad de la investigación** y la nota del vault que lo documenta, y permite
**lanzar el perfil** listo para trabajar mostrando sus cuentas. La fuente de
verdad vive en el service `osint_db` (FastAPI + DuckDB, `http://127.0.0.1:8771`),
en las tablas `browser_profiles` + `browser_profile_accounts` (schema main,
pobladas solo por API, como `network_scans`). Estas funciones son clientes HTTP
finos a ese service.
**Regla de seguridad dura:** una cuenta guarda `secret_ref` — una **referencia**
al secreto (ej. `pass show osint/p1/gmail`), NUNCA la contraseña en claro. Ni el
service ni estas funciones almacenan o resuelven credenciales: `browser_profile_open`
solo expone el `secret_ref` para que el operador (o otra herramienta) lo resuelva
con `pass`/keepass.
Comparte el ecosistema del project `osint` (vault Obsidian + service `osint_db`)
con los grupos `recon`, `osint-passive` y `dav`. El perfil real de Chromium vive
en `~/.config/chromium-cdp` (user-data-dir con CDP 9222 inyectado por el wrapper
`/usr/bin/chromium`); el catálogo NO toca el perfil en disco, solo su metadata.
## Funciones
| ID | Firma | Qué hace |
|---|---|---|
| `browser_profile_register_py_browser` | `browser_profile_register(profile_dir, label="", persona="", purpose="", note_path="", tags=None, notes="", user_data_dir="", status="active", accounts=None, base_url=...) -> dict` | Registra/actualiza un perfil y, opcionalmente, sus cuentas en una sola llamada (1 POST del perfil + 1 POST por cuenta). Idempotente (upsert por `profile_dir` y por `id` de cuenta). `accounts` es una lista de dicts `{service, identity, secret_ref?, role?, status?, notes?}`. |
| `browser_profile_list_py_browser` | `browser_profile_list(status=None, base_url=...) -> dict` | Lista los perfiles del catálogo con su nº de cuentas (`n_accounts`). Filtro opcional por `status` (active/archived). Devuelve `{"status":"ok","profiles":[...]}`. |
| `browser_profile_show_py_browser` | `browser_profile_show(profile_dir, base_url=...) -> dict` | Muestra un perfil con todas sus cuentas. Devuelve `{"status":"ok","profile":{...},"accounts":[...]}` o error si no existe. Las cuentas traen `secret_ref` (referencia), nunca el password. |
| `browser_profile_open_py_browser` | `browser_profile_open(profile_dir, url=None, base_url=..., dry_run=False) -> dict` | Lanza Chromium en el perfil (`--profile-directory`) vía `systemd-run --user --scope` (evita exit-144) y devuelve sus cuentas/`secret_ref` para saber qué usar. `dry_run=True` devuelve el comando sin abrir nada. Compone `browser_profile_show` para leer la metadata. |
## Ejemplo canónico (end-to-end)
```python
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from browser.browser_profile_register import browser_profile_register
from browser.browser_profile_list import browser_profile_list
from browser.browser_profile_show import browser_profile_show
from browser.browser_profile_open import browser_profile_open
# 1. Registrar un perfil con sus cuentas (secret_ref = referencia a pass, NO el password)
browser_profile_register(
"osint_01",
label="osint_01",
persona="sock-puppet Marta R.",
purpose="infiltración foros nicho X",
tags=["osint", "sockpuppet"],
accounts=[
{"service": "gmail", "identity": "marta.r.osint@gmail.com", "secret_ref": "pass show osint/osint_01/gmail", "role": "primary"},
{"service": "twitter", "identity": "@marta_r_osint", "secret_ref": "pass show osint/osint_01/x", "role": "burner"},
],
)
# 2. Listar el catálogo
browser_profile_list() # {"status":"ok","profiles":[{profile_dir, label, n_accounts, ...}]}
# 3. Ver un perfil con sus cuentas
browser_profile_show("osint_01") # {"profile": {...}, "accounts": [{service, identity, secret_ref, role}]}
# 4. Abrir el perfil listo para trabajar (lanza Chromium + dice qué cuentas usar)
browser_profile_open("osint_01", url="https://twitter.com")
# -> systemd-run --user --scope -- chromium --profile-directory=osint_01 https://twitter.com
# -> accounts: [(gmail, pass show osint/osint_01/gmail), (twitter, pass show osint/osint_01/x)]
```
Vía `fn run` (un id conocido a la vez):
```bash
./fn run browser_profile_list
./fn run browser_profile_show osint_01
./fn run browser_profile_open osint_01 https://twitter.com
```
## Fronteras (qué NO cubre)
- **No gestiona el perfil de Chromium en disco** (crear/clonar/extensiones/avatar):
eso es `create_chrome_profile_bash_browser`, `list_chrome_profiles_go_browser`,
`set_chrome_profile_appearance_bash_browser`. Este grupo solo guarda metadata
operativa y lanza un perfil existente.
- **No almacena ni resuelve contraseñas.** Solo referencias (`secret_ref`). El
password se resuelve aparte con `pass`/keepass.
- **No automatiza el login** ni rellena formularios: para eso usa el `browser_mcp`
o el grupo `flow-replay` una vez el perfil está abierto.
- **Requiere el service `osint_db` vivo** en `:8771`. Si está caído, las funciones
devuelven `{"status":"error", ...}` sin lanzar.
## Gotchas
- El `profile_dir` es el nombre del directorio REAL del perfil de Chromium (lo
que va en `--profile-directory`): `"Default"`, `"Profile 1"`, `"osint_01"`. NO
es el nombre legible (ese es `label`). Verlos con
`list_chrome_profiles_go_browser` o el `Local State` del user-data-dir.
- `browser_profile_open` por defecto NO pasa `--user-data-dir` (el perfil vive en
`~/.config/chromium-cdp`, que el wrapper `/usr/bin/chromium` ya inyecta). Si el
perfil está en otro user-data-dir, regístralo con `user_data_dir=<ruta>` y la
función lo pasará explícito.
- Se lanza vía `systemd-run --user --scope` a propósito: lanzar Chromium directo
desde un proceso hijo da exit-144 en este entorno.
- `secret_ref` NUNCA es el password. Si te ves tentado a meter la contraseña ahí,
para: guárdala en `pass`/keepass y referencia el comando.