{ pkgs, lib, config, ... }: let inherit (config.services) public-inbox; inherit (config.users) groups; orga = "sourcephile"; domain = "${orga}.fr"; repositories = [ "doclang" "majurity" "reloto" "haskell/symantic" "haskell/symantic-atom" "haskell/symantic-base" "haskell/symantic-cli" "haskell/symantic-compta" "haskell/symantic-document" "haskell/symantic-http" "haskell/symantic-parser" "haskell/symantic-xml" ]; in # Pour supprimer un message : # curl https://mails.sourcephile.fr/inbox/environnement/8ea699887ca47797b4460053588cbef2d115829ab4@vieber.ru/raw | # sudo -u public-inbox public-inbox-learn rm { security.acme.certs."${domain}" = { postRun = "systemctl try-restart public-inbox-nntpd public-inbox-imapd"; }; networking.nftables.ruleset = '' add rule inet filter net2fw tcp dport ${toString public-inbox.nntp.port} counter accept comment "NNTPS" add rule inet filter net2fw tcp dport 1993 counter accept comment "IMAPS" ''; fileSystems."/var/lib/public-inbox" = { device = "rpool/var/public-inbox"; fsType = "zfs"; }; systemd.services = { public-inbox-httpd = { serviceConfig = { SupplementaryGroups = [ groups."git-daemon".name ]; BindReadOnlyPaths = [ "/var/lib/acme/${domain}" ]; }; }; public-inbox-imapd = { wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service"]; after = [ "acme-selfsigned-${domain}.service" ]; serviceConfig = { SupplementaryGroups = [ groups."acme".name ]; BindReadOnlyPaths = [ "/var/lib/acme/${domain}" ]; }; }; public-inbox-nntpd = { wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service"]; after = [ "acme-selfsigned-${domain}.service" ]; serviceConfig = { SupplementaryGroups = [ groups."acme".name ]; BindReadOnlyPaths = [ "/var/lib/acme/${domain}" ]; }; }; }; services.public-inbox = { enable = true; settings.publicinbox = { css = [ "href=https://mails.${domain}/style/light.css" ]; nntpserver = [ "nntps://news.${domain}" ]; wwwlisting = "match=domain"; }; mda = { enable = true; args = [ "--no-precheck" ]; # Allow Bcc: }; http = { enable = true; port = "/run/public-inbox-http.sock"; #port = 8080; args = ["-W0"]; mounts = [ "https://mails.${domain}/inbox" "https://public-inbox.${domain}/inbox" ]; }; nntp = { enable = true; #port = 563; args = ["-W0"]; cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; imap = { enable = true; # FIXME: find an IP or .onion to put 993 port = null; args = [ "-W0" "--listen" "imaps://0.0.0.0:1993" ]; #args = ["-W0"]; cert = "/var/lib/acme/${domain}/fullchain.pem"; key = "/var/lib/acme/${domain}/key.pem"; }; inboxes = { news = { address = [ "news@${domain}" "public-inbox+news@${domain}" ]; description = '' news@${domain} : annonces d'informations concernant importantes ''; url = "https://mails.${domain}/inbox/news"; newsgroup = "inbox.comp.${orga}.news"; #coderepo = [ "sourcephile-txt" ]; }; chat = { address = [ "chat@${domain}" "public-inbox+chat@${domain}" ]; description = '' chat@${domain} : discussions concernant l'informatique en général. ''; url = "https://mails.${domain}/inbox/chat"; newsgroup = "inbox.comp.${orga}.chat"; }; contact = { address = [ "contact@${domain}" "public-inbox+contact@${domain}" ]; description = '' contact@${domain} : discussions avec le grand public. ''; url = "https://mails.${domain}/inbox/contact"; newsgroup = "inbox.comp.${orga}.contact"; #coderepo = [ "${orga}" ]; }; environnement = { address = [ "environnement@${domain}" "public-inbox+environnement@${domain}" ]; description = '' environnement@${domain} : discussions sur les impacts environnementaux de l'informatique. ''; url = "https://mails.${domain}/inbox/environnement"; newsgroup = "inbox.comp.${orga}.environnement"; #coderepo = [ "sourcephile-txt" ]; }; labo = { address = [ "labo@${domain}" "public-inbox+labo@${domain}" ]; description = '' labo@${domain} : discussions concernant la science de l'informatique. ''; url = "https://mails.${domain}/inbox/labo"; newsgroup = "inbox.comp.${orga}.labo"; # TODO: list many source code repositories #coderepo = [ "sourcephile-txt" ]; }; prod = { address = [ "prod@${domain}" "public-inbox+prod@${domain}" ]; description = '' prod@${domain} : discussions concernant l'administration technique de l'infrastructure informatique. ''; url = "https://mails.${domain}/inbox/prod"; newsgroup = "inbox.comp.${orga}.prod"; #coderepo = [ "sourcephile-txt" "sourcephile-nix" ]; }; orga = { address = [ "orga@${domain}" "public-inbox+orga@${domain}" ]; description = '' orga@${domain} : discussions à l'attention de l'ensemble des personnes à bord. ''; url = "https://mails.${domain}/inbox/orga"; newsgroup = "inbox.comp.${orga}.orga"; #coderepo = [ "sourcephile-txt" ]; }; test = { address = [ "test@${domain}" "public-inbox+test@${domain}" ]; description = '' test@${domain} : une cible de test pour effectuer des tirs de mails. ''; url = "https://mails.${domain}/inbox/test"; newsgroup = "inbox.comp.${orga}.test"; hide = [ /* FIXME: doesn't work for IMAP */"imap" "www" "manifest" ]; }; } // lib.genAttrs (map baseNameOf repositories) (name: { address = [ "${name}@${domain}" "public-inbox+${name}@${domain}" ]; description = '' ${name}@${domain} : discussions about ${name}. ''; url = "https://mails.${domain}/inbox/${name}"; newsgroup = "inbox.comp.${orga}.${name}"; coderepo = [ name ]; }); settings.coderepo = { sourcephile-txt = { dir = "/var/lib/gitolite/repositories/sourcephile-txt.git"; cgitUrl = "https://code.${domain}/sourcephile-txt.git"; }; sourcephile-nix = { dir = "/var/lib/gitolite/repositories/sourcephile-nix.git"; cgitUrl = "https://code.${domain}/sourcephile-nix.git"; }; } // lib.listToAttrs (map (path: lib.nameValuePair (baseNameOf path) { dir = "/var/lib/gitolite/repositories/${path}.git"; cgitUrl = "https://code.${domain}/${path}.git"; }) repositories); }; services.postfix.virtual = lib.concatMapStringsSep "\n" (name: '' ${name}@${domain} public-inbox@localhost '') (map baseNameOf repositories); services.sanoid.datasets."rpool/var/public-inbox" = { use_template = [ "snap" ]; daily = 7; }; }