{ pkgs, ... }: let element-web = pkgs.fetchzip { url = "https://github.com/vector-im/element-web/releases/download/v1.11.43/element-v1.11.43.tar.gz"; sha256 = "sha256-MxUu5dFf4RL0crQol4hG6gNE+9Qu5/vBWdpf0ENaFV0="; }; in { services.nginx.virtualHosts."element.nekover.se" = { forceSSL = true; enableACME = true; root = pkgs.buildEnv { name = "element-web"; paths = [ element-web ./element-web-config ]; }; listen = [ { addr = "localhost"; port = 1234; } # workaround for enableACME check { addr = "localhost"; port = 8443; ssl = true; proxyProtocol = true; } ]; # 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 = '' add_header Cache-Control "no-cache"; 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 'none'"; add_header Strict-Transport-Security "max-age=63072000" always; ''; }; locations."= /version" = { extraConfig = '' add_header Cache-Control "no-cache"; 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 'none'"; add_header Strict-Transport-Security "max-age=63072000" always; ''; }; # covers config.json and config.hostname.json requests as it is prefix. locations."/config" = { extraConfig = '' add_header Cache-Control "no-cache"; 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 'none'"; add_header Strict-Transport-Security "max-age=63072000" always; ''; }; extraConfig = '' index index.html; # 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 'none'"; add_header Strict-Transport-Security "max-age=63072000" always; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; set_real_ip_from 127.0.0.1; real_ip_header proxy_protocol; ''; }; }