{
  config,
  lib,
  fn,
  mailserver,
  ...
}:
with lib;
{
  imports = [
    mailserver.nixosModules.mailserver
  ];
}
// mkIf (elem "mailserver" config.machine.services) {
  mailserver =
    let
      cfg = config.machine;
      inherit (cfg) domain;
      fdomain = (findFirst (s: s.service == "mail") cfg cfg.vHosts).domain;
      mkFqdnAlias = name: [
        "${name}@${domain}"
        "${name}@${fdomain}"
      ];
      mkExDomAlias = name: (map (exDom: "${name}@${exDom}") cfg.extraDomains);
      mkUser = user: rec {
        name = "${user.name}@${domain}";
        value = {
          hashedPasswordFile = config.sops.secrets."users/${user.name}/mail".path;
          aliases =
            [ "${user.name}@${fdomain}" ]
            ++ (flatten (map mkFqdnAlias user.aliases))
            ++ (flatten (map mkExDomAlias ([ user.name ] ++ user.aliases)));
        };
      };
    in
    rec {
      enable = true;
      fqdn = fdomain;
      domains = [
        fdomain
        domain
      ] ++ cfg.extraDomains;
      loginAccounts = listToAttrs (map mkUser cfg.mailAccounts);

      # Use Let's Encrypt certificates. Note that this needs to set up a stripped
      # down nginx and opens port 80.
      certificateScheme = "manual";
      certificateFile = "/var/lib/acme/" + fdomain + "/fullchain.pem";
      keyFile = "/var/lib/acme/" + fdomain + "/key.pem";

      #dhParamBitLength = 4096; # this doesn't exist???

      # Enable IMAP and POP3
      enableImap = true;
      enablePop3 = false;
      enableImapSsl = true;
      enablePop3Ssl = false;

      # Enable the ManageSieve protocol
      enableManageSieve = true;

      # whether to scan inbound emails for viruses (note that this requires at least
      # 1 Gb RAM for the server. Without virus scanning 256 MB RAM should be plenty)
      virusScanning = false;
    };
  sops.secrets = fn.sopsHelper (user: "users/${user.name}/mail") config.machine.mailAccounts { };
}