{ config, lib, pkgs, ... }: with lib; let cfg = config.sydnix.deertopia.webdav; in { options = { sydnix.deertopia.webdav = { enable = mkEnableOption "Deertopia's WebDAV server"; port = lib.mkOption { default = 22016; type = lib.types.port; description = '' The internal WebDAV port. The actual server will be hosted at https://dav.deertopia.net/. ''; }; user = lib.mkOption { default = "webdav"; type = lib.types.str; }; group = lib.mkOption { default = "webdav"; type = lib.types.str; }; }; }; config = mkIf cfg.enable { users.users.${cfg.user} = { isSystemUser = true; group = cfg.group; }; users.groups.${cfg.group} = {}; systemd.services.webdav = let htpasswdFile = "/run/secrets/webdav-htpasswd"; directory = "/var/lib/webdav"; in { description = "Deertopia's WebDAV server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; script = '' ${pkgs.rclone}/bin/rclone serve webdav \ --addr ":${builtins.toString cfg.port}" \ --htpasswd "${htpasswdFile}" "${directory}" ''; serviceConfig = { User = cfg.user; Group = cfg.group; Restart = "always"; }; unitConfig = { StateDirectory = "webdav"; }; }; # Without this, Nginx will attempt redirections to https://localhost, which # is not okay because localhost does not have any associated certs! # See: https://forum.seafile.com/t/seafdav-move-command-causing-502/11582/26 services.nginx.appendHttpConfig = '' map $http_destination $http_destination_webdav { ~*https://(.+) http://$1; default $http_destination; } ''; systemd.tmpfiles.settings."50-var-lib-webdav" = let e = let x = { inherit (cfg) user group; mode = "2775"; }; in { z = x; v = x; }; in { "/var/lib/webdav/~msyds/org" = e; "/var/lib/webdav/~msyds/zotero" = e; }; sydnix.sops.secrets.webdav-htpasswd = { owner = cfg.user; mode = "0600"; }; sydnix.impermanence.directories = [ "/var/lib/webdav" ]; sydnix.deertopia.nginx.vhosts."dav".vhost = { forceSSL = true; enableACME = true; locations."/" = { extraConfig = '' proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; # See previous note regarding the HTTPS -> HTTP redirection. proxy_set_header Destination $http_destination_webdav; # Increase limit of upload sizes. client_max_body_size 20G; proxy_pass "http://localhost:${builtins.toString cfg.port}"; ''; }; }; }; }