{ povSelf, config, lib, ... }: let inherit (lib) types; cfg = lib.getAttrFromPath povSelf config; in { options = { enable = { type = types.bool; default = false; }; domain = { type = types.str; }; adminUsers = { type = with types; listOf str; default = []; }; }; config = lib.mkIf cfg.enable { dns.zones."${cfg.domain}" = { SRV = [ { proto = "tcp"; service = "xmpp-server"; priority = 0; weight = 5; port = 5269; target = "xmpp.${cfg.domain}."; } { proto = "tcp"; service = "xmpp-client"; priority = 0; weight = 5; port = 5222; target = "xmpp.${cfg.domain}."; } ]; subdomains = { "muc.xmpp".SRV = [ { proto = "tcp"; service = "xmpp-server"; priority = 0; weight = 5; port = 5269; target = "xmpp.${cfg.domain}."; } ]; "upload.xmpp".CNAME = [ "${config.networking.fqdn}." ]; xmpp.CNAME = [ "${config.networking.fqdn}." ]; }; }; networking.firewall.allowedTCPPorts = [ 5269 5222 ] ++ config.services.prosody.httpsPorts; modules.filesystem.impermanence.system.dirs = [ { directory = config.services.prosody.dataDir; mode = "755"; user = config.services.prosody.user; group = config.services.prosody.group; } ]; security.acme.certs."${cfg.domain}" = { group = config.services.prosody.group; reloadServices = [ "prosody.service" ]; extraDomainNames = [ "xmpp.${cfg.domain}" "muc.xmpp.${cfg.domain}" "upload.xmpp.${cfg.domain}" ]; }; services.prosody = { enable = true; allowRegistration = false; authentication = "internal_hashed"; admins = cfg.adminUsers; # c2sRequireEncryption = true; # s2sSecureAuth = true; disco_items = [ { url = "muc.xmpp.${cfg.domain}"; description = "Channels"; } { url = "upload.xmpp.${cfg.domain}"; description = "File upload"; } ]; modules = { disco = true; # Service discovery roster = true; # Allow users to have a roster. Recommended ;) saslauth = true; # Authentication for clients and servers. Recommended if you want to log in. tls = true; # Add support for secure TLS on c2s/s2s connections blocklist = true; # Allow users to block communications with other users bookmarks = true; # Synchronise the list of open rooms between clients carbons = true; # Keep multiple online clients in sync dialback = true; # Support for verifying remote servers using DNS limits = true; # Enable bandwidth limiting for XMPP connections pep = true; # Allow users to store public and private data in their account private = true; # Private XML storage (for room bookmarks, etc.) smacks = true; # Allow a client to resume a disconnected session, and prevent message loss vcard = true; # User profiles (stored in PEP) vcard_legacy = true; # Conversion between legacy vCard and PEP Avatar, vcard csi = true; # Allows clients to report their active/inactive state ping = true; # Replies to XMPP pings with pongs register = true; # Allow users to register on this server using a client and change passwords time = true; # Let others know the time here on this server uptime = true; # Report how long server has been running version = true; # Replies to server version requests mam = true; # Store recent messages to allow multi-device synchronization }; extraModules = [ "admin_adhoc" # Allows administration via an XMPP client that supports ad-hoc commands "admin_shell" # Allow secure administration via 'prosodyctl shell' "invites" # Create and manage invites "invites_adhoc" # Allow admins/users to create invitations via their client "invites_register" # Allows invited users to create accounts ]; httpsPorts = [ 5281 ]; httpFileShare.domain = "upload.xmpp.${cfg.domain}"; ssl.cert = "${config.security.acme.certs."${cfg.domain}".directory}/fullchain.pem"; ssl.key = "${config.security.acme.certs."${cfg.domain}".directory}/key.pem"; virtualHosts = { zaphyra = rec { enabled = true; domain = "zaphyra.eu"; ssl.cert = "${config.security.acme.certs."${domain}".directory}/fullchain.pem"; ssl.key = "${config.security.acme.certs."${domain}".directory}/key.pem"; }; }; muc = [ { domain = "muc.xmpp.${cfg.domain}"; name = "zaphyra Chat"; restrictRoomCreation = "local"; extraConfig = '' modules_enabled = { "muc_mam"; "muc_archive"; "vcard_muc"; "measure_muc"; "pastebin"; } ''; } ]; }; }; }