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