From 687764102ae09b316ba42c7b362745dc651b3e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20=22Thebys=22=20Biheler?= Date: Tue, 1 Sep 2026 21:34:39 +0200 Subject: [PATCH] Fix space status widget SpaceAPI 0.13 returns state as an object ({"open": bool, "lastchange": ts}), not a boolean, so `data.state` was always truthy and the widget reported the space as open regardless of its real state. Read `data.state.open`. Fetch /api/spaceapi same-origin through the nginx proxy, and drop the hand-written Cache-Control/Pragma request headers: they make the request non-simple, and HA answers the resulting CORS preflight with 403 because its allowed-header list is hardcoded. The ?t= cache buster already does the job. Co-Authored-By: Claude Opus 5 --- js/main.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/js/main.js b/js/main.js index ee24319..7d7c764 100644 --- a/js/main.js +++ b/js/main.js @@ -483,17 +483,15 @@ document.addEventListener('DOMContentLoaded', function () { }; const lang = isCzech ? 'czech' : 'english'; - // Note on how to obtain the following JSON file, CURL example: - // curl -k -H https://ha.base48.cz/api/spaceapi -o api/base_status.json + // nginx proxies /api/spaceapi to Home Assistant, so this is same-origin. + // curl https://base48.cz/api/spaceapi // Try to fetch the base status (with cache busting) const cacheBuster = Date.now(); - fetch(`https://ha.base48.cz/api/spaceapi?t=${cacheBuster}`, { - cache: 'no-cache', - headers: { - 'Cache-Control': 'no-cache, no-store, must-revalidate', - 'Pragma': 'no-cache' - } + // No custom headers: they would trigger a CORS preflight, which HA + // answers with 403. The ?t= above is enough to bust the cache. + fetch(`/api/spaceapi?t=${cacheBuster}`, { + cache: 'no-cache' }) .then(response => { if (!response.ok) { @@ -503,8 +501,8 @@ document.addEventListener('DOMContentLoaded', function () { }) .then(data => { // Check if the base is open based on the state field - // New API format: true/false - const isOpen = data.state; + // SpaceAPI 0.13: state is {"open": bool, "lastchange": ts} + const isOpen = data.state.open; statusElement.textContent = isOpen ? texts[lang].open : texts[lang].closed; statusElement.className = `base-status ${isOpen ? 'open' : 'closed'}`;