fix(frontend): Ursprung der HoneyOS-Leiste kommt aus der .env

Die Adresse im <script>-Tag stand fest im Quelltext, waehrend die CSP aus
HONEYBAR_ORIGIN kam. Wer die Leiste woanders betreibt, bekam genau den
Widerspruch: die CSP erlaubte den eigenen Ursprung, geladen wurde der alte.

Beides speist sich jetzt aus derselben Variablen. Ist sie leer, nimmt
vite.config.ts den Tag ganz heraus — sonst bliebe src="/honeybar/honeybar.js"
stehen und der Service Worker beantwortete das mit index.html.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-08-24 22:58:19 +02:00
1 parent 1d933c5c73
commit 6c7eb348b0
5 files changed
+38 -12

No files matched your search

+5 -4
View File
@@ -65,11 +65,12 @@ ADMIN_PASSWORD=changeme_strong_admin_password
# OIDC_BUTTON_LABEL=Anmelden mit PocketID # OIDC_BUTTON_LABEL=Anmelden mit PocketID
# ── HoneyOS-Leiste ──────────────────────────────────────────────────────────── # ── HoneyOS-Leiste ────────────────────────────────────────────────────────────
# Ursprung, von dem die Leiste geladen wird. Nimmt ihn in die CSP auf # Ursprung, von dem die Leiste geladen wird. Landet an zwei Stellen: beim
# (script-src + connect-src) — ohne das blockt der Browser das Skript. # Bauen im <script>-Tag der index.html, zur Laufzeit in der CSP
# (script-src + connect-src). Leer = keine Leiste, CSP so eng wie ohne sie.
# #
# Muss exakt zur Adresse im <script>-Tag der frontend/index.html passen. # Wird beim **Bauen** eingesetzt — nach einer Änderung also
# Leer = keine Leiste, und die CSP bleibt so eng wie ohne sie. # `docker compose build app`, ein Neustart genügt nicht.
HONEYBAR_ORIGIN=https://honeyos.example.com HONEYBAR_ORIGIN=https://honeyos.example.com
# Schlüssel, mit dem sich die Leiste die App-Liste holt. Nötig, weil HoneyOS auf # Schlüssel, mit dem sich die Leiste die App-Liste holt. Nötig, weil HoneyOS auf
# einer anderen Site liegt als Aether und der Browser die HoneyOS-Sitzung dann # einer anderen Site liegt als Aether und der Browser die HoneyOS-Sitzung dann
+5 -2
View File
@@ -4,9 +4,12 @@ WORKDIR /app/frontend
COPY frontend/package*.json ./ COPY frontend/package*.json ./
RUN npm ci RUN npm ci
COPY frontend/ ./ COPY frontend/ ./
# Schlüssel für die HoneyOS-Leiste. Vite setzt ihn in die index.html ein; leer # Ursprung und Schlüssel für die HoneyOS-Leiste. Vite setzt beides in die
# heisst: die Leiste bekommt keine App-Liste, der Rest bleibt unberührt. # index.html ein. Ohne Ursprung faellt der Tag weg (keine Leiste), ohne
# Schlüssel bekommt die Leiste keine App-Liste — Aether bleibt unberührt.
ARG HONEYBAR_ORIGIN=""
ARG HONEYBAR_KEY="" ARG HONEYBAR_KEY=""
ENV VITE_HONEYBAR_ORIGIN=$HONEYBAR_ORIGIN
ENV VITE_HONEYBAR_KEY=$HONEYBAR_KEY ENV VITE_HONEYBAR_KEY=$HONEYBAR_KEY
RUN npm run build RUN npm run build
+1
View File
@@ -18,6 +18,7 @@ services:
dockerfile: deploy/Dockerfile dockerfile: deploy/Dockerfile
args: args:
# Wird in die index.html eingebacken, siehe dort. # Wird in die index.html eingebacken, siehe dort.
HONEYBAR_ORIGIN: ${HONEYBAR_ORIGIN:-}
HONEYBAR_KEY: ${HONEYBAR_KEY:-} HONEYBAR_KEY: ${HONEYBAR_KEY:-}
image: gitea.honeyy.duckdns.org/docker/aether:latest image: gitea.honeyy.duckdns.org/docker/aether:latest
restart: unless-stopped restart: unless-stopped
+6 -6
View File
@@ -29,17 +29,17 @@
`defer`: ohne wartet der Seitenaufbau auf das Skript. Ist HoneyOS `defer`: ohne wartet der Seitenaufbau auf das Skript. Ist HoneyOS
langsam oder aus, darf das Aether nicht ausbremsen. langsam oder aus, darf das Aether nicht ausbremsen.
Damit der Browser sie überhaupt lädt, muss HONEYBAR_ORIGIN in der .env Ursprung und Schlüssel kommen beide aus der .env (HONEYBAR_ORIGIN,
auf denselben Ursprung zeigen — sonst blockt die CSP. HONEYBAR_KEY) und werden beim Bauen eingesetzt. Derselbe Ursprung
landet zur Laufzeit in der CSP — so können die beiden nicht
data-key kommt aus HONEYBAR_KEY in der .env und wird beim Bauen auseinanderlaufen. Ist er leer, entfernt vite.config.ts diesen Tag
eingesetzt. HoneyOS liegt auf einer anderen Site als Aether ganz; Aether läuft dann ohne Leiste weiter. HoneyOS liegt auf einer anderen Site als Aether
(duckdns.org ist ein public suffix), deshalb schickt der Browser die (duckdns.org ist ein public suffix), deshalb schickt der Browser die
HoneyOS-Sitzung nicht mit — ohne diesen zweiten Ausweis bekäme die HoneyOS-Sitzung nicht mit — ohne diesen zweiten Ausweis bekäme die
Leiste nie eine App-Liste. Der Schlüssel steht bewusst nicht im Leiste nie eine App-Liste. Der Schlüssel steht bewusst nicht im
Quelltext: er käme sonst ins Repo und liesse sich nur mit einer Quelltext: er käme sonst ins Repo und liesse sich nur mit einer
Code-Änderung wechseln. --> Code-Änderung wechseln. -->
<script defer src="https://honeyos.duckdns.org/honeybar/honeybar.js" <script defer src="%VITE_HONEYBAR_ORIGIN%/honeybar/honeybar.js"
data-app="aether" data-key="%VITE_HONEYBAR_KEY%"></script> data-app="aether" data-key="%VITE_HONEYBAR_KEY%"></script>
</body> </body>
</html> </html>
+21
View File
@@ -32,9 +32,30 @@ function pdfjsStandardFonts(): Plugin {
} }
} }
/**
* Den <script>-Tag der HoneyOS-Leiste entfernen, wenn kein Ursprung gesetzt ist.
*
* Ohne das bliebe nach der Ersetzung src="/honeybar/honeybar.js" stehen: der
* Service Worker beantwortet die Navigation mit index.html, der Browser meldet
* einen MIME-Fehler. Kein Ursprung heisst schlicht keine Leiste.
*/
function honeybar(): Plugin {
return {
name: 'aether-honeybar',
transformIndexHtml: {
order: 'pre',
handler(html) {
if (process.env.VITE_HONEYBAR_ORIGIN?.trim()) return html
return html.replace(/\s*<script[^>]*honeybar\.js[^>]*><\/script>/, '')
},
},
}
}
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
pdfjsStandardFonts(), pdfjsStandardFonts(),
honeybar(),
react(), react(),
tailwindcss(), tailwindcss(),
VitePWA({ VitePWA({