85 lines
2.1 KiB
Nix
85 lines
2.1 KiB
Nix
{
|
|
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;
|
|
radicaleHost = "cal.${domain}";
|
|
mailAccounts = cfg.loginAccounts;
|
|
discoveryHosts = lib.unique (
|
|
cfg.domains
|
|
++ [
|
|
cfg.fqdn
|
|
radicaleHost
|
|
]
|
|
);
|
|
|
|
accountHash =
|
|
mail: account:
|
|
if account.hashedPassword != null then
|
|
account.hashedPassword
|
|
else if account.hashedPasswordFile != null then
|
|
lib.removeSuffix "\n" (builtins.readFile account.hashedPasswordFile)
|
|
else
|
|
throw "Radicale requires ${mail} to define hashedPassword or hashedPasswordFile";
|
|
|
|
htpasswd = pkgs.writeText "radicale.users" (
|
|
lib.concatStrings (
|
|
lib.mapAttrsToList (mail: account: "${mail}:${accountHash mail account}\n") mailAccounts
|
|
)
|
|
);
|
|
|
|
mkWellKnownLocations = {
|
|
"/.well-known/caldav".return = "301 https://${radicaleHost}/";
|
|
"/.well-known/carddav".return = "301 https://${radicaleHost}/";
|
|
};
|
|
|
|
discoveryVirtualHosts = lib.listToAttrs (
|
|
map (host: {
|
|
name = host;
|
|
value = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations = mkWellKnownLocations;
|
|
};
|
|
}) discoveryHosts
|
|
);
|
|
in
|
|
{
|
|
services.radicale = {
|
|
enable = true;
|
|
settings = {
|
|
auth = {
|
|
type = "htpasswd";
|
|
htpasswd_filename = "${htpasswd}";
|
|
htpasswd_encryption = "bcrypt";
|
|
};
|
|
};
|
|
};
|
|
|
|
services.nginx.virtualHosts = discoveryVirtualHosts // {
|
|
${radicaleHost} = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations = mkWellKnownLocations // {
|
|
"/" = {
|
|
proxyPass = "http://127.0.0.1:5232/";
|
|
extraConfig = ''
|
|
proxy_set_header X-Script-Name /;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_pass_header Authorization;
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|
|
)
|