1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 cfg = config.programs.msmtp;
10
11in
12{
13 meta.maintainers = with lib.maintainers; [ euxane ];
14
15 options = {
16 programs.msmtp = {
17 enable = lib.mkEnableOption "msmtp - an SMTP client";
18
19 setSendmail = lib.mkOption {
20 type = lib.types.bool;
21 default = true;
22 description = ''
23 Whether to set the system sendmail to msmtp's.
24 '';
25 };
26
27 defaults = lib.mkOption {
28 type = lib.types.attrs;
29 default = { };
30 example = {
31 aliases = "/etc/aliases";
32 port = 587;
33 tls = true;
34 };
35 description = ''
36 Default values applied to all accounts.
37 See {manpage}`msmtp(1)` for the available options.
38 '';
39 };
40
41 accounts = lib.mkOption {
42 type = with lib.types; attrsOf attrs;
43 default = { };
44 example = {
45 "default" = {
46 host = "smtp.example";
47 auth = true;
48 user = "someone";
49 passwordeval = "cat /secrets/password.txt";
50 };
51 };
52 description = ''
53 Named accounts and their respective configurations.
54 The special name "default" allows a default account to be defined.
55 See {manpage}`msmtp(1)` for the available options.
56
57 Use `programs.msmtp.extraConfig` instead of this attribute set-based
58 option if ordered account inheritance is needed.
59
60 It is advised to use the `passwordeval` setting to read the password
61 from a secret file to avoid having it written in the world-readable
62 nix store. The password file must end with a newline (`\n`).
63 '';
64 };
65
66 extraConfig = lib.mkOption {
67 type = lib.types.lines;
68 default = "";
69 description = ''
70 Extra lines to add to the msmtp configuration verbatim.
71 See {manpage}`msmtp(1)` for the syntax and available options.
72 '';
73 };
74 };
75 };
76
77 config = lib.mkIf cfg.enable {
78 environment.systemPackages = [ pkgs.msmtp ];
79
80 services.mail.sendmailSetuidWrapper = lib.mkIf cfg.setSendmail {
81 program = "sendmail";
82 source = "${pkgs.msmtp}/bin/sendmail";
83 setuid = false;
84 setgid = false;
85 owner = "root";
86 group = "root";
87 };
88
89 environment.etc."msmtprc".text =
90 let
91 mkValueString =
92 v:
93 if v == true then
94 "on"
95 else if v == false then
96 "off"
97 else
98 lib.generators.mkValueStringDefault { } v;
99 mkKeyValueString = k: v: "${k} ${mkValueString v}";
100 mkInnerSectionString =
101 attrs: builtins.concatStringsSep "\n" (lib.mapAttrsToList mkKeyValueString attrs);
102 mkAccountString = name: attrs: ''
103 account ${name}
104 ${mkInnerSectionString attrs}
105 '';
106 in
107 ''
108 defaults
109 ${mkInnerSectionString cfg.defaults}
110
111 ${builtins.concatStringsSep "\n" (lib.mapAttrsToList mkAccountString cfg.accounts)}
112
113 ${cfg.extraConfig}
114 '';
115 };
116}