// ⚠ LA PRIMERA LÍNEA DE UN FICHERO AUTOCONFIG SE IGNORA — SIEMPRE, POR DISEÑO. // El parser de Gecko salta la línea 1 sin mirarla (herencia del formato de Netscape). Si acá // hubiera código en vez de este comentario, no correría y no habría ningún error: el fallo más caro // de este fichero es el que no dice nada. Por eso la línea 1 es, deliberadamente, un comentario. // ── PREFS DE FÁBRICA ─────────────────────────────────────────────────────────────────────────── // `defaultPref` y no `lockPref`: son valores de arranque, no una cárcel. Una distro que decide POR // el usuario y no lo deja cambiar de idea es exactamente lo que atuq no quiere ser. Lo que sí se // bloquea con política de verdad va en `distribution/policies.json`. // Los dientes: pestañas verticales, que Firefox trae nativas desde la 133 y vienen apagadas. defaultPref("sidebar.revamp", true); defaultPref("sidebar.verticalTabs", true); // ── LOS CONTENEDORES, PRENDIDOS DE FÁBRICA (SDD 26 §6.8) ─────────────────────────────────────── // Firefox trae los contenedores en el motor desde hace años y los deja APAGADOS: para usarlos hay // que prender una pref escondida o instalar la extensión de Mozilla. atuq los prende de fábrica // porque son la mitad de abajo del proxy por contenedor —la que separa cookies, sesión y // almacenamiento—; la otra mitad, la que separa por dónde SALEN los paquetes, la pone la extensión // `proxy@atuq.tawasuyu`. // // Los contenedores CONCRETOS (Personal/Trabajo/Banco/Compras) no se declaran acá sino en // `distribution/policies.json`, con la política `Containers.Default`: es el único mecanismo que // crea contenedores en un perfil NUEVO sin que el usuario los escriba a mano. Comprobado dentro del // artefacto, no en la documentación: `ContextualIdentityService.sys.mjs` los lee de // `Services.policies.getActivePolicies().Containers.Default` en su `init()`. // // ⚠ `privacy.userContext.enabled` es la pref que ese mismo servicio observa: si alguna vez pasa a // false, Gecko CIERRA las pestañas de contenedor y borra la lista. Va como `defaultPref` igual que // todo lo demás —el usuario puede apagarlo—, pero apagarlo no es cosmético y por eso queda dicho. defaultPref("privacy.userContext.enabled", true); defaultPref("privacy.userContext.ui.enabled", true); // La distro se actualiza con hammer. Un navegador que se auto-actualiza por su cuenta rompería el // invariante entero: el binario dejaría de ser el que el artefacto dice que es. defaultPref("app.update.auto", false); defaultPref("browser.shell.checkDefaultBrowser", false); // Telemetría. No es «apagar una casilla»: es que la distro no reporta, punto. Lo verificable de // verdad —que la clausura no tenga a dónde reportar— es otro frente (SDD 26 §6); esto es el suelo. defaultPref("datareporting.healthreport.uploadEnabled", false); defaultPref("datareporting.policy.dataSubmissionEnabled", false); defaultPref("toolkit.telemetry.enabled", false); defaultPref("toolkit.telemetry.unified", false); defaultPref("toolkit.telemetry.archive.enabled", false); // Extensiones que la distro deja en `distribution/extensions/`: sin esto Gecko las instala // DESACTIVADAS y el usuario ve una lista de complementos apagados que nunca pidió apagar. // El otro lado de esto es `--with-unsigned-addon-scopes=app,system`, que va en el CONFIGURE de // `recipes/firefox.toml` y por eso no se puede resolver desde acá. defaultPref("extensions.autoDisableScopes", 0); // ── LA FIRMA DE COMPLEMENTOS ─────────────────────────────────────────────────────────────────── // Sin esto la política de instalación muere con un error que no menciona la firma por su nombre: // Policies: Download failed - ERROR_SIGNEDSTATE_REQUIRED - file:///…/inicio@atuq…xpi // Firefox exige que todo XPI esté firmado por Mozilla, y `--with-unsigned-addon-scopes=app,system` // —que sí está en el build— NO cubre el camino de instalación por política. // // Esta pref sólo tiene efecto en builds **unbranded**, y la nuestra lo es: `recipes/firefox.toml` // construye con `--with-branding=browser/branding/unofficial`. O sea que esto funciona por una // decisión que ya estaba tomada, no por una excepción nueva. // // ⚠ Lo que se pierde, dicho: atuq deja de exigir la firma de Mozilla para CUALQUIER complemento, // no sólo el suyo. Es la misma postura que toman las distros que empaquetan extensiones propias, y // la alternativa real —firmar con AMO— exige una cuenta y una revisión de Mozilla por cada versión, // que es exactamente la dependencia externa que esta distro existe para no tener. lockPref("xpinstall.signatures.required", false); // La página de inicio la pone la extensión `inicio@atuq.tawasuyu` con // `chrome_settings_overrides.homepage`; acá sólo se dice que al arrancar se abra la HOME y no la // sesión anterior. Poner la URL a mano en `browser.startup.homepage` pelearía con la extensión, y // gana la última que escribe: dos dueños para un valor es la forma de que el arranque sea sorpresa. defaultPref("browser.startup.page", 1); // ── EL CHROME ────────────────────────────────────────────────────────────────────────────────── // Por qué acá y no en `userChrome.css`: ese fichero vive en el PERFIL y exige que el usuario prenda // `toolkit.legacyUserProfileCustomizations.stylesheets`. atuq tiene que verse como atuq en el // primer arranque, con un perfil recién creado, sin que nadie prenda nada. El único gancho a nivel // de APLICACIÓN es nsIStyleSheetService, y llegar a él es la razón de `sandbox_enabled = false`. // // USER_SHEET y no AGENT_SHEET: es el mismo nivel de cascada que usa `userChrome.css`, así que lo // que se escriba en `chrome/atuq.css` se comporta como la gente espera y el usuario puede seguir // pisándolo con el suyo. AGENT_SHEET ganaría siempre y además alcanzaría al CONTENIDO de las // páginas, que no es lo que queremos tocar. try { const { classes: Cc, interfaces: Ci } = Components; // ── TESTIGO: «¿corrió este fichero?» es la PRIMERA pregunta de cualquier diagnóstico ───────── // `defaultPref` no deja rastro en `prefs.js` (sólo se guardan los valores que difieren del // default), así que un autoconfig que no se ejecuta es INDISTINGUIBLE de uno que se ejecutó y no // hizo nada. Esto escribe una pref de USUARIO, que sí queda en el perfil y se puede leer desde // fuera sin abrir el navegador. Cc["@mozilla.org/preferences-service;1"] .getService(Ci.nsIPrefBranch) .setBoolPref("atuq.autoconfig.ok", true); const sss = Cc["@mozilla.org/content/style-sheet-service;1"] .getService(Ci.nsIStyleSheetService); const ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); const dirs = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); // "GreD" = el directorio de la aplicación (donde vive el binario). En una instalación normal es // el mismo que "XCurProcD"; se usa GreD porque es el que no cambia si algún día atuq se lanza // con un `-app`. const css = dirs.get("GreD", Ci.nsIFile); css.append("chrome"); css.append("atuq.css"); if (css.exists()) { const uri = ios.newFileURI(css); if (!sss.sheetRegistered(uri, sss.USER_SHEET)) { sss.loadAndRegisterSheet(uri, sss.USER_SHEET); } } } catch (e) { // Un fallo acá NO debe impedir que el navegador arranque: sin estilo es feo, sin navegador no hay // nada. Queda en la consola de errores, que es donde se mira cuando «atuq se ve como Firefox». Components.utils.reportError("atuq.cfg: no pude registrar chrome/atuq.css: " + e); } // ── LA BÓVEDA, Y EL GESTOR QUE SE APAGA PARA DEJARLE LUGAR (SDD-BOVEDA D7) ───────────────────── // Las contraseñas las guarda la suite: la bóveda las ofrece en el sitio que corresponde, las // sincroniza entre los equipos de la persona y se puede recuperar si se pierde el equipo. Gecko // trae su propio gestor, y DOS gestores peleando por el mismo campo es la peor experiencia que // puede tener alguien que sólo quiere entrar a su correo: el sitio se rellena dos veces, o ninguna, // y no hay forma de saber cuál de los dos tiene la contraseña buena. // // Por eso de fábrica manda la bóveda. Pero va como `defaultPref` y NO como política: el que // prefiera el de Gecko lo prende y listo. Prohibírselo sería decidir por él, que es exactamente lo // que este fichero dice en su cabecera que atuq no quiere ser — y el costo de equivocarse acá lo // paga alguien que se queda sin poder guardar una contraseña en su propia máquina. defaultPref("signon.rememberSignons", false); defaultPref("signon.autofillForms", false); // Y que tampoco ofrezca la que ya tenga guardada de antes: el usuario que migra sus claves con // `foreign-mozlogins` se las lleva a la bóveda, y ver las dos listas a la vez es confuso sin // motivo. defaultPref("signon.autofillForms.autocompleteOff", false);