# Issue #004: Administración de extensiones de Chrome **Tipo**: Enhancement **Prioridad**: Media **Estado**: Pendiente ## Descripción Implementar sistema completo para cargar, gestionar y configurar extensiones de Chrome en perfiles de navegador. ## Funcionalidad deseada ### Carga de extensiones - Cargar extensiones desde archivos `.crx` (empaquetadas) - Cargar extensiones desempaquetadas (carpetas) - Cargar múltiples extensiones simultáneamente - Especificar extensiones en configuración de perfil ### Gestión de extensiones - Listar extensiones instaladas en perfil - Habilitar/deshabilitar extensiones - Desinstalar extensiones - Actualizar extensiones - Obtener información de extensión (nombre, versión, ID) ### Extensiones predefinidas - Configuraciones para extensiones populares - uBlock Origin - bloqueador de ads - Tampermonkey - userscripts - Cookie editors - Proxy switchers - User-agent switchers ### Configuración de extensiones - Establecer configuración de extensión desde código - Importar/exportar configuraciones - Templates de configuración para casos comunes ## Implementación técnica ### Archivo sugerido `pkg/browser/extensions.go` ### Flags de Chrome necesarias ```go // Cargar extensión específica "--load-extension=/path/to/extension" // Cargar múltiples extensiones "--load-extension=/path/ext1,/path/ext2,/path/ext3" // Deshabilitar todas excepto las especificadas "--disable-extensions-except=/path/ext1,/path/ext2" // Desempaquetar y cargar .crx "--load-extension=/path/to/extension.crx" ``` ### API propuesta ```go // === Configuración de extensiones === type ExtensionConfig struct { Path string // Ruta a extensión (carpeta o .crx) ID string // ID de extensión (opcional) Enabled bool // Habilitada por defecto Settings map[string]string // Configuración específica } // Config.Extensions - campo para extensiones type Config struct { // ... campos existentes ... Extensions []*ExtensionConfig // Extensiones a cargar DisableOtherExts bool // Deshabilitar extensiones no especificadas } // === Gestión en runtime === // Extension representa una extensión instalada type Extension struct { ID string Name string Version string Path string Enabled bool Description string } // ListExtensions lista extensiones instaladas en el navegador actual func (b *Browser) ListExtensions(ctx context.Context) ([]*Extension, error) // LoadExtension carga una extensión en runtime func (b *Browser) LoadExtension(ctx context.Context, path string) (*Extension, error) // EnableExtension habilita una extensión func (b *Browser) EnableExtension(ctx context.Context, extensionID string) error // DisableExtension deshabilita una extensión func (b *Browser) DisableExtension(ctx context.Context, extensionID string) error // RemoveExtension desinstala una extensión func (b *Browser) RemoveExtension(ctx context.Context, extensionID string) error // GetExtensionSettings obtiene configuración de una extensión func (b *Browser) GetExtensionSettings(ctx context.Context, extensionID string) (map[string]interface{}, error) // SetExtensionSettings establece configuración de extensión func (b *Browser) SetExtensionSettings(ctx context.Context, extensionID string, settings map[string]interface{}) error // === Extensiones predefinidas === // PresetExtensions contiene configuraciones de extensiones populares var PresetExtensions = map[string]*ExtensionConfig{ "ublock-origin": { Path: "~/.navegator/extensions/ublock-origin", ID: "cjpalhdlnbpafiamejdnhcphjbkeiagm", }, "tampermonkey": { Path: "~/.navegator/extensions/tampermonkey", ID: "dhdgffkkebhmkfjojejmpbldmpobfkfo", }, } // LoadPresetExtension carga una extensión predefinida func LoadPresetExtension(name string) (*ExtensionConfig, error) ``` ### Estructura de directorio de extensiones ``` ~/.navegator/ ├── profiles/ │ └── / │ └── Extensions/ # Extensiones instaladas del perfil │ └── / │ └── / └── extensions/ # Extensiones compartidas ├── ublock-origin/ │ ├── manifest.json │ └── ... └── tampermonkey/ ├── manifest.json └── ... ``` ## Casos de uso ### Caso 1: Lanzar con uBlock Origin ```go config := browser.DefaultConfig() config.Extensions = []*browser.ExtensionConfig{ {Path: "/path/to/ublock-origin"}, } b, _ := browser.Launch(ctx, config) ``` ### Caso 2: Cargar extensión en runtime ```go ext, _ := b.LoadExtension(ctx, "/path/to/extension") log.Printf("Cargada: %s v%s\n", ext.Name, ext.Version) ``` ### Caso 3: Usar extensión predefinida ```go config := browser.DefaultConfig() ublock, _ := browser.LoadPresetExtension("ublock-origin") config.Extensions = []*browser.ExtensionConfig{ublock} b, _ := browser.Launch(ctx, config) ``` ### Caso 4: Gestionar extensiones existentes ```go // Listar todas exts, _ := b.ListExtensions(ctx) for _, ext := range exts { log.Printf("%s: %s\n", ext.Name, ext.Enabled) } // Deshabilitar extensión específica b.DisableExtension(ctx, "extension-id-here") ``` ### Caso 5: Configurar extensión ```go // Configurar uBlock Origin con listas personalizadas b.SetExtensionSettings(ctx, "cjpalhdlnbpafiamejdnhcphjbkeiagm", map[string]interface{}{ "customFilterLists": []string{ "https://example.com/my-filters.txt", }, }) ``` ## Extensiones útiles para automatización ### Stealth y anti-detección - **Buster**: Solver de CAPTCHAs - **User-Agent Switcher**: Cambiar user agent - **Canvas Fingerprint Defender**: Anti-fingerprinting ### Scraping - **uBlock Origin**: Bloquear ads y trackers - **Cookie Editor**: Gestión avanzada de cookies - **Header Editor**: Modificar headers HTTP ### Automatización - **Tampermonkey**: Ejecutar userscripts personalizados - **Violentmonkey**: Alternativa a Tampermonkey ### Desarrollo - **React DevTools**: Inspeccionar componentes React - **Vue.js DevTools**: Inspeccionar aplicaciones Vue - **Redux DevTools**: Debugging de estado Redux ## Obtener extensiones ### Chrome Web Store ```bash # URL de extensión en Chrome Web Store https://chrome.google.com/webstore/detail/ # Descargar .crx con herramientas # https://github.com/Rob--W/crxviewer ``` ### Desarrollo local ```bash # Crear extensión simple mkdir my-extension cd my-extension cat > manifest.json </page.html` 4. **Local storage**: Acceder a storage de extensión si es accesible ```go // Ejecutar código en contexto de extensión script := fmt.Sprintf(` chrome.runtime.sendMessage('%s', {action: 'configure'}, response => { return response; }); `, extensionID) ``` ## Consideraciones especiales ### Manifest V3 vs V2 - Chrome está migrando a Manifest V3 - Algunas extensiones V2 dejarán de funcionar - Verificar compatibilidad al cargar extensiones ### Permisos - Extensiones pueden requerir permisos específicos - Algunas operaciones requieren interacción manual la primera vez - Considerar pre-configurar permisos en perfil ### Actualizaciones - Extensiones de Chrome Web Store se actualizan automáticamente - Extensiones locales no se actualizan - Implementar sistema de actualización manual si es necesario ### Headless mode - Algunas extensiones no funcionan en modo headless - Extensiones con UI pueden requerir modo visible - Probar compatibilidad con `--headless=new` ## Referencias - Chrome Extensions: https://developer.chrome.com/docs/extensions/ - Load unpacked extensions: https://developer.chrome.com/docs/extensions/mv3/getstarted/ - Chrome Extension IDs: https://robwu.nl/crxviewer/ - Manifest V3: https://developer.chrome.com/docs/extensions/mv3/intro/ - Extension CLI flags: https://peter.sh/experiments/chromium-command-line-switches/