{pkgs, outputs, config, ...}: {
  services = {
    # Synapse Matrix server
    matrix-synapse = with config.services.coturn; {
      enable = true;
      settings = {
        server_name = "${outputs.secrets.jimDomain}";
        public_baseurl = "https://matrix.${outputs.secrets.jimDomain}";
        suppress_key_server_warning = true;

        # Set the network config
        listeners = [{
          # Client config
          port = 8008;
          bind_addresses = [ "::" "0.0.0.0" ];
          resources = [ { compress = false;  names = [ "client" "federation" ]; } ];
          type = "http";
          tls = false;
          x_forwarded = true;
        }];

        # Enable smtp for password resets
        email = {
          notif_from = "Jimbo's Matrix <noreply@${outputs.secrets.jimDomain}>";
          smtp_host = "mx.${outputs.secrets.jimDomain}";
          smtp_user = "noreply@${outputs.secrets.jimDomain}";
          smtp_pass = outputs.secrets.noreplyPassword;
          enable_tls = true;
          smtp_port = 587;
          require_transport_security = true;
        };

	# Allows a Discord/Matrix bridge, comment on first use and copy using instructions
	app_service_config_files = [
          # cp /var/lib/matrix-appservice-discord/discord-registration.yaml /var/lib/matrix-synapse/
          # chown matrix-synapse:matrix-synapse /var/lib/matrix-synapse/discord-registration.yaml
          "/var/lib/matrix-synapse/discord-registration.yaml"
        ];

        # Disable registration without email
        registrations_require_3pid = [ "email" ];

        # Allow only this range of emails
        allowed_local_3pids = [{
          medium = "email";
          pattern = "^[^@]+@jimbosfiles\\.com$";
        }];

        # Set the type of database
        database.name = "sqlite3";

        # Allow account registration
        enable_registration = true;

        # General settings
        url_preview_enabled = true;
        max_upload_size = "50M";
        report_stats = false;

        # Turn settings
        turn_uris = [
          "turn:turn.${outputs.secrets.jimDomain}:3478?transport=udp"
          "turn:turn.${outputs.secrets.jimDomain}:3478?transport=tcp"
        ];
        turn_shared_secret = static-auth-secret;
        turn_user_lifetime = "1h";

        # Ratelimiting
        burst_count = 15;
      };
    };

    # Sliding sync proxy for Matrix
    matrix-sliding-sync = let
      matrixSecretFile = pkgs.writeText "matrixsecret" ''
        SYNCV3_SECRET=${outputs.secrets.matrixSecret}
      '';
    in {
      enable = true;
      settings = {
        SYNCV3_SERVER = "https://matrix.${outputs.secrets.jimDomain}";
        SYNCV3_BINDADDR = "0.0.0.0:8009";
      };
      environmentFile = "${matrixSecretFile}";
    };

    # Coturn for VC
    coturn = rec {
      enable = true;
      no-cli = true;
      no-tcp-relay = true;
      min-port = 49000;
      max-port = 50000;
      use-auth-secret = true;
      static-auth-secret = "will be world readable for local users :(";
      realm = "turn.${outputs.secrets.jimDomain}";
      cert = "/var/lib/acme/turn.${outputs.secrets.jimDomain}.com/fullchain.pem";
      pkey = "/var/lib/acme/turn.${outputs.secrets.jimDomain}.com/key.pem";
    };

    # Nginx
    nginx.virtualHosts = {
      "matrix.${outputs.secrets.jimDomain}" = {
        enableACME = true;
        forceSSL = true;
        locations = {
          "/".extraConfig = ''return 403;'';
           "/client".proxyPass = "http://127.0.0.1:8009";
           "/_matrix".proxyPass = "http://127.0.0.1:8008";
          "/_matrix/client/unstable/org.matrix.msc3575/sync".proxyPass = "http://127.0.0.1:8009";
           "/_synapse/client".proxyPass = "http://127.0.0.1:8008";
        };
      };
      "turn.${outputs.secrets.jimDomain}" = {
        enableACME = true;
        forceSSL = true;
        listen = [
          { addr = "0.0.0.0"; port = 80; ssl = false; }
        ];
        locations."/".proxyPass = "http://127.0.0.1:1380";
      };
    };
  };
}