{
  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
      {};
  }