embed friends' sites live in desktop windows; frame the skopec mirror since skopec.dev blocks framing
This commit is contained in:
parent
bfa0840b0e
commit
d5dfea060f
4 changed files with 30 additions and 1 deletions
|
|
@ -41,6 +41,10 @@ heatmap**, a gym SBD panel and links to friends' sites.
|
|||
`ND_HTTPHEADERS_FRAMEOPTIONS=ALLOWALL` and Forgejo needs `[cors] X_FRAME_OPTIONS = unset`.
|
||||
A spinner covers the frame while the site boots. Discord sends `DENY` and keeps a link card
|
||||
instead.
|
||||
- **Friend sites in windows** — clicking a friend's desktop icon opens their site in a
|
||||
window. `bukovinafilip.com` and `vlcak.me` send no framing headers, so they load live;
|
||||
`skopec.dev` sends `X-Frame-Options: SAMEORIGIN`, so the window frames the bundled mirror
|
||||
at `/skopec.html` and the `www` button opens the real site.
|
||||
- **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
|
||||
from mcstatus.io through the site's own ping API.
|
||||
|
|
|
|||
|
|
@ -295,6 +295,14 @@ list reordering, not free placement. Don't confuse the two.
|
|||
`Content-Security-Policy: frame-ancestors`. Discord keeps a link card because
|
||||
it sends `DENY` and can't be configured. Always verify headers before enabling
|
||||
`embed` on a new service.
|
||||
- Friend shortcuts reuse the same embed path, driven by `data.ts`. `friend.iframe`
|
||||
is the `embed` flag; `friend.url` is what the frame loads and `friend.realUrl`
|
||||
is what the www button opens — `createWebsiteApp`'s `embedUrl` option lets the
|
||||
two differ. `bukovinafilip.com` and `vlcak.me` send no framing headers, so they
|
||||
frame the live site; `skopec.dev` sends `X-Frame-Options: SAMEORIGIN` on every
|
||||
path, so `friends[0].url` points at the bundled `/public/skopec.html` mirror
|
||||
and only the button is live. Making a blocking site load *live* would need a
|
||||
header-stripping proxy (allowlisted) — not implemented.
|
||||
- **Embedded iframes swallow the pointer.** While dragging/resizing a window,
|
||||
the moment the cursor passes over a service `<iframe>` the site's own document
|
||||
receives the `pointermove`/`pointerup`, so a gesture that listens on `window`
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ interface Shortcut {
|
|||
image?: string;
|
||||
/** Show the real site in an iframe. Only for sites that allow framing. */
|
||||
embed?: boolean;
|
||||
/** Frame src when it differs from `url` (e.g. a local mirror of a blocking site). */
|
||||
embedUrl?: string;
|
||||
}
|
||||
|
||||
interface IconEntry {
|
||||
|
|
@ -58,10 +60,18 @@ const SERVICE_SHORTCUTS: Shortcut[] = [
|
|||
{ id: "svc-gitdxd", icon: "🐙", label: "GitDXD", url: "https://git.dvorakmortonxd.dev", color: "#6a4fb3", desc: "Best Git Hosting OAT", embed: true },
|
||||
];
|
||||
|
||||
// Friends' sites, opened in a live window when they allow framing. bukovinafilip
|
||||
// and vlcak.me send no framing headers, so `url` (== `realUrl`) is framed
|
||||
// directly. skopec.dev sends `X-Frame-Options: SAMEORIGIN` on every path, so we
|
||||
// frame the same-origin mirror at `/skopec.html` instead; the www button still
|
||||
// opens the live site. To embed a site that blocks framing live, it would need a
|
||||
// header-stripping proxy.
|
||||
const FRIEND_SHORTCUTS: Shortcut[] = friends.map((f, i) => ({
|
||||
id: `friend-${i}`,
|
||||
label: f.name,
|
||||
url: f.realUrl || f.url,
|
||||
embedUrl: f.url,
|
||||
embed: f.iframe,
|
||||
color: "#c0392b",
|
||||
icon: "🫂",
|
||||
image: f.img,
|
||||
|
|
@ -214,6 +224,7 @@ export default function WindowsDesktop() {
|
|||
icon: s.icon,
|
||||
image: s.image,
|
||||
embed: s.embed,
|
||||
embedUrl: s.embedUrl,
|
||||
});
|
||||
setDynamicApps((prev) => (prev[id] ? prev : { ...prev, [id]: app }));
|
||||
openAppDef(app);
|
||||
|
|
|
|||
|
|
@ -851,6 +851,12 @@ export function createWebsiteApp(opts: {
|
|||
* sites that do not send `X-Frame-Options` / a `frame-ancestors` CSP.
|
||||
*/
|
||||
embed?: boolean;
|
||||
/**
|
||||
* URL to load inside the frame when it differs from `url` (which the www
|
||||
* button opens). Used for sites that block framing: we frame a same-origin
|
||||
* mirror instead, while the button still points at the live site.
|
||||
*/
|
||||
embedUrl?: string;
|
||||
}): AppDef {
|
||||
return {
|
||||
id: opts.id,
|
||||
|
|
@ -861,7 +867,7 @@ export function createWebsiteApp(opts: {
|
|||
height: opts.embed ? 640 : 440,
|
||||
url: opts.url,
|
||||
content: opts.embed ? (
|
||||
<EmbeddedSite title={opts.title} url={opts.url} />
|
||||
<EmbeddedSite title={opts.title} url={opts.embedUrl ?? opts.url} />
|
||||
) : (
|
||||
<WebsiteApp
|
||||
title={opts.title}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue