diff options
| -rw-r--r-- | modules/desktop/hyprland/default.nix | 4 | ||||
| -rw-r--r-- | modules/web/chromium/browserpass.nix | 1 | ||||
| -rw-r--r-- | modules/web/chromium/default.nix | 141 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/aria2-explorer.nix | 33 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/browserpass.nix | 35 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/dark-mode.nix | 32 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/default.nix | 15 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/lib.nix | 116 | ||||
| -rw-r--r-- | modules/web/chromium/extensions/ublock-origin.nix | 32 | ||||
| -rw-r--r-- | users/arpit.nix | 4 |
10 files changed, 347 insertions, 66 deletions
diff --git a/modules/desktop/hyprland/default.nix b/modules/desktop/hyprland/default.nix index 4c5281d..1e48e3f 100644 --- a/modules/desktop/hyprland/default.nix +++ b/modules/desktop/hyprland/default.nix @@ -20,13 +20,13 @@ in primaryCard = lib.mkOption { type = lib.types.str; - default = "/dev/dri/by-path/pci-0000:05:00.0-card"; + default = "/dev/dri/gpu-amd"; description = "Path to primary DRM card device for Aquamarine/Hyprland rendering"; }; secondaryCard = lib.mkOption { type = lib.types.nullOr lib.types.str; - default = "/dev/dri/by-path/pci-0000:01:00.0-card"; + default = "/dev/dri/gpu-nvidia"; description = "Path to secondary DRM card device for offloading (null if single GPU)"; }; }; diff --git a/modules/web/chromium/browserpass.nix b/modules/web/chromium/browserpass.nix index a07b1d7..860d46e 100644 --- a/modules/web/chromium/browserpass.nix +++ b/modules/web/chromium/browserpass.nix @@ -1,4 +1,3 @@ -# Browserpass - browser extension providing it access to your password store { lib, config, diff --git a/modules/web/chromium/default.nix b/modules/web/chromium/default.nix index f867e3b..8cf0bea 100644 --- a/modules/web/chromium/default.nix +++ b/modules/web/chromium/default.nix @@ -1,7 +1,7 @@ -# Chromium - Web browser configuration { config, lib, + pkgs, ... }: { @@ -17,77 +17,96 @@ defaultText = lib.literalExpression "config.programs.chromium.finalPackage"; description = "Package to use for chromium. Defaults to the wrapped finalPackage from programs.chromium."; }; + checkForUpdates = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Check GitHub for newer extension releases before building, and abort + with upgrade instructions if the pinned version is stale. Requires + network access during evaluation (pass --impure to nix/home-manager). + ''; + }; }; - config = lib.mkIf config.web.chromium.enable { - programs.chromium = { - enable = true; + config = lib.mkIf config.web.chromium.enable ( + let + exts = import ./extensions { + inherit lib pkgs; + checkForUpdates = config.web.chromium.checkForUpdates; + }; - commandLineArgs = [ - "--force-device-scale-factor=1.15" + extensionDirs = [ + exts.ublockOrigin.drv + exts.darkMode.drv + exts.browserpass.drv + exts.aria2Explorer.drv ]; - extensions = [ - { id = "ddkjiahejlhfcafbddmgiahcphecmpfh"; } # uBlock Origin Lite - { id = "naepdomgkenhinolocfifgehidddafch"; } # Browserpass - { id = "faeadnfmdfamenfhaipofoffijhlnkif"; } # True Amoled Black Theme - { id = "eimadpbcbfnmbkopoojfekhnkhdbieeh"; } # Dark Reader - { id = "mpkodccbngfoacfalldjimigbofkhgjn"; } # Aria2 Explorer + 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 = [ + "--force-device-scale-factor=1.15" + "--load-extension=${lib.concatStringsSep "," 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 { - browser = { - show_full_urls = true; - theme = { - follows_system_colors = true; + xdg.configFile."chromium/Default/Preferences" = { + force = true; + text = builtins.toJSON { + 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; - }; - credentials_enable_service = false; - credentials_enable_autosignin = false; - extensions = { - pinned_extensions = [ - "ddkjiahejlhfcafbddmgiahcphecmpfh" - "naepdomgkenhinolocfifgehidddafch" - "eimadpbcbfnmbkopoojfekhnkhdbieeh" - ]; - ui = { - developer_mode = true; + search = { + suggest_enabled = false; }; - }; - profile = { - default_content_setting_values = { - notifications = 2; + 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 = pinnedIds; + ui = { + developer_mode = true; + }; + }; + profile = { + default_content_setting_values = { + notifications = 2; + }; + }; + high_efficiency_mode_enabled = true; }; - high_efficiency_mode_enabled = true; }; - }; - }; + } + ); } diff --git a/modules/web/chromium/extensions/aria2-explorer.nix b/modules/web/chromium/extensions/aria2-explorer.nix new file mode 100644 index 0000000..1f6e5b1 --- /dev/null +++ b/modules/web/chromium/extensions/aria2-explorer.nix @@ -0,0 +1,33 @@ +{ + lib, + pkgs, + extLib, +}: +let + pname = "aria2-explorer"; + owner = "alexhua"; + repo = "Aria2-Explorer"; + version = "2.8.2"; + checkedVersion = extLib.checkExtensionVersion { + inherit + pname + owner + repo + version + ; + tagPrefix = "v"; + urlTemplate = "https://github.com/${owner}/${repo}/releases/download/v<version>/A2E-v<version>.crx"; + }; +in +{ + inherit pname; + version = checkedVersion; + id = "dkcfilkhokojanlmgpbmjidiidoebnbm"; + drv = extLib.fetchUnpackedExtension { + inherit pname; + version = checkedVersion; + url = "https://github.com/${owner}/${repo}/releases/download/v${checkedVersion}/A2E-v${checkedVersion}.crx"; + hash = "sha256-ljTgKd9QJTRJ11rlNx+PTynlQvdLW3IEoYNnCeOU2K8="; + isCrx = true; + }; +} diff --git a/modules/web/chromium/extensions/browserpass.nix b/modules/web/chromium/extensions/browserpass.nix new file mode 100644 index 0000000..527f073 --- /dev/null +++ b/modules/web/chromium/extensions/browserpass.nix @@ -0,0 +1,35 @@ +{ + lib, + pkgs, + extLib, +}: +let + pname = "browserpass"; + owner = "browserpass"; + repo = "browserpass-extension"; + version = "3.12.0"; + checkedVersion = extLib.checkExtensionVersion { + inherit + pname + owner + repo + version + ; + tagPrefix = ""; + urlTemplate = "https://github.com/${owner}/${repo}/releases/download/<version>/browserpass-webstore-<version>.crx"; + }; +in +{ + inherit pname; + version = checkedVersion; + # Stable webstore ID — only holds if the crx's manifest.json embeds "key". + # Verify at chrome://extensions after switching; update if it drifts. + id = "klfoddkbhleoaabpmiigbmpbjfljimgb"; + drv = extLib.fetchUnpackedExtension { + inherit pname; + version = checkedVersion; + url = "https://github.com/${owner}/${repo}/releases/download/${checkedVersion}/browserpass-webstore-${checkedVersion}.crx"; + hash = "sha256-NfLbEe2EBctmntJqbsIpwm2WRFdo8q6yjWGjVK2MmFE="; + isCrx = true; + }; +} diff --git a/modules/web/chromium/extensions/dark-mode.nix b/modules/web/chromium/extensions/dark-mode.nix new file mode 100644 index 0000000..4ac9040 --- /dev/null +++ b/modules/web/chromium/extensions/dark-mode.nix @@ -0,0 +1,32 @@ +{ + lib, + pkgs, + extLib, +}: +let + pname = "dark-mode"; + owner = "code-charity"; + repo = "dark-mode"; + version = "3.3.11"; + checkedVersion = extLib.checkExtensionVersion { + inherit + pname + owner + repo + version + ; + tagPrefix = "v"; + urlTemplate = "https://github.com/${owner}/${repo}/archive/refs/tags/v<version>.zip"; + }; +in +{ + inherit pname; + version = checkedVersion; + id = "ifpghghnlimndidoppdkdnbljddikfoj"; + drv = extLib.fetchUnpackedExtension { + inherit pname; + version = checkedVersion; + url = "https://github.com/${owner}/${repo}/archive/refs/tags/v${checkedVersion}.zip"; + hash = "sha256-Lt3T8i0ylV0l+T0eqnzs6veBcOpizhP79LgSkUx4xI8="; + }; +} diff --git a/modules/web/chromium/extensions/default.nix b/modules/web/chromium/extensions/default.nix new file mode 100644 index 0000000..a44286e --- /dev/null +++ b/modules/web/chromium/extensions/default.nix @@ -0,0 +1,15 @@ +{ + lib, + pkgs, + checkForUpdates ? true, +}: +let + extLib = import ./lib.nix { inherit lib pkgs checkForUpdates; }; + mkExtension = path: import path { inherit lib pkgs extLib; }; +in +{ + ublockOrigin = mkExtension ./ublock-origin.nix; + darkMode = mkExtension ./dark-mode.nix; + browserpass = mkExtension ./browserpass.nix; + aria2Explorer = mkExtension ./aria2-explorer.nix; +} diff --git a/modules/web/chromium/extensions/lib.nix b/modules/web/chromium/extensions/lib.nix new file mode 100644 index 0000000..f5e83a1 --- /dev/null +++ b/modules/web/chromium/extensions/lib.nix @@ -0,0 +1,116 @@ +{ + lib, + pkgs, + checkForUpdates ? true, +}: +rec { + # --- Hit the GitHub releases API and return the latest tag name. --- + # Impure: requires --impure since there's no fixed output hash for the API + # response itself. Optionally uses $GITHUB_TOKEN to dodge rate limits. + fetchLatestGithubReleaseTag = + { owner, repo }: + let + token = builtins.getEnv "GITHUB_TOKEN"; + raw = builtins.fetchurl { + url = "https://api.github.com/repos/${owner}/${repo}/releases/latest"; + name = "${repo}-latest-release.json"; + }; + json = builtins.fromJSON (builtins.readFile raw); + in + json.tag_name; + + # --- Compare pinned version against upstream latest, abort with instructions if stale. --- + # Returns `version` unchanged on success so it can be threaded into the + # derivation below and force this check to actually run. + checkExtensionVersion = + { + pname, + owner, + repo, + version, + urlTemplate, # human-readable template shown in the error message + tagPrefix ? "", # e.g. "v" if tags look like "v1.2.3" + }: + if !checkForUpdates then + version + else + let + latestTag = fetchLatestGithubReleaseTag { inherit owner repo; }; + latestVersion = + if lib.hasPrefix tagPrefix latestTag then lib.removePrefix tagPrefix latestTag else latestTag; + in + if latestVersion != version then + throw '' + [${pname}] A newer release is available upstream — refusing to build a stale extension. + + pinned version : ${version} + latest version : ${latestVersion} (tag: ${latestTag}) + + To upgrade, edit extensions/${pname}.nix: + 1. Set version = "${latestVersion}"; + 2. Point the url at the new release asset: + ${urlTemplate} + 3. Set hash = lib.fakeHash; + then re-run your switch — it'll fail with a hash mismatch showing + the real sha256. Paste that in as the final hash. + 4. Re-run once more. This check passes once pinned == latest. + + To skip this check for now (e.g. offline / pure eval), set: + web.chromium.checkForUpdates = false; + '' + else + version; + + # --- Download + unpack a zip *or* crx into a plain unpacked-extension dir. --- + # A CRX3 file is just: "Cr24" magic (4B) + version (4B) + header length N (4B) + # + N bytes of protobuf header + a normal zip payload. We slice off the + # header when isCrx = true, then unzip exactly like any other release zip — + # so every extension, crx or not, goes through one identical pipeline. + fetchUnpackedExtension = + { + pname, + version, + url, + hash, + isCrx ? false, + }: + pkgs.stdenv.mkDerivation { + inherit pname version; + src = pkgs.fetchurl { inherit url hash; }; + nativeBuildInputs = [ + pkgs.unzip + pkgs.python3 + ]; + dontUnpack = true; + + buildPhase = '' + runHook preBuild + mkdir -p $out + + if [ "${lib.boolToString isCrx}" = "true" ]; then + offset=$(python3 -c " + import struct + with open('$src', 'rb') as f: + magic, ver, hlen = struct.unpack('<4sII', f.read(12)) + assert magic == b'Cr24', 'not a CRX file' + print(12 + hlen) + ") + dd if=$src of=payload.zip bs=1 skip=$offset status=none + unzip -q payload.zip -d $out + else + unzip -q $src -d $out + fi + + # Flatten a single wrapping folder (common in GitHub release zips) + if [ "$(ls -1 $out | wc -l)" -eq 1 ] && [ -d "$out"/* ]; then + shopt -s dotglob + mv "$out"/*/* "$out"/ 2>/dev/null || true + rmdir "$out"/*/ 2>/dev/null || true + shopt -u dotglob + fi + runHook postBuild + ''; + + installPhase = "true"; + }; +} diff --git a/modules/web/chromium/extensions/ublock-origin.nix b/modules/web/chromium/extensions/ublock-origin.nix new file mode 100644 index 0000000..7d11ee4 --- /dev/null +++ b/modules/web/chromium/extensions/ublock-origin.nix @@ -0,0 +1,32 @@ +{ + lib, + pkgs, + extLib, +}: +let + pname = "ublock-origin"; + owner = "gorhill"; + repo = "uBlock"; + version = "1.72.2"; + checkedVersion = extLib.checkExtensionVersion { + inherit + pname + owner + repo + version + ; + tagPrefix = ""; + urlTemplate = "https://github.com/${owner}/${repo}/releases/download/<version>/uBlock0_<version>.chromium.zip"; + }; +in +{ + inherit pname; + version = checkedVersion; + id = "nnpdegnhelmjgchicpfdigllmhgpndeg"; # unpacked, ID derives from manifest key at load time + drv = extLib.fetchUnpackedExtension { + inherit pname; + version = checkedVersion; + url = "https://github.com/${owner}/${repo}/releases/download/${checkedVersion}/uBlock0_${checkedVersion}.chromium.zip"; + hash = "sha256-0QTKxOH0jXaxw/+Irt4uqoJpgUrgbMnIUNJ6+1J05TM="; + }; +} diff --git a/users/arpit.nix b/users/arpit.nix index 19d3204..df99fed 100644 --- a/users/arpit.nix +++ b/users/arpit.nix @@ -17,8 +17,8 @@ desktop.hardware.gpu = { nvidia.enable = true; amd.enable = true; - primaryCard = "/dev/dri/by-path/pci-0000:05:00.0-card"; - secondaryCard = "/dev/dri/by-path/pci-0000:01:00.0-card"; + primaryCard = "/dev/dri/gpu-amd"; + secondaryCard = "/dev/dri/gpu-nvidia"; }; # Gaming |
