{ config, lib, ... }: let cfg = config.distrust.services; in { options = { distrust = { services = lib.mkOption { description = "Services configuration map"; type = lib.types.attrsOf ( lib.types.submodule { options = { url = lib.mkOption { description = "Clearnet URL"; type = lib.types.str; }; onion = lib.mkOption { description = "Onion service settings"; type = lib.types.submodule { options = { url = lib.mkOption { description = ".onion URL"; type = lib.types.str; }; secretKey = lib.mkOption { description = "Path to onion secret key file"; type = lib.types.path; }; }; }; default = {}; }; virtualHostConfig = lib.mkOption { description = "Caddy virtual host config"; type = lib.types.str; }; }; } ); default = {}; }; }; }; config = { services.tor.relay.onionServices = builtins.foldl' (acc: key: acc // { "${key}" = { map = [80]; inherit (cfg.${key}.onion) secretKey; }; }) {} (builtins.attrNames cfg); services.caddy = { enable = true; virtualHosts = builtins.foldl' (acc: key: let site = cfg.${key}; vhostKey = "${site.url} ${site.onion.url}"; extraCfg = '' ${site.virtualHostConfig or ""} header Onion-Location ${site.onion.url} ''; in acc // { "${vhostKey}" = { extraConfig = extraCfg; }; }) {} (builtins.attrNames cfg); }; }; }