{
config,
lib,
pkgs,
...
}:
let
cfg = config.mailserver;
hasMailDiscoveryConfig = cfg.enable && cfg.fqdn != null && cfg.domains != [ ];
in
lib.mkIf hasMailDiscoveryConfig (
let
domain = builtins.head cfg.domains;
mobileconfigHost = "autoconfig.${domain}";
radicaleHost = "cal.${domain}";
safeAccountName = email: builtins.replaceStrings [ "@" "+" ] [ "_" "-" ] email;
emailQueryPattern = email:
builtins.replaceStrings [
"\\+"
"@"
] [
"(?:\\+|%2B)"
"(?:@|%40)"
] (lib.escapeRegex email);
mkUuid = seed:
let
hash = builtins.hashString "sha256" seed;
in
"${lib.substring 0 8 hash}-${lib.substring 8 4 hash}-${lib.substring 12 4 hash}-${lib.substring 16 4 hash}-${lib.substring 20 12 hash}";
mkMobileconfig = email:
let
safeName = safeAccountName email;
profileUuid = mkUuid "${email}-apple-profile";
mailUuid = mkUuid "${email}-apple-mail";
caldavUuid = mkUuid "${email}-apple-caldav";
carddavUuid = mkUuid "${email}-apple-carddav";
in
pkgs.writeText "${safeName}.mobileconfig" ''
Open this page in Safari on iPhone, iPad, or macOS and enter your email address to download the configuration profile.
The profile configures IMAP, SMTP, CalDAV, and CardDAV. You will still be asked for your password during installation.
''; mobileconfigRedirectConfig = lib.concatStrings ( lib.mapAttrsToList ( email: profile: '' if ($arg_emailaddress ~* "^${emailQueryPattern email}$") { return 302 /mobileconfig/${profile.safeName}.mobileconfig; } '' ) mobileconfigProfiles ); mobileconfigLocations = lib.listToAttrs ( [ { name = "= /mobileconfig"; value.return = "308 /mobileconfig/"; } { name = "= /mobileconfig/"; value.extraConfig = '' ${mobileconfigRedirectConfig} return 302 /mobileconfig/index.html; ''; } { name = "= /mobileconfig/index.html"; value.extraConfig = '' default_type text/html; alias ${mobileconfigLandingPage}; ''; } ] ++ lib.mapAttrsToList ( _: profile: { name = "= /mobileconfig/${profile.safeName}.mobileconfig"; value.extraConfig = '' default_type application/x-apple-aspen-config; add_header Content-Disposition 'attachment; filename="${profile.safeName}.mobileconfig"' always; alias ${profile.profile}; ''; } ) mobileconfigProfiles ); defaultMobileconfigLocation = let accounts = lib.attrNames mobileconfigProfiles; in if lib.length accounts == 1 then let profile = mobileconfigProfiles.${builtins.head accounts}; in { "= /mobileconfig/billenius.mobileconfig".extraConfig = '' default_type application/x-apple-aspen-config; add_header Content-Disposition 'attachment; filename="billenius.mobileconfig"' always; alias ${profile.profile}; ''; } else { }; in { services.nginx.virtualHosts.${mobileconfigHost}.locations = mobileconfigLocations // defaultMobileconfigLocation; } )