Skip to content

Commit 6152ba9

Browse files
committed
Tiger Studio Web no longer flagged 'Not secure': the web bridge refuses insecure ws:/http: connections on https (Creality / Snapmaker printer pings reached the LAN from the page); worklog notes the server-side XP history fix
1 parent b08f7da commit 6152ba9

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

‎WORKLOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
- Studio Web served at the root of `studio.tigersystem.io` (no redirect); `tigersystem.io/studio` redirects there; separate sign-in from the Hub — `docs/WEB_DEPLOYMENT.md`, `docs/STUDIO-WEB-PLAN.md`, `README.md`, `FEATURES.md`, `llms.txt`, `scripts/build-web.mjs` (comments)
1010

1111
## Fixed
12+
- XP history showed some gains twice ("+20 · +20" for one printer, also chips, TigerSquad, friends) while the total counted them once — a server-side race: two recomputations of the same account ran at once and each logged the move. The backend now recomputes XP in a single Firestore transaction (`storeTotals`, TigerTag_Firebase_Backend `functions/supportWebhooks.js`, 12 functions redeployed 2026-10-14), and the 259 duplicate history entries on 42 accounts were removed. No XP total was wrong. To mention in the release note and What's New (user-visible) — no Studio code change
13+
- Tiger Studio Web was flagged "Not secure" and asked for local-network access: the Creality / Snapmaker modules ping and connect to printers straight from the page (`ws://<ip>:9999`, `http://<ip>:7125`) as soon as the printer list loads — mixed content on an https page. The web bridge now refuses any insecure WebSocket / fetch on https (callers already treat it as "printer unreachable") — `renderer/web-bridge.js`
1214
- Tiger Studio Web: the page no longer requests the Agora SDK (Anycubic cloud camera, desktop-only, not in git), which answered 404 on the web (shipped to the web as web-v2.40.0.1) — `scripts/build-web.mjs`
15+
- Hold-to-confirm buttons: the "Hold 1.5 s to confirm" bubble no longer stays on screen after the action closes its menu or rebuilds its card (e.g. deleting a printer) — PR #77 (Ptitlouis6012), `renderer/inventory.js`
16+
- Printers board: after a long drag (or with printers reporting live) the card and its widgets no longer pile up at the top-left corner with the drop never saved — the gesture and its release are module-level and survive a rebuild, held objects keep their drawn position, a hold with no gesture behind it is cleared — PR #78 (Ptitlouis6012), `renderer/inventory.js`
17+
- Printers board: a dragged group can no longer be pulled away for ever (one card reached x ≈ 11 000 and vanished off-screen) — it stops one screenful past the furthest object it is not carrying — PR #79 (Ptitlouis6012), `renderer/inventory.js`
1318

1419
## Removed
1520

‎renderer/web-bridge.js‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,34 @@
2121
// Hides every `[data-desktop-only]` element (rule in css/00-base.css).
2222
document.documentElement.classList.add("is-web");
2323

24+
// NO LAN FROM THE WEB. Some printer modules talk to the machines straight from
25+
// the page (Creality ws://<ip>:9999, Snapmaker http://<ip>:7125 — the other
26+
// brands go through the desktop's main process, absent here), and their
27+
// background pings start as soon as the printer list loads. From an https page
28+
// that is mixed content: Chrome flags the whole site "Not secure" and asks for
29+
// local-network access, for something that can't work anyway. So an insecure
30+
// WebSocket or fetch is refused right here — the callers already treat a
31+
// failure as "printer unreachable". (Printers on the web will come through a
32+
// secure relay, never the LAN — docs/STUDIO-WEB-PLAN.md.)
33+
if (location.protocol === "https:") {
34+
const insecure = (u) => {
35+
try { return /^(ws|http):$/.test(new URL(String(u), location.href).protocol); } catch { return false; }
36+
};
37+
const NativeWS = window.WebSocket;
38+
window.WebSocket = function (url, protocols) {
39+
if (insecure(url)) throw new DOMException("LAN connections are desktop-only", "SecurityError");
40+
return protocols === undefined ? new NativeWS(url) : new NativeWS(url, protocols);
41+
};
42+
window.WebSocket.prototype = NativeWS.prototype;
43+
Object.assign(window.WebSocket, { CONNECTING: 0, OPEN: 1, CLOSING: 2, CLOSED: 3 });
44+
const nativeFetch = window.fetch.bind(window);
45+
window.fetch = (input, init) => {
46+
const url = input instanceof Request ? input.url : input;
47+
if (insecure(url)) return Promise.reject(new TypeError("LAN connections are desktop-only"));
48+
return nativeFetch(input, init);
49+
};
50+
}
51+
2452
// Install as an app (PWA): Chrome / Edge / Android announce it once, possibly
2553
// before the renderer module has loaded — keep the event for the sidebar's
2654
// "Install the app" button (inventory.js) and tell it the moment it lands.

0 commit comments

Comments
 (0)