fix(cinny/nginx): let the app frame its bundled Element Call again
Lint / Shell (shellcheck) (push) Successful in 20s
Lint / JS (eslint) (push) Successful in 13s
Lint / No secrets in webhook configs (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 5s
Lint / Python deps (pip-audit) (push) Successful in 44s
Lint / Secret scan (gitleaks) (push) Successful in 8s

Web calls broke ("nobody can join calls from the web version"): 23ad133
(cinny #210) put the security-headers snippet, including the app CSP, on
every .html response. /public/element-call/index.html then carried
frame-ancestors 'none', so the browser refused to load it inside the app
("Content-Security-Policy ... frame-ancestors 'none'"). Desktop was fine (it
loads Element Call from its own bundle). Before #210 that page had no CSP.

A `location ^~ /public/element-call/` now serves it with
cinny-security-headers-framed.conf: the same headers minus the CSP
(X-Frame-Options SAMEORIGIN still limits framing to chat.lotusguild.org),
and the same caching (HTML no-cache, hashed assets 1 year). Applied live on
LXC 106 (backup sites-available/cinny.bak-ecframe-*), nginx -t ok; verified
from outside: no CSP on the call page, and the live site frames it and it
loads ("Element Call").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
Lotus CI
2026-09-25 19:26:44 -04:00
co-authored by Claude Opus 5.5
parent 23ad133dc3
commit d4fd1d0b8e
2 changed files with 28 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
# Headers for the bundled Element Call page (/public/element-call/).
# Same as cinny-security-headers.conf minus the Content-Security-Policy: the app
# embeds this page in an iframe, and the app CSP's frame-ancestors 'none' (plus a
# connect-src that doesn't list the call backends) blocked it. X-Frame-Options
# SAMEORIGIN still limits framing to chat.lotusguild.org itself.
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Permissions-Policy "accelerometer=(), autoplay=(self), camera=(self), display-capture=(self), encrypted-media=(self), fullscreen=(self), geolocation=(self), gyroscope=(), magnetometer=(), microphone=(self), midi=(), payment=(), usb=()" always;
+17
View File
@@ -51,6 +51,23 @@ server {
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
}
# Bundled Element Call: framed by the app itself, so it must not carry the
# app CSP (frame-ancestors 'none' blocked every web call). Same caching as
# below: HTML never cached, hashed assets for a year.
location ^~ /public/element-call/ {
include snippets/cinny-security-headers-framed.conf;
location ~* \.html$ {
include snippets/cinny-security-headers-framed.conf;
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
}
location ~* \.(?:js|css|woff2?|png|svg|ico|webp|wasm)$ {
include snippets/cinny-security-headers-framed.conf;
expires 1y;
add_header Cache-Control "public, immutable" always;
}
}
# Cache content-addressed static assets aggressively
location ~* \.(?:js|css|woff2?|png|svg|ico|webp)$ {
include snippets/cinny-security-headers.conf;