desktop: embed Navidrome again (needs ND_HTTPHEADERS_FRAMEOPTIONS on the Navidrome host)
This commit is contained in:
parent
dbff352054
commit
19fa915e74
3 changed files with 21 additions and 14 deletions
|
|
@ -36,9 +36,10 @@ heatmap**, a gym SBD panel and links to friends' sites.
|
||||||
- **Live service status** — each self-hosted service is health-checked through the site's
|
- **Live service status** — each self-hosted service is health-checked through the site's
|
||||||
own API; Minecraft is checked through mcstatus.io.
|
own API; Minecraft is checked through mcstatus.io.
|
||||||
- **Embedded live services** — opening a frameable self-hosted service (Llama.cpp/Open WebUI,
|
- **Embedded live services** — opening a frameable self-hosted service (Llama.cpp/Open WebUI,
|
||||||
Jellyfin) from the desktop shows the real site inside the window (an iframe). Services that
|
Jellyfin, Navidrome) from the desktop shows the real site inside the window (an iframe). A
|
||||||
send `X-Frame-Options` / `frame-ancestors` can't be framed, so they keep a link card or their
|
service must not send `X-Frame-Options`: Navidrome sends `DENY` unless it runs with
|
||||||
own app card instead (Navidrome sends `DENY`, Forgejo/GitDXD `SAMEORIGIN`, Discord `DENY`).
|
`ND_HTTPHEADERS_FRAMEOPTIONS=ALLOWALL`. Forgejo/GitDXD (`SAMEORIGIN`) and Discord (`DENY`)
|
||||||
|
keep a link card / their own app card instead.
|
||||||
- **Minecraft-style SMP window** — the SMP shortcut opens a join menu modelled on
|
- **Minecraft-style SMP window** — the SMP shortcut opens a join menu modelled on
|
||||||
Minecraft's multiplayer screen, with live status, player count, MOTD and version pulled
|
Minecraft's multiplayer screen, with live status, player count, MOTD and version pulled
|
||||||
from mcstatus.io through the site's own ping API.
|
from mcstatus.io through the site's own ping API.
|
||||||
|
|
|
||||||
17
opencode.md
17
opencode.md
|
|
@ -270,13 +270,16 @@ list reordering, not free placement. Don't confuse the two.
|
||||||
- Service shortcuts can show the real site in an iframe via
|
- Service shortcuts can show the real site in an iframe via
|
||||||
`createWebsiteApp({ embed: true })` (the shortcut's `embed` flag), but the
|
`createWebsiteApp({ embed: true })` (the shortcut's `embed` flag), but the
|
||||||
browser refuses to frame a site that sends `X-Frame-Options` /
|
browser refuses to frame a site that sends `X-Frame-Options` /
|
||||||
`frame-ancestors`, leaving a blank window. `embed` is only set on Llama.cpp
|
`frame-ancestors`, leaving a blank window. `embed` is set on Llama.cpp (Open
|
||||||
(Open WebUI) and Jellyfin, which allow framing. Navidrome (`DENY`) and
|
WebUI), Jellyfin and Navidrome. Llama.cpp/Jellyfin allow framing; Navidrome
|
||||||
Forgejo/GitDXD (`SAMEORIGIN`) are deliberately **not** embedded: Navidrome
|
only does when its host runs with `ND_HTTPHEADERS_FRAMEOPTIONS=ALLOWALL`
|
||||||
falls back to the link card and GitDXD opens its dedicated app card. To embed
|
(Navidrome maps `HTTPHeaders.FrameOptions` to that env var and it overrides
|
||||||
them live you must strip those headers at the edge (Cloudflare "Modify
|
its built-in `FrameDeny`; any unrecognised value is ignored by the browser).
|
||||||
Response Header" or nginx) and accept the clickjacking risk. Always verify
|
For a scoped, clickjacking-safe alternative, remove the header at the edge
|
||||||
headers before enabling `embed` on a new service.
|
(Cloudflare "Modify Response Header" / nginx) and add
|
||||||
|
`Content-Security-Policy: frame-ancestors`. Forgejo/GitDXD (`SAMEORIGIN`)
|
||||||
|
keeps its dedicated app card. Always verify headers before enabling `embed`
|
||||||
|
on a new service.
|
||||||
- Reduced motion is handled with a near-zero `animation-duration` (not
|
- Reduced motion is handled with a near-zero `animation-duration` (not
|
||||||
`animation: none`) so `animationend` still fires and windows unmount.
|
`animation: none`) so `animationend` still fires and windows unmount.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,18 @@ interface IconEntry {
|
||||||
|
|
||||||
// `embed: true` renders the real site in an iframe, which the browser refuses
|
// `embed: true` renders the real site in an iframe, which the browser refuses
|
||||||
// (blank window) when the server sends X-Frame-Options / frame-ancestors.
|
// (blank window) when the server sends X-Frame-Options / frame-ancestors.
|
||||||
// Llama.cpp and Jellyfin allow framing; Navidrome sends `X-Frame-Options: DENY`
|
// Llama.cpp and Jellyfin allow framing out of the box. Navidrome sends
|
||||||
// and Forgejo (GitDXD) sends `SAMEORIGIN`, so those two use their link card or
|
// `X-Frame-Options: DENY` unless it is started with
|
||||||
// the dedicated GitDXD app instead.
|
// `ND_HTTPHEADERS_FRAMEOPTIONS=ALLOWALL`, which replaces that header with an
|
||||||
|
// unrecognised value the browser ignores (that env var is set on the Navidrome
|
||||||
|
// host — without it this window is blank again). Forgejo (GitDXD) sends
|
||||||
|
// `SAMEORIGIN`, so it keeps its dedicated app card.
|
||||||
const SERVICE_SHORTCUTS: Shortcut[] = [
|
const SERVICE_SHORTCUTS: Shortcut[] = [
|
||||||
{ id: "svc-proxmox", icon: "🖥️", label: "Proxmox", appId: "alacritty", color: "#1257a0", desc: "Server Management" },
|
{ id: "svc-proxmox", icon: "🖥️", label: "Proxmox", appId: "alacritty", color: "#1257a0", desc: "Server Management" },
|
||||||
{ id: "svc-ai", icon: "🦾", label: "Llama.cpp", url: "https://ai.dvorakmortonxd.dev/", color: "#157347", desc: "Local AI Server", embed: true },
|
{ id: "svc-ai", icon: "🦾", label: "Llama.cpp", url: "https://ai.dvorakmortonxd.dev/", color: "#157347", desc: "Local AI Server", embed: true },
|
||||||
{ id: "svc-jellyfin", icon: "🎬", label: "Jellyfin", url: "https://jelly.dvorakmortonxd.dev/", color: "#6a4fb3", desc: "Local Media Server", embed: true },
|
{ id: "svc-jellyfin", icon: "🎬", label: "Jellyfin", url: "https://jelly.dvorakmortonxd.dev/", color: "#6a4fb3", desc: "Local Media Server", embed: true },
|
||||||
{ id: "svc-smp", icon: "🎮", label: "SMP", appId: "smp", color: "#c0392b", desc: "My Survival Minecraft Server" },
|
{ id: "svc-smp", icon: "🎮", label: "SMP", appId: "smp", color: "#c0392b", desc: "My Survival Minecraft Server" },
|
||||||
{ id: "svc-navidrome", icon: "🎸", label: "Navidrome", url: "https://navidrome.dvorakmortonxd.dev/", color: "#b3005f", desc: "Music Streaming" },
|
{ id: "svc-navidrome", icon: "🎸", label: "Navidrome", url: "https://navidrome.dvorakmortonxd.dev/", color: "#b3005f", desc: "Music Streaming", embed: true },
|
||||||
{ id: "svc-gitdxd", icon: "🐙", label: "GitDXD", appId: "gitdxd", color: "#6a4fb3", desc: "Best Git Hosting OAT" },
|
{ id: "svc-gitdxd", icon: "🐙", label: "GitDXD", appId: "gitdxd", color: "#6a4fb3", desc: "Best Git Hosting OAT" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue