From a16754ff06b7db478a9252bb6159652818cdad0d Mon Sep 17 00:00:00 2001 From: Arpit Chakladar Date: Sun, 2 Aug 2026 02:50:10 +0530 Subject: feat: added example to use pgp signing of emails, fixed browserpass - Added example on how to enable pgp signing on gmail email accounts - The programs.browserpass.enable option only used extension ids for the actual extensions not for the custom extension key we gave it. So we are updaing the com.github.browserpass.native.json file to manually add our own extension id to it --- .../neomutt/account/flavors/gmail.nix | 2 +- modules/private/email.example.nix | 8 ++ modules/web/chromium/browserpass.nix | 17 +++ modules/web/chromium/default.nix | 149 ++++++++++----------- modules/web/chromium/extensions/default.nix | 65 +++++++-- 5 files changed, 146 insertions(+), 95 deletions(-) diff --git a/modules/communication/neomutt/account/flavors/gmail.nix b/modules/communication/neomutt/account/flavors/gmail.nix index 4d6cff2..28ec979 100644 --- a/modules/communication/neomutt/account/flavors/gmail.nix +++ b/modules/communication/neomutt/account/flavors/gmail.nix @@ -31,7 +31,7 @@ }; }; - neomutt.extraConfig = lib.mkDefault '' + neomutt.extraConfig = lib.mkBefore '' mailboxes =Inbox ="[Gmail]/Drafts" ="[Gmail]/Sent Mail" ="[Gmail]/Spam" ="[Gmail]/Trash" unset record ''; diff --git a/modules/private/email.example.nix b/modules/private/email.example.nix index c525b71..16d8402 100644 --- a/modules/private/email.example.nix +++ b/modules/private/email.example.nix @@ -8,6 +8,14 @@ passwordGopassSecret = "mail/user@gmail.com"; flavor = "gmail.com"; primary = true; + neomutt.extraConfig = '' + set pgp_default_key = YOUR_GPG_KEY_FINGERPRINT + ''; + gpg = { + key = "YOUR_GPG_KEY_ID"; + signByDefault = true; + encryptByDefault = false; # set true only if you also want auto-encrypt + }; }; }; } diff --git a/modules/web/chromium/browserpass.nix b/modules/web/chromium/browserpass.nix index 860d46e..f09945d 100644 --- a/modules/web/chromium/browserpass.nix +++ b/modules/web/chromium/browserpass.nix @@ -1,13 +1,30 @@ { lib, config, + pkgs, ... }: +let + # Extension ID computed from the pinned "extensionKey" in + patchedHost = + pkgs.runCommand "com.github.browserpass.native.json" + { + nativeBuildInputs = [ pkgs.jq ]; + } + '' + jq '.allowed_origins = ["chrome-extension://${config.web.chromium.extensions.browserpass.id}/"]' \ + ${config.programs.browserpass.package}/lib/browserpass/hosts/chromium/com.github.browserpass.native.json \ + > $out + ''; +in { config = lib.mkIf (config.web.chromium.enable && config.security.gopass.enable) { programs.browserpass = { enable = true; browsers = [ "chromium" ]; }; + home.file.".config/chromium/NativeMessagingHosts/com.github.browserpass.native.json" = lib.mkForce { + source = patchedHost; + }; }; } diff --git a/modules/web/chromium/default.nix b/modules/web/chromium/default.nix index 2cd9fc1..8a86a5a 100644 --- a/modules/web/chromium/default.nix +++ b/modules/web/chromium/default.nix @@ -7,7 +7,7 @@ { imports = [ ./browserpass.nix - ./extensions/assertions.nix + ./extensions ]; options.web.chromium = { @@ -29,93 +29,80 @@ }; }; - config = lib.mkIf config.web.chromium.enable ( - let - exts = import ./extensions { - inherit lib pkgs config; - checkForUpdates = config.web.chromium.checkForUpdates; - }; - - extensionDirs = [ - exts.aria2Explorer.drv - exts.browserpass.drv - exts.darkMode.drv - exts.searxngHome.drv - exts.theme.drv - exts.ublockOrigin.drv - ]; - - pinnedIds = lib.filter (id: id != null) [ - exts.browserpass.id - exts.darkMode.id - exts.ublockOrigin.id - ]; - in - { - programs.chromium = { - enable = true; - package = pkgs.ungoogled-chromium; - commandLineArgs = [ + config = lib.mkIf config.web.chromium.enable { + programs.chromium = { + enable = true; + package = pkgs.ungoogled-chromium; + commandLineArgs = + let + extensionDirs = lib.concatStringsSep "," ( + lib.mapAttrsToList (_: ext: ext.drv) config.web.chromium.extensions + ); + in + [ "--force-device-scale-factor=1.15" - "--load-extension=${lib.concatStringsSep "," extensionDirs}" + "--load-extension=${extensionDirs}" ]; - }; + }; - xdg.mimeApps.defaultApplications = { - "x-scheme-handler/http" = "chromium-browser.desktop"; - "x-scheme-handler/https" = "chromium-browser.desktop"; - "x-scheme-handler/chrome" = "chromium-browser.desktop"; - "text/html" = "chromium-browser.desktop"; - "application/xhtml+xml" = "chromium-browser.desktop"; - }; + xdg.mimeApps.defaultApplications = { + "x-scheme-handler/http" = "chromium-browser.desktop"; + "x-scheme-handler/https" = "chromium-browser.desktop"; + "x-scheme-handler/chrome" = "chromium-browser.desktop"; + "text/html" = "chromium-browser.desktop"; + "application/xhtml+xml" = "chromium-browser.desktop"; + }; - xdg.configFile."chromium/Default/Preferences" = { - force = true; - text = builtins.toJSON { - NewTabPage = { - FooterVisible = false; - }; - bookmark_bar = { - show_on_all_tabs = false; - }; - browser = { - show_full_urls = true; - theme = { - follows_system_colors = true; - }; - }; - search = { - suggest_enabled = false; - }; - url_handling = { - show_full_urls = true; - }; - autofill = { - profile_enabled = false; - credit_card_enabled = false; - }; - vertical_tabs = { - collapsed_state = true; - enabled = true; - enabled_first_time = true; - uncollapsed_width = 240; + xdg.configFile."chromium/Default/Preferences" = { + force = true; + text = builtins.toJSON { + NewTabPage = { + FooterVisible = false; + }; + bookmark_bar = { + show_on_all_tabs = false; + }; + browser = { + show_full_urls = true; + theme = { + follows_system_colors = true; }; - credentials_enable_service = false; - credentials_enable_autosignin = false; - extensions = { - pinned_extensions = pinnedIds; - ui = { - developer_mode = true; - }; + }; + search = { + suggest_enabled = false; + }; + url_handling = { + show_full_urls = true; + }; + autofill = { + profile_enabled = false; + credit_card_enabled = false; + }; + vertical_tabs = { + collapsed_state = true; + enabled = true; + enabled_first_time = true; + uncollapsed_width = 240; + }; + credentials_enable_service = false; + credentials_enable_autosignin = false; + extensions = { + pinned_extensions = [ + config.web.chromium.extensions.browserpass.id + config.web.chromium.extensions.darkMode.id + config.web.chromium.extensions.ublockOrigin.id + ]; + ui = { + developer_mode = true; }; - profile = { - default_content_setting_values = { - notifications = 2; - }; + }; + profile = { + default_content_setting_values = { + notifications = 2; }; - high_efficiency_mode_enabled = true; }; + high_efficiency_mode_enabled = true; }; - } - ); + }; + }; } diff --git a/modules/web/chromium/extensions/default.nix b/modules/web/chromium/extensions/default.nix index a73f5f2..6128d2b 100644 --- a/modules/web/chromium/extensions/default.nix +++ b/modules/web/chromium/extensions/default.nix @@ -2,24 +2,63 @@ lib, pkgs, config, - checkForUpdates ? true, + ... }: let + cfg = config.web.chromium; + extLib = import ./lib.nix { - inherit - lib - pkgs - config - checkForUpdates - ; + inherit lib pkgs config; + checkForUpdates = cfg.checkForUpdates; }; + mkExtension = path: import path { inherit lib pkgs extLib; }; + + extensionSubmodule = lib.types.submodule { + options = { + pname = lib.mkOption { + type = lib.types.str; + description = "Package name of the extension."; + }; + version = lib.mkOption { + type = lib.types.str; + description = "Resolved/pinned version of the extension."; + }; + id = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = "Chrome extension ID, derived from the pinned key. Null if the extension isn't key-pinned."; + }; + drv = lib.mkOption { + type = lib.types.package; + description = "Unpacked extension derivation."; + }; + }; + }; in { - aria2Explorer = mkExtension ./aria2-explorer.nix; - browserpass = mkExtension ./browserpass.nix; - darkMode = mkExtension ./dark-mode.nix; - searxngHome = mkExtension ./searxng-home.nix; - theme = mkExtension ./theme.nix; - ublockOrigin = mkExtension ./ublock-origin.nix; + imports = [ + ./assertions.nix + ]; + + options.web.chromium.extensions = lib.mkOption { + type = lib.types.attrsOf extensionSubmodule; + internal = true; + default = { }; + description = '' + Resolved chromium extension derivations, keyed by name. Computed + internally from ./extensions/*.nix — not user-settable. Read from + other modules via e.g. `config.web.chromium.extensions.browserpass.id`. + ''; + }; + + # readOnly options get their actual value assigned here, in this same + # module's config — this is the one place allowed to set it. + config.web.chromium.extensions = { + aria2Explorer = mkExtension ./aria2-explorer.nix; + browserpass = mkExtension ./browserpass.nix; + darkMode = mkExtension ./dark-mode.nix; + searxngHome = mkExtension ./searxng-home.nix; + theme = mkExtension ./theme.nix; + ublockOrigin = mkExtension ./ublock-origin.nix; + }; } -- cgit v1.2.3