{ pkgs, ... }:

let
  elementWebVersion = "1.11.84";
  element-web = pkgs.fetchzip {
    url = "https://github.com/vector-im/element-web/releases/download/v${elementWebVersion}/element-v${elementWebVersion}.tar.gz";
    sha256 = "sha256-z2qaKKyUq2S/r3xUUU3ym0FgFbiQr6bcltuKvUMPbH4=";
  };
  elementSecurityHeaders = ''
    # Configuration best practices
    # See: https://github.com/vector-im/element-web/tree/develop#configuration-best-practices
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Content-Security-Policy "frame-ancestors 'self'";

    add_header Strict-Transport-Security "max-age=63072000" always;
  '';
in
{
  services.nginx.virtualHosts = {
    "acme-element.hamburg.ccc.de" = {
      enableACME = true;
      serverName = "element.hamburg.ccc.de";

      listen = [
        {
          addr = "0.0.0.0";
          port = 31820;
        }
      ];
    };

    "element.hamburg.ccc.de" = {
      forceSSL = true;
      useACMEHost = "element.hamburg.ccc.de";

      listen = [
        {
          addr = "0.0.0.0";
          port = 8443;
          ssl = true;
          proxyProtocol = true;
        }
      ];

      root = pkgs.buildEnv {
        name = "element-web";
        paths = [
          element-web
          ./element-web-config
        ];
      };

      # Set no-cache for the version, config and index.html
      # so that browsers always check for a new copy of Element Web.
      # NB http://your-domain/ and http://your-domain/? are also covered by this

      locations."= /index.html" = {
        extraConfig = elementSecurityHeaders + ''
          add_header Cache-Control "no-cache";
        '';
      };
      locations."= /version" = {
        extraConfig = elementSecurityHeaders + ''
          add_header Cache-Control "no-cache";
        '';
      };
      # covers config.json and config.hostname.json requests as it is prefix.
      locations."/config" = {
        extraConfig = elementSecurityHeaders + ''
          add_header Cache-Control "no-cache";
        '';
      };
      extraConfig = elementSecurityHeaders + ''
        index  index.html;

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;

        # Make use of the ngx_http_realip_module to set the $remote_addr and
        # $remote_port to the client address and client port, when using proxy
        # protocol.
        # First set our proxy protocol proxy as trusted.
        set_real_ip_from 172.31.17.140;
        # Then tell the realip_module to get the addreses from the proxy protocol
        # header.
        real_ip_header proxy_protocol;
      '';
    };
  };
}