1
0

feat: add ephemeral webcam faces and adaptive screens

This commit is contained in:
2026-08-11 22:38:56 -07:00
parent 3326d2e6d0
commit d4859b33c6
17 changed files with 1107 additions and 11 deletions
+28 -3
View File
@@ -32,9 +32,10 @@ tera.example.com {
file_server
header {
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'"
# Screen sharing remains a per-action browser prompt. Webcam capture stays
# disabled until that separate feature is deliberately deployed.
Permissions-Policy "display-capture=(self), camera=(), microphone=(), geolocation=(), payment=(), usb=()"
# Screen sharing and webcam faces remain contextual, per-action browser
# prompts. Same-origin permission enables those prompts; it does not grant
# capture. Microphone capture is deliberately unavailable.
Permissions-Policy "display-capture=(self), camera=(self), microphone=(), geolocation=(), payment=(), usb=()"
}
}
```
@@ -48,6 +49,30 @@ is drawn on a canvas at runtime rather than shipped as a file — see
ARCHITECTURE.md §3.1 for why that is a licensing decision and not a technical
one.
### Capture-policy acceptance check
Webcam faces require a secure context and `camera=(self)` on both the Tera and
Office hostnames. That policy only permits the application to ask: capture must
still begin inside the explicit face or screen action, display a persistent
active indicator, and stop on the in-product control or `pagehide`. Keep
`microphone=()` because neither webcam faces nor office screens request audio.
After changing the live Caddy site, reload Caddy through the normal reviewed
deployment procedure and verify both hostnames before enabling the UI:
```bash
curl -fsSI https://tera.example.com/ | grep -i '^permissions-policy:'
curl -fsSI https://office.example.com/ | grep -i '^permissions-policy:'
```
Both responses must contain `display-capture=(self)`, `camera=(self)`, and
`microphone=()`. In browser developer tools,
`document.permissionsPolicy?.allowsFeature("camera")` should be true on the
top-level same-origin page; denying the browser prompt must leave the generated
face and every office screen placeholder intact. The CSP needs no camera/media
host exception: webcam and display tracks are caller-owned `MediaStream`s, not
network media URLs, and signaling remains under same-origin `connect-src`.
## Serving the API too
Only needed for live weather, real ADS-B, or markers from an external source.