NixDaemon

NixOS pentest workstation as one flake — IceBreaker's successor
git clone https://git.daemon-sec.xyz/NixDaemon.git
Log | Files | Refs | README

zen.nix (4987B)


      1 # modules/home/zen.nix — Zen Browser, the default browser, sharing one
      2 # bookmarks file with Floorp.
      3 #
      4 # This module owns xdg.mimeApps for links and HTML and $BROWSER; the Niri and
      5 # Hyprland browser binds launch zen-beta too. Floorp stays installed
      6 # (modules/home/floorp.nix); to go back, move those settings to it.
      7 #
      8 # Zen is not in nixpkgs, so the package comes from the community flake
      9 # (inputs.zen-browser, pinned in flake.nix). `packages.default` is the general
     10 # release channel — the binary is literally `zen-beta` and versions carry a `b`,
     11 # which is how upstream labels its releases; `twilight` is the nightly.
     12 #
     13 # The profile is written by hand under ~/.zen, for the same reason as Floorp:
     14 # Zen's application.ini declares `Profile=zen`, so Gecko reads ~/.zen rather
     15 # than anywhere home-manager's Firefox-family modules would look.
     16 #
     17 # Bookmarks are NOT duplicated. The one encrypted export at
     18 # secrets/floorp/bookmarks.html (111 links, 19 folders, matching the live Floorp
     19 # profile) is declared here a second time under its own name so this module does
     20 # not depend on floorp.nix being imported. Edit it once with
     21 # `TMPDIR=/dev/shm sops secrets/floorp/bookmarks.html` and both browsers see it.
     22 #
     23 # Prefs live in Nix here, not sops, because nothing in them is private yet —
     24 # only the start page and the bookmark-file path. If this grows personal prefs,
     25 # move it to secrets/zen/user.js and mirror the sops.secrets block floorp.nix
     26 # uses.
     27 { ... }:
     28 {
     29   flake.homeModules.zen =
     30   { config, lib, pkgs, inputs, ... }:
     31   let
     32     profile = "daemon";
     33     profileDir = ".zen/${profile}";
     34     zen = inputs.zen-browser.packages.${pkgs.stdenv.hostPlatform.system}.default;
     35     bookmarksPath = config.sops.secrets."zen-bookmarks.html".path;
     36   in
     37   {
     38     home.packages = [ zen ];
     39 
     40     # Zen as the handler for links and HTML.
     41     xdg.mimeApps = {
     42       enable = true;
     43       defaultApplications = lib.genAttrs [
     44         "text/html"
     45         "application/xhtml+xml"
     46         "x-scheme-handler/http"
     47         "x-scheme-handler/https"
     48         "x-scheme-handler/about"
     49         "x-scheme-handler/unknown"
     50       ] (_: [ "zen-beta.desktop" ]);
     51     };
     52 
     53     home.sessionVariables.BROWSER = "zen-beta";
     54 
     55     # The same encrypted export Floorp imports, under its own secret name so
     56     # neither module needs the other. sops-nix is happy for two secrets to come
     57     # from one sopsFile; they decrypt to separate runtime paths.
     58     sops.secrets."zen-bookmarks.html" = {
     59       sopsFile = ../../secrets/floorp/bookmarks.html;
     60       format = "binary";
     61     };
     62 
     63     home.file = {
     64       # Written here rather than left to Zen so the Nix-built profile is the
     65       # default one. Trade-off, as with Floorp: profile changes made in Zen's
     66       # own profile manager are reverted on the next `nh os switch`.
     67       ".zen/profiles.ini".text = ''
     68         [Profile0]
     69         Name=${profile}
     70         IsRelative=1
     71         Path=${profile}
     72         Default=1
     73 
     74         [General]
     75         StartWithLastProfile=1
     76         Version=2
     77       '';
     78 
     79       # browser.places.importBookmarksHTML is deliberately absent: see the
     80       # activation script below for why it cannot live in user.js.
     81       "${profileDir}/user.js".text = ''
     82         // Managed by modules/home/zen.nix. Zen reads this only at startup.
     83         user_pref("browser.bookmarks.file", "${bookmarksPath}");
     84         // Don't let Zen's shipped default bookmarks compete with the import.
     85         user_pref("browser.bookmarks.restore_default_bookmarks", false);
     86         user_pref("browser.startup.homepage", "https://startpage.daemon-sec.xyz/");
     87         // No first-run tour or import wizard racing the seeded import.
     88         user_pref("browser.aboutwelcome.enabled", false);
     89         user_pref("browser.startup.firstrunSkipsHomepage", true);
     90         user_pref("datareporting.policy.firstRunURL", "");
     91       '';
     92     };
     93 
     94     # One-time bookmark import, same mechanism floorp.nix documents.
     95     #
     96     # `browser.places.importBookmarksHTML` is what makes Gecko read
     97     # browser.bookmarks.file into the places database. It cannot live in
     98     # user.js: the browser consumes it and sets it back to false, but user.js
     99     # re-applies every pref at every startup, so the import would run again on
    100     # each launch and duplicate all 111 bookmarks. Seeding it into prefs.js
    101     # instead, only while the profile has no places.sqlite yet, imports once on
    102     # first launch and never again.
    103     home.activation.zenSeedBookmarkImport = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
    104       zenProfile="$HOME/${profileDir}"
    105       zenPrefs="$zenProfile/prefs.js"
    106       if [ ! -e "$zenProfile/places.sqlite" ] \
    107         && ! grep -qs 'browser.places.importBookmarksHTML' "$zenPrefs"; then
    108         verboseEcho "Zen: seeding the one-time bookmark import in $zenPrefs"
    109         if [ -z "''${DRY_RUN:-}" ]; then
    110           mkdir -p "$zenProfile"
    111           printf '%s\n' 'user_pref("browser.places.importBookmarksHTML", true);' >> "$zenPrefs"
    112         fi
    113       fi
    114     '';
    115   }
    116   ;
    117 }