nixos/preload: init
[NixPkgs.git] / nixos / modules / programs / firefox.nix
blob1edf935d1649ebf024ce113b7be230f33a7b2f82
1 { pkgs, config, lib, ... }:
3 with lib;
5 let
6   cfg = config.programs.firefox;
8   policyFormat = pkgs.formats.json { };
10   organisationInfo = ''
11     When this option is in use, Firefox will inform you that "your browser
12     is managed by your organisation". That message appears because NixOS
13     installs what you have declared here such that it cannot be overridden
14     through the user interface. It does not mean that someone else has been
15     given control of your browser, unless of course they also control your
16     NixOS configuration.
17   '';
19   # deprecated per-native-messaging-host options
20   nmhOptions = {
21     browserpass = {
22       name = "Browserpass";
23       package = pkgs.browserpass;
24     };
25     bukubrow = {
26       name = "Bukubrow";
27       package = pkgs.bukubrow;
28     };
29     euwebid = {
30       name = "Web eID";
31       package = pkgs.web-eid-app;
32     };
33     ff2mpv = {
34       name = "ff2mpv";
35       package = pkgs.ff2mpv;
36     };
37     fxCast = {
38       name = "fx_cast";
39       package = pkgs.fx-cast-bridge;
40     };
41     gsconnect = {
42       name = "GSConnect";
43       package = pkgs.gnomeExtensions.gsconnect;
44     };
45     jabref = {
46       name = "JabRef";
47       package = pkgs.jabref;
48     };
49     passff = {
50       name = "PassFF";
51       package = pkgs.passff-host;
52     };
53     tridactyl = {
54       name = "Tridactyl";
55       package = pkgs.tridactyl-native;
56     };
57     ugetIntegrator = {
58       name = "Uget Integrator";
59       package = pkgs.uget-integrator;
60     };
61   };
64   options.programs.firefox = {
65     enable = mkEnableOption (mdDoc "the Firefox web browser");
67     package = mkOption {
68       type = types.package;
69       default = pkgs.firefox;
70       description = mdDoc "Firefox package to use.";
71       defaultText = literalExpression "pkgs.firefox";
72       relatedPackages = [
73         "firefox"
74         "firefox-beta-bin"
75         "firefox-bin"
76         "firefox-devedition-bin"
77         "firefox-esr"
78       ];
79     };
81     wrapperConfig = mkOption {
82       type = types.attrs;
83       default = {};
84       description = mdDoc "Arguments to pass to Firefox wrapper";
85     };
87     policies = mkOption {
88       type = policyFormat.type;
89       default = { };
90       description = mdDoc ''
91         Group policies to install.
93         See [Mozilla's documentation](https://mozilla.github.io/policy-templates/)
94         for a list of available options.
96         This can be used to install extensions declaratively! Check out the
97         documentation of the `ExtensionSettings` policy for details.
99         ${organisationInfo}
100       '';
101     };
103     preferences = mkOption {
104       type = with types; attrsOf (oneOf [ bool int str ]);
105       default = { };
106       description = mdDoc ''
107         Preferences to set from `about:config`.
109         Some of these might be able to be configured more ergonomically
110         using policies.
112         ${organisationInfo}
113       '';
114     };
116     preferencesStatus = mkOption {
117       type = types.enum [ "default" "locked" "user" "clear" ];
118       default = "locked";
119       description = mdDoc ''
120         The status of `firefox.preferences`.
122         `status` can assume the following values:
123         - `"default"`: Preferences appear as default.
124         - `"locked"`: Preferences appear as default and can't be changed.
125         - `"user"`: Preferences appear as changed.
126         - `"clear"`: Value has no effect. Resets to factory defaults on each startup.
127       '';
128     };
130     languagePacks = mkOption {
131       # Available languages can be found in https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/
132       type = types.listOf (types.enum ([
133         "ach"
134         "af"
135         "an"
136         "ar"
137         "ast"
138         "az"
139         "be"
140         "bg"
141         "bn"
142         "br"
143         "bs"
144         "ca-valencia"
145         "ca"
146         "cak"
147         "cs"
148         "cy"
149         "da"
150         "de"
151         "dsb"
152         "el"
153         "en-CA"
154         "en-GB"
155         "en-US"
156         "eo"
157         "es-AR"
158         "es-CL"
159         "es-ES"
160         "es-MX"
161         "et"
162         "eu"
163         "fa"
164         "ff"
165         "fi"
166         "fr"
167         "fy-NL"
168         "ga-IE"
169         "gd"
170         "gl"
171         "gn"
172         "gu-IN"
173         "he"
174         "hi-IN"
175         "hr"
176         "hsb"
177         "hu"
178         "hy-AM"
179         "ia"
180         "id"
181         "is"
182         "it"
183         "ja"
184         "ka"
185         "kab"
186         "kk"
187         "km"
188         "kn"
189         "ko"
190         "lij"
191         "lt"
192         "lv"
193         "mk"
194         "mr"
195         "ms"
196         "my"
197         "nb-NO"
198         "ne-NP"
199         "nl"
200         "nn-NO"
201         "oc"
202         "pa-IN"
203         "pl"
204         "pt-BR"
205         "pt-PT"
206         "rm"
207         "ro"
208         "ru"
209         "sco"
210         "si"
211         "sk"
212         "sl"
213         "son"
214         "sq"
215         "sr"
216         "sv-SE"
217         "szl"
218         "ta"
219         "te"
220         "th"
221         "tl"
222         "tr"
223         "trs"
224         "uk"
225         "ur"
226         "uz"
227         "vi"
228         "xh"
229         "zh-CN"
230         "zh-TW"
231       ]));
232       default = [ ];
233       description = mdDoc ''
234         The language packs to install.
235       '';
236     };
238     autoConfig = mkOption {
239       type = types.lines;
240       default = "";
241       description = mdDoc ''
242         AutoConfig files can be used to set and lock preferences that are not covered
243         by the policies.json for Mac and Linux. This method can be used to automatically
244         change user preferences or prevent the end user from modifiying specific
245         preferences by locking them. More info can be found in https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig.
246       '';
247     };
249     nativeMessagingHosts = ({
250       packages = mkOption {
251         type = types.listOf types.package;
252         default = [];
253         description = mdDoc ''
254           Additional packages containing native messaging hosts that should be made available to Firefox extensions.
255         '';
256       };
257     }) // (mapAttrs (k: v: mkEnableOption (mdDoc "${v.name} support")) nmhOptions);
258   };
260   config = let
261     forEachEnabledNmh = fn: flatten (mapAttrsToList (k: v: lib.optional cfg.nativeMessagingHosts.${k} (fn k v)) nmhOptions);
262   in mkIf cfg.enable {
263     warnings = forEachEnabledNmh (k: v:
264       "The `programs.firefox.nativeMessagingHosts.${k}` option is deprecated, " +
265       "please add `${v.package.pname}` to `programs.firefox.nativeMessagingHosts.packages` instead."
266     );
267     programs.firefox.nativeMessagingHosts.packages = forEachEnabledNmh (_: v: v.package);
269     environment.systemPackages = [
270       (cfg.package.override (old: {
271         extraPrefsFiles = old.extraPrefsFiles or [] ++ [(pkgs.writeText "firefox-autoconfig.js" cfg.autoConfig)];
272         nativeMessagingHosts = old.nativeMessagingHosts or [] ++ cfg.nativeMessagingHosts.packages;
273         cfg = (old.cfg or {}) // cfg.wrapperConfig;
274       }))
275     ];
277     environment.etc =
278       let
279         policiesJSON = policyFormat.generate "firefox-policies.json" { inherit (cfg) policies; };
280       in
281       mkIf (cfg.policies != { }) {
282         "firefox/policies/policies.json".source = "${policiesJSON}";
283       };
285     # Preferences are converted into a policy
286     programs.firefox.policies = {
287       Preferences = (mapAttrs
288         (_: value: { Value = value; Status = cfg.preferencesStatus; })
289         cfg.preferences);
290       ExtensionSettings = listToAttrs (map
291         (lang: nameValuePair
292           "langpack-${lang}@firefox.mozilla.org"
293           {
294             installation_mode = "normal_installed";
295             install_url = "https://releases.mozilla.org/pub/firefox/releases/${cfg.package.version}/linux-x86_64/xpi/${lang}.xpi";
296           }
297         )
298         cfg.languagePacks);
299     };
300   };
302   meta.maintainers = with maintainers; [ danth ];