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