From c8dd0b179ec4dc02362629c29c94967601ef0d15 Mon Sep 17 00:00:00 2001 From: Dmitry Voronin Date: Fri, 1 Nov 2024 01:07:41 +0300 Subject: [PATCH] Firefox: Use Dark Reader for with a broken policy config support. --- home/config/chromium/default.nix | 6 +- home/program/firefox/default.nix | 347 +++++++++++++++++++++++++------ package/darkreader/default.nix | 42 ++++ 3 files changed, 335 insertions(+), 60 deletions(-) create mode 100644 package/darkreader/default.nix diff --git a/home/config/chromium/default.nix b/home/config/chromium/default.nix index b945b105..4ae7646d 100644 --- a/home/config/chromium/default.nix +++ b/home/config/chromium/default.nix @@ -85,5 +85,9 @@ }; }; - policy = (pkgs.formats.json { }).generate "ChromiumPolicy" { URLBlocklist = [ "darkreader.org" ]; }; + # REF: https://chromeenterprise.google/intl/en_us/policies/ + policy = (pkgs.formats.json { }).generate "ChromiumPolicy" { + URLBlocklist = [ "darkreader.org" ]; + DefaultBrowserSettingEnabled = false; + }; } diff --git a/home/program/firefox/default.nix b/home/program/firefox/default.nix index eff5e551..e63d5016 100644 --- a/home/program/firefox/default.nix +++ b/home/program/firefox/default.nix @@ -1,4 +1,9 @@ -{ pkgs, config, ... }: +{ + pkgs, + config, + __findFile, + ... +}: let bookmarks = [ (mkBookmark "Dashboard" "https://home.voronind.com") @@ -31,7 +36,11 @@ let ]; extensions = [ - (mkExtension "addon@darkreader.org" "https://addons.mozilla.org/firefox/downloads/latest/darkreader/latest.xpi") + # TODO: Use this after https://github.com/darkreader/darkreader/pull/12920 gets merged. + # (mkExtension "addon@darkreader.org" "https://addons.mozilla.org/firefox/downloads/latest/darkreader/latest.xpi") + (mkExtension "addon@darkreader.org" "file://${ + pkgs.callPackage { } + }/latest.xpi") (mkExtension "cliget@zaidabdulla.com" "https://addons.mozilla.org/firefox/downloads/latest/cliget/latest.xpi") (mkExtension "foxyproxy@eric.h.jung" "https://addons.mozilla.org/firefox/downloads/latest/foxyproxy-standard/latest.xpi") (mkExtension "uBlock0@raymondhill.net" "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi") @@ -44,72 +53,75 @@ let # (mkExtension "queryamoid@kaply.com" "https://github.com/mkaply/queryamoid/releases/download/v0.1/query_amo_addon_id-0.1-fx.xpi") ]; - extraConfig = '' - // Bookmarks. - user_pref("browser.microsummary.enabled", true); - user_pref("browser.places.importBookmarksHTML", true); - user_pref("browser.toolbars.bookmarks.visibility", "never"); + prefs = [ + # WARN: Remove when Dark Reader policies gets mnerged. + (mkLockedPref "xpinstall.signatures.required" false) - // Fonts. - user_pref("browser.display.use_document_fonts", 0); - user_pref("font.minimum-size.x-cyrillic", ${toString config.style.font.size.application}); - user_pref("font.minimum-size.x-unicode", ${toString config.style.font.size.application}); - user_pref("font.minimum-size.x-western", ${toString config.style.font.size.application}); - user_pref("font.name.monospace.x-cyrillic", "${config.style.font.monospace.name}"); - user_pref("font.name.monospace.x-unicode", "${config.style.font.monospace.name}"); - user_pref("font.name.monospace.x-western", "${config.style.font.monospace.name}"); - user_pref("font.name.sans-serif.x-cyrillic", "${config.style.font.sansSerif.name}"); - user_pref("font.name.sans-serif.x-unicode", "${config.style.font.sansSerif.name}"); - user_pref("font.name.sans-serif.x-western", "${config.style.font.sansSerif.name}"); - user_pref("font.name.serif.x-cyrillic", "${config.style.font.serif.name}"); - user_pref("font.name.serif.x-unicode", "${config.style.font.serif.name}"); - user_pref("font.name.serif.x-western", "${config.style.font.serif.name}"); + # Bookmarks. + (mkLockedPref "browser.microsummary.enabled" true) + (mkLockedPref "browser.places.importBookmarksHTML" true) + (mkLockedPref "browser.toolbars.bookmarks.visibility" "never") - // Animations. - user_pref("browser.fullscreen.animateUp", 0); - user_pref("browser.fullscreen.autohide", true); + # Fonts. + (mkUserPref "browser.display.use_document_fonts" 0) + (mkLockedPref "font.minimum-size.x-cyrillic" (toString config.style.font.size.application)) + (mkLockedPref "font.minimum-size.x-unicode" (toString config.style.font.size.application)) + (mkLockedPref "font.minimum-size.x-western" (toString config.style.font.size.application)) + (mkLockedPref "font.name.monospace.x-cyrillic" config.style.font.monospace.name) + (mkLockedPref "font.name.monospace.x-unicode" config.style.font.monospace.name) + (mkLockedPref "font.name.monospace.x-western" config.style.font.monospace.name) + (mkLockedPref "font.name.sans-serif.x-cyrillic" config.style.font.sansSerif.name) + (mkLockedPref "font.name.sans-serif.x-unicode" config.style.font.sansSerif.name) + (mkLockedPref "font.name.sans-serif.x-western" config.style.font.sansSerif.name) + (mkLockedPref "font.name.serif.x-cyrillic" config.style.font.serif.name) + (mkLockedPref "font.name.serif.x-unicode" config.style.font.serif.name) + (mkLockedPref "font.name.serif.x-western" config.style.font.serif.name) - // Homepage. - user_pref("browser.newtabpage.enabled", false); - user_pref("browser.startup.homepage", "https://home.voronind.com/"); - user_pref("browser.startup.page", 3); + # Animations. + (mkLockedPref "browser.fullscreen.animateUp" 0) + (mkLockedPref "browser.fullscreen.autohide" true) - // Passwords. - user_pref("signon.prefillForms", false); - user_pref("signon.rememberSignons", false); + # Homepage. + (mkLockedPref "browser.newtabpage.enabled" false) + (mkLockedPref "browser.startup.homepage" "https://home.voronind.com/") + (mkLockedPref "browser.startup.page" 3) - // Formats. - user_pref("image.jxl.enabled", true); + # Passwords. + (mkLockedPref "signon.prefillForms" false) + (mkLockedPref "signon.rememberSignons" false) - // User agent. - // user_pref("general.useragent.override", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"); + # Formats. + (mkLockedPref "image.jxl.enabled" true) - // Disable HTTP3. - user_pref("network.http.http3.enable", false); + # User agent. + # (mkLockedPref "general.useragent.override" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36") - // Disable built-in DoH. - user_pref("doh-rollout.disable-heuristics", true); - user_pref("network.trr.mode", 5); + # Disable HTTP3. + (mkLockedPref "network.http.http3.enable" false) - // HTTPS only mode. - user_pref("dom.security.https_only_mode", true); - user_pref("dom.security.https_only_mode_ever_enabled", true); + # Disable built-in DoH. + (mkLockedPref "doh-rollout.disable-heuristics" true) + (mkLockedPref "network.trr.mode" 5) - // Style. - user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); + # HTTPS only mode. + (mkLockedPref "dom.security.https_only_mode" true) + (mkLockedPref "dom.security.https_only_mode_ever_enabled" true) - // Disable auto gain for the mic. - // user_pref("media.getusermedia.audio.processing.aec", 0); - // user_pref("media.getusermedia.audio.processing.aec.enabled", false); - // user_pref("media.getusermedia.audio.processing.agc", 0); - // user_pref("media.getusermedia.audio.processing.agc.enabled", false); - // user_pref("media.getusermedia.audio.processing.agc2.forced", false) - // user_pref("media.getusermedia.audio.processing.hpf.enabled", false); - // user_pref("media.getusermedia.audio.processing.noise", 0); - // user_pref("media.getusermedia.audio.processing.noise.enabled", false); - // user_pref("media.getusermedia.audio.processing.platform.enabled", false); - // user_pref("media.getusermedia.audio.processing.transient.enabled", false); - ''; + # Style. + (mkLockedPref "toolkit.legacyUserProfileCustomizations.stylesheets" true) + + # Disable auto gain for the mic. + # (mkLockedPref "media.getusermedia.audio.processing.aec" 0) + # (mkLockedPref "media.getusermedia.audio.processing.aec.enabled" false) + # (mkLockedPref "media.getusermedia.audio.processing.agc" 0) + # (mkLockedPref "media.getusermedia.audio.processing.agc.enabled" false) + # (mkLockedPref "media.getusermedia.audio.processing.agc2.forced" false + # (mkLockedPref "media.getusermedia.audio.processing.hpf.enabled" false) + # (mkLockedPref "media.getusermedia.audio.processing.noise" 0) + # (mkLockedPref "media.getusermedia.audio.processing.noise.enabled" false) + # (mkLockedPref "media.getusermedia.audio.processing.platform.enabled" false) + # (mkLockedPref "media.getusermedia.audio.processing.transient.enabled" false) + ]; userChrome = '' * { @@ -156,17 +168,60 @@ let Method = "GET"; Name = Description; }; + + mkPref = Name: Value: Status: { + ${Name} = { + inherit Value Status; + }; + }; + mkLockedPref = Name: Value: mkPref Name Value "locked"; + mkUserPref = Name: Value: mkPref Name Value "user"; in { enable = true; package = pkgs.firefox-esr; # languagePacks = [ "en-US" "ru" ]; profiles.default = { - inherit extraConfig userChrome userContent; + inherit userChrome userContent; }; + # REF: https://mozilla.github.io/policy-templates/ policies = { - ManagedBookmarks = [ { toplevel_name = "Pin"; } ] ++ bookmarks; + AppAutoUpdate = false; + BackgroundAppUpdate = false; + DisableBuiltinPDFViewer = true; + DisableFirefoxAccounts = true; + DisableFirefoxStudies = true; + DisableFormHistory = true; + DisableMasterPasswordCreation = true; + DisablePasswordReveal = true; + DisablePocket = true; + DisableProfileImport = true; + DisableSetDesktopBackground = true; + DisableTelemetry = true; + DontCheckDefaultBrowser = true; ExtensionUpdate = true; + ManagedBookmarks = [ { toplevel_name = "Pin"; } ] ++ bookmarks; + NoDefaultBookmarks = true; + OfferToSaveLogins = false; + PasswordManagerEnabled = false; + Preferences = builtins.foldl' (acc: pref: acc // pref) { } prefs; + PromptForDownloadLocation = false; + SearchSuggestEnabled = false; + ShowHomeButton = false; + StartDownloadsInTempDirectory = false; + UseSystemPrintDialog = true; + EnableTrackingProtection = { + Value = true; + Locked = false; + Cryptomining = true; + Fingerprinting = true; + EmailTracking = true; + Exceptions = [ "https://example.com" ]; + }; + EncryptedMediaExtensions = { + Enabled = true; + Locked = true; + }; ExtensionSettings = { # Block extension installation outside of this config. "*" = { @@ -174,6 +229,96 @@ in installation_mode = "blocked"; }; } // builtins.foldl' (acc: ext: acc // ext) { } extensions; + "3rdparty".Extensions = { + "uBlock0@raymondhill.net".adminSettings = { + userSettings = { + uiTheme = "dark"; + cloudStorageEnabled = false; + }; + # NOTE: Check in `Support` -> `Troubleshooting Information` tab. + selectedFilterLists = [ + "user-filters" + "ublock-badware" + "ublock-privacy" + "ublock-quick-fixes" + "ublock-filters" + "easyprivacy" + "ublock-unbreak" + "urlhaus-1" + "easylist" + "plowe-0" + "adguard-cookies" + "fanboy-cookiemonster" + "ublock-cookies-easylist" + "adguard-other-annoyances" + "ublock-cookies-adguard" + "adguard-widgets" + "fanboy-social" + "ublock-annoyances" + "adguard-social" + "fanboy-thirdparty_social" + "easylist-chat" + "easylist-newsletters" + "easylist-notifications" + "easylist-annoyances" + "adguard-mobile-app-banners" + "adguard-popup-overlays" + "RUS-0" + ]; + }; + "addon@darkreader.org" = { + enabled = false; + enabledByDefault = false; + previewNewDesign = true; + syncSettings = false; + # disabledFor = [ + # "home.voronind.com" + # ]; + # fetchNews = false; + # theme = { + # mode = 1; + # brightness = 100; + # contrast = 100; + # grayscale = 0; + # sepia = 0; + # useFont = true; + # fontFamily = config.style.font.sansSerif.name; + # textStroke = 0; + # engine = "dynamicTheme"; # dynamicTheme, cssFilter or svgFilter. + # stylesheet = ""; + # darkSchemeBackgroundColor = "ff0000"; + # darkSchemeTextColor = "00ff00"; + # lightSchemeBackgroundColor = "ff0000"; + # lightSchemeTextColor = "00ff00"; + # scrollbarColor = "0000ff"; + # selectionColor = "00ffff"; + # styleSystemControls = true; + # lightColorScheme = "Default"; + # darkColorScheme = "Default"; + # immediateModify = true; + # }; + # changeBrowserTheme = true; + # syncSitesFixes = true; + # automation = { + # enabled = false; + # mode = ""; + # behavior = "OnOff"; + # }; + # time = { + # activation = "18:00"; + # deactivation = "9:00"; + # }; + # location = { + # latitude = null; + # longitude = null; + # }; + # previewNewDesign = true; + # enableForPDF = true; + # enableForProtectedPages = false; + # enableContextMenus = true; + # detectDarkTheme = true; + }; + }; # NOTE: `firefox-esr` edition is required to change search engines. SearchEngines = { Add = searchEngines; @@ -186,5 +331,89 @@ in "Wikipedia (en)" ]; }; + FirefoxHome = { + Search = false; + TopSites = false; + SponsoredTopSites = false; + Highlights = false; + Pocket = false; + Snippets = false; + Locked = true; + }; + FirefoxSuggest = { + WebSuggestions = false; + SponsoredSuggestions = false; + ImproveSuggest = false; + Locked = true; + }; + PDFjs = { + Enabled = false; + EnablePermissions = false; + }; + Handlers = { + mimeTypes."application/pdf".action = "saveToDisk"; + }; + extensions = { + pdf = { + action = "useHelperApp"; + ask = true; + handlers = [ + { + name = "GNOME Document Viewer"; + path = "${pkgs.evince}/bin/evince"; + } + ]; + }; + }; + Permissions = { + Camera = { + Allow = [ ]; + Block = [ ]; + BlockNewRequests = false; + Locked = false; + }; + Microphome = { + Allow = [ ]; + Block = [ ]; + BlockNewRequests = false; + Locked = false; + }; + Location = { + Allow = [ ]; + Block = [ ]; + BlockNewRequests = true; + Locked = true; + }; + Autoplay = { + Allow = [ ]; + Block = [ ]; + Default = "block-audio-video"; # allow-audio-video | block-audio | block-audio-video + Locked = true; + }; + }; + PictureInPicture = { + Enabled = false; + Locked = false; + }; + SanitizeOnShutdown = { + Cache = true; + Cookies = false; + Downloads = false; + FormData = true; + History = false; + Sessions = false; + SiteSettings = false; + OfflineApps = true; + Locked = true; + }; + UserMessaging = { + ExtensionRecommendations = false; + FeatureRecommendations = false; + MoreFromMozilla = false; + SkipOnboarding = true; + UrlbarInterventions = false; + WhatsNew = false; + Locked = true; + }; }; } diff --git a/package/darkreader/default.nix b/package/darkreader/default.nix new file mode 100644 index 00000000..c85f5a1e --- /dev/null +++ b/package/darkreader/default.nix @@ -0,0 +1,42 @@ +{ + fetchFromGitHub, + buildNpmPackage, + fetchpatch, + fetchNpmDeps, + ... +}: +buildNpmPackage rec { + # version = "4.9.96"; + version = "c700f9e03440131d46c6506eca79499a65fb1bd8"; + + pname = "dark-reader"; + + src = fetchFromGitHub { + owner = "nenikitov"; + repo = "darkreader"; + # rev = "v${version}"; + # rev = "c700f9e03440131d46c6506eca79499a65fb1bd8"; + rev = version; + hash = "sha256-oscW2V6GBBAa6/1uwhU4nimu2kMnd429p9rCEYZC7ZM="; + }; + + npmDepsHash = "sha256-e41PXGgoQkVSHQj6kElqXPhzc6irnr09ltBAPmcUjik="; + # npmDepsHash = "sha256-dSuCL8GZXiksqVQ+TypzOdAROn3q30ExaGCJu72GLyY="; + # npmDeps = fetchNpmDeps { + # inherit src; + # name = "${pname}-${version}-npm-deps"; + # hash = npmDepsHash; + # }; + + # patches = [ + # (fetchpatch { + # url = "https://github.com/darkreader/darkreader/pull/12920.patch"; + # hash = "sha256-XNYSrccQAAT4nd/uu/cunlq4WfoL7xKqWUUlTBqwuU8="; + # }) + # ]; + + installPhase = '' + mkdir -p $out + cp build/release/darkreader-firefox.xpi $out/latest.xpi + ''; +}