From 133af4ac95c3e061f819ce78c6154d2aad8b7154 Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 27 Oct 2022 01:37:51 +0200 Subject: workstation: Switch to Nix-managed Firefox I had this laying around locally for a year now and I'm still not really happy with some things, for example not having yet full source builds of the extensions and a few config options not yet managed by Nix (eg. search engines). However, since Firefox takes a while to build it's a bit tedious to always do it directly (and locally) after I update my machines. Having this part of my workstation profile should make sure that my version of Firefox is available at all times. Signed-off-by: aszlig --- pkgs/aszlig/default.nix | 1 + pkgs/aszlig/firefox/addons.json | 18 ++++ pkgs/aszlig/firefox/default.nix | 125 +++++++++++++++++++++++ pkgs/aszlig/firefox/dont-block-about-pages.patch | 12 +++ pkgs/aszlig/firefox/ff2mpv.py | 38 +++++++ pkgs/aszlig/firefox/mute-by-default.patch | 20 ++++ pkgs/aszlig/firefox/update-addons.sh | 9 ++ 7 files changed, 223 insertions(+) create mode 100644 pkgs/aszlig/firefox/addons.json create mode 100644 pkgs/aszlig/firefox/default.nix create mode 100644 pkgs/aszlig/firefox/dont-block-about-pages.patch create mode 100644 pkgs/aszlig/firefox/ff2mpv.py create mode 100644 pkgs/aszlig/firefox/mute-by-default.patch create mode 100755 pkgs/aszlig/firefox/update-addons.sh (limited to 'pkgs') diff --git a/pkgs/aszlig/default.nix b/pkgs/aszlig/default.nix index 9eb0012f..55f73762 100644 --- a/pkgs/aszlig/default.nix +++ b/pkgs/aszlig/default.nix @@ -3,6 +3,7 @@ { aacolorize = callPackage ./aacolorize { }; axbo = callPackage ./axbo { }; + firefox = callPackage ./firefox { }; git-detach = callPackage ./git-detach { }; gopass = callPackage ./gopass { inherit gopass; }; grandpa = callPackage ./grandpa { }; diff --git a/pkgs/aszlig/firefox/addons.json b/pkgs/aszlig/firefox/addons.json new file mode 100644 index 00000000..48684040 --- /dev/null +++ b/pkgs/aszlig/firefox/addons.json @@ -0,0 +1,18 @@ +{ + "ff2mpv": { + "url": "https://addons.mozilla.org/firefox/downloads/file/3898765/ff2mpv-4.0.0.xpi", + "hash": "sha256:88312a84fc0a5d8e32100664af900a252a86875ee51869c30fd68054e990c992" + }, + "styl-us": { + "url": "https://addons.mozilla.org/firefox/downloads/file/3995806/styl_us-1.5.26.xpi", + "hash": "sha256:b30b14e9c4fa0c8d490d57e6b7d8afe6cc71e2f459b974b5c6fa2bfa32210294" + }, + "tridactyl-vim": { + "url": "https://addons.mozilla.org/firefox/downloads/file/3926466/tridactyl_vim-1.22.1.xpi", + "hash": "sha256:ed0337dd67516142d1f02a77cab910c7cb95ca575ec1ee4b1f5cf8971918b0f6" + }, + "multi-account-containers": { + "url": "https://addons.mozilla.org/firefox/downloads/file/3932862/multi_account_containers-8.0.7.xpi", + "hash": "sha256:0e60e00c13dcc372b43ddb2e5428c2e3c1e79d2b23d7166df82d45245edc4f10" + } +} diff --git a/pkgs/aszlig/firefox/default.nix b/pkgs/aszlig/firefox/default.nix new file mode 100644 index 00000000..8595a3e2 --- /dev/null +++ b/pkgs/aszlig/firefox/default.nix @@ -0,0 +1,125 @@ +{ lib, writeTextFile, writers, wrapFirefox, fetchFirefoxAddon +, firefox-unwrapped, tridactyl-native +}: + +let + mkExtension = name: { url, hash }: fetchFirefoxAddon { + inherit name url hash; + }; + + extensions = lib.mapAttrs mkExtension (lib.importJSON ./addons.json); + + firefoxNoSigning = (firefox-unwrapped.override { + crashreporterSupport = false; + drmSupport = false; + googleAPISupport = false; + }).overrideAttrs (drv: { + patches = (drv.patches or []) ++ [ + ./mute-by-default.patch + ./dont-block-about-pages.patch + ]; + MOZ_REQUIRE_SIGNING = false; + }); + + jsString = str: builtins.toJSON (toString str); + +in wrapFirefox firefoxNoSigning { + nixExtensions = lib.attrValues extensions; + + extraNativeMessagingHosts = [ + (writeTextFile { + name = "ff2mpv-native"; + destination = "/lib/mozilla/native-messaging-hosts/ff2mpv.json"; + text = builtins.toJSON { + name = "ff2mpv"; + description = "Helper to actually run mpv"; + path = let + source = builtins.readFile ./ff2mpv.py; + in writers.writePython3 "ff2mpv.py" {} source; + type = "stdio"; + allowed_extensions = [ extensions.ff2mpv.extid ]; + }; + }) + (writeTextFile { + name = "tridactyl-native"; + destination = "/lib/mozilla/native-messaging-hosts/tridactyl.json"; + text = builtins.toJSON { + name = "tridactyl"; + description = "Tridactyl native command handler"; + path = "${tridactyl-native}/share/tridactyl/native_main.py"; + type = "stdio"; + allowed_extensions = [ + extensions.tridactyl-vim.extid + "tridactyl.vim@cmcaine.co.uk" + ]; + }; + }) + ]; + + extraPrefs = '' + lockPref('app.normandy.enabled', false); + lockPref('app.normandy.first_run', false); + lockPref('app.shield.optoutstudies.enabled', false); + lockPref('browser.aboutConfig.showWarning', false); + lockPref('browser.aboutwelcome.enabled', false); + lockPref('browser.contentblocking.category', 'strict'); + lockPref('browser.laterrun.enabled', false); + lockPref('browser.newtab.extensionControlled', true); + lockPref('browser.newtab.privateAllowed', false); + lockPref('browser.newtabpage.enabled', false); + lockPref('browser.rights.3.shown', true); + lockPref('browser.safebrowsing.malware.enabled', false); + lockPref('browser.safebrowsing.phishing.enabled', false); + lockPref('browser.shell.checkDefaultBrowser', false); + lockPref('devtools.theme', 'dark'); + lockPref('extensions.webextensions.restrictedDomains', ""); + lockPref('privacy.donottrackheader.enabled', true); + lockPref('privacy.query_stripping.enabled', true); + lockPref('privacy.query_stripping.enabled.pbmode', true); + lockPref('privacy.trackingprotection.enabled', true); + lockPref('privacy.trackingprotection.socialtracking.enabled', true); + lockPref('reader.color_scheme', 'dark'); + + pref('browser.uiCustomization.state', ${jsString (builtins.toJSON { + placements = { + widget-overflow-fixed-list = []; + nav-bar = [ + "back-button" + "forward-button" + "stop-reload-button" + "urlbar-container" + "downloads-button" + "fxa-toolbar-menu-button" + "nixos_ff2mpv-browser-action" + "nixos_multi_account_containers-browser-action" + "nixos_stylus-browser-action" + "nixos_styl-us-browser-action" + "nixos_multi-account-containers-browser-action" + ]; + toolbar-menubar = [ "menubar-items" ]; + TabsToolbar = [ "tabbrowser-tabs" "new-tab-button" "alltabs-button" ]; + PersonalToolbar = [ "import-button" "personal-bookmarks" ]; + }; + currentVersion = 17; + })}); + ''; + + extraPolicies = { + DisableFirefoxAccounts = true; + DisableFirefoxStudies = true; + DisablePocket = true; + DisableSetDesktopBackground = true; + DisableTelemetry = true; + EnableTrackingProtection.Cryptomining = true; + EnableTrackingProtection.Fingerprinting = true; + EnableTrackingProtection.Locked = true; + EnableTrackingProtection.Value = true; + EncryptedMediaExtensions.Enabled = false; + EncryptedMediaExtensions.Locked = true; + FirefoxHome.Pocket = false; + FirefoxHome.Snippets = false; + OverrideFirstRunPage = ""; + UserMessaging.ExtensionRecommendations = false; + UserMessaging.SkipOnboarding = false; + }; +} diff --git a/pkgs/aszlig/firefox/dont-block-about-pages.patch b/pkgs/aszlig/firefox/dont-block-about-pages.patch new file mode 100644 index 00000000..3f328ffc --- /dev/null +++ b/pkgs/aszlig/firefox/dont-block-about-pages.patch @@ -0,0 +1,12 @@ +diff --git a/browser/components/enterprisepolicies/Policies.sys.mjs b/browser/components/enterprisepolicies/Policies.sys.mjs +index 21e3e8804f60..106ec235c5c0 100644 +--- a/browser/components/enterprisepolicies/Policies.sys.mjs ++++ b/browser/components/enterprisepolicies/Policies.sys.mjs +@@ -2615,6 +2615,7 @@ function clearBlockedAboutPages() { + } + + function blockAboutPage(manager, feature, neededOnContentProcess = false) { ++ return; + addChromeURLBlocker(); + gBlockedAboutPages.push(feature); + diff --git a/pkgs/aszlig/firefox/ff2mpv.py b/pkgs/aszlig/firefox/ff2mpv.py new file mode 100644 index 00000000..a983c982 --- /dev/null +++ b/pkgs/aszlig/firefox/ff2mpv.py @@ -0,0 +1,38 @@ +import sys +import struct +import json +from subprocess import Popen, DEVNULL + + +def main(): + message = get_message() + url = message.get("url") + + mpv_args = ["--no-terminal", "--pause", "--force-window=immediate"] + + args = ["mpv", *mpv_args, "--", url] + Popen(args, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) + # Need to respond something to avoid "Error: An unexpected error occurred" + # in Browser Console. + send_message("ok") + + +def get_message(): + raw_length = sys.stdin.buffer.read(4) + if not raw_length: + return {} + length = struct.unpack("@I", raw_length)[0] + message = sys.stdin.buffer.read(length).decode("utf-8") + return json.loads(message) + + +def send_message(message): + content = json.dumps(message).encode("utf-8") + length = struct.pack("@I", len(content)) + sys.stdout.buffer.write(length) + sys.stdout.buffer.write(content) + sys.stdout.buffer.flush() + + +if __name__ == "__main__": + main() diff --git a/pkgs/aszlig/firefox/mute-by-default.patch b/pkgs/aszlig/firefox/mute-by-default.patch new file mode 100644 index 00000000..67e6bce4 --- /dev/null +++ b/pkgs/aszlig/firefox/mute-by-default.patch @@ -0,0 +1,20 @@ +diff --git a/dom/media/autoplay/AutoplayPolicy.cpp b/dom/media/autoplay/AutoplayPolicy.cpp +index 77c53ce58acd..688af016a72c 100644 +--- a/dom/media/autoplay/AutoplayPolicy.cpp ++++ b/dom/media/autoplay/AutoplayPolicy.cpp +@@ -78,15 +78,6 @@ static bool IsWindowAllowedToPlay(nsPIDOMWindowInner* aWindow) { + return true; + } + +- WindowContext* topContext = +- aWindow->GetBrowsingContext()->GetTopWindowContext(); +- if (topContext && topContext->HasBeenUserGestureActivated()) { +- AUTOPLAY_LOG( +- "Allow autoplay as top-level context has been activated by user " +- "gesture."); +- return true; +- } +- + Document* currentDoc = aWindow->GetExtantDoc(); + if (!currentDoc) { + return false; diff --git a/pkgs/aszlig/firefox/update-addons.sh b/pkgs/aszlig/firefox/update-addons.sh new file mode 100755 index 00000000..4d25c503 --- /dev/null +++ b/pkgs/aszlig/firefox/update-addons.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p bash coreutils jq +for addon in ff2mpv styl-us tridactyl-vim multi-account-containers; do + url="https://addons.mozilla.org/api/v5/addons/addon/$addon/versions/" + curl -s -H 'Accept: application/json' "$url" \ + | jq --arg name "$addon" '. + {$name}' +done | jq -s ' + map({key: .name, value: .results[0].file | {url, hash}}) | from_entries +' > "$(cd "$(dirname "$0")" && pwd)/addons.json" -- cgit 1.4.1