{ pkgs, lib, inputs, config, system, ... }: let tomlFormat = pkgs.formats.toml { }; cfg = config.programs.captive-browser; inherit (pkgs.stdenv.hostPlatform) isDarwin; in { options.programs.captive-browser = { enable = lib.mkEnableOption "Enable custom captive-browser in user PATH"; package = lib.mkPackageOption pkgs "captive-browser" { nullable = true; }; settings = lib.mkOption { type = lib.types.submodule { freeformType = tomlFormat.type; options = { browser = lib.mkOption { type = lib.types.str; description = "command to invoke the browser with"; # browser is the shell (/bin/sh) command executed once the proxy starts. # When browser exits, the proxy exits. An extra env var PROXY is available. # # Here, we use a separate Chrome instance in Incognito mode, so that # it can run (and be waited for) alongside the default one, and that # it maintains no state across runs. To configure this browser open a # normal window in it, settings will be preserved. default = '' ${cfg.browserCommand} \ --user-data-dir="$HOME/Library/Application Support/Google/Captive" \ --proxy-server="socks5://$PROXY" \ --host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE localhost" \ --no-first-run --new-window --incognito \ http://example.com ''; }; }; }; }; interface = lib.mkOption { type = lib.types.str; description = "WLAN interface to use"; }; browserCommand = lib.mkOption { type = lib.types.str; default = if isDarwin then "open -n -W -a \"Google Chrome\" --args" else (lib.getExe pkgs.chromium); }; }; config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; programs.captive-browser.settings = builtins.mapAttrs (_: lib.mkOptionDefault) { # dhcp-dns is the shell (/bin/sh) command executed to obtain the DHCP # DNS server address. The first match of an IPv4 regex is used. # IPv4 only, because let's be real, it's a captive portal. dhcp-dns = if isDarwin then "ipconfig getoption ${cfg.interface} domain_name_server" else "${lib.getExe pkgs.dhcpcd} -U ${cfg.interface} | grep domain_name_servers"; # socks5-addr is the listen address for the SOCKS5 proxy server. socks5-addr = "localhost:1666"; }; home.file.".config/captive-browser.toml" = lib.mkIf (isDarwin && !config.xdg.enable) { source = tomlFormat.generate "captive-browser-config" cfg.settings; }; xdg.configFile."captive-browser.toml" = lib.mkIf (!(isDarwin && !config.xdg.enable)) { source = tomlFormat.generate "captive-browser-config" cfg.settings; }; }; }