docs: die Leiste per Reverse Proxy in fremde Apps einsetzen
Rezept fuer nginx, geprueft gegen eine App mit gzip und eigener CSP. Die vier Fallen stehen dabei: Kompression, CSP ersetzen statt ergaenzen, nur HTML anfassen, Ursprung in HoneyOS eintragen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cce926ab2e
commit
05e56f4cd2
2 files changed
+66
No files matched your search
@@ -241,6 +241,22 @@ Zu klären, wenn es soweit ist:
|
|||||||
- **Kein Netz, kein Wetter.** Dann verschwindet das Symbol, statt eine Zahl von
|
- **Kein Netz, kein Wetter.** Dann verschwindet das Symbol, statt eine Zahl von
|
||||||
gestern als heutige auszugeben.
|
gestern als heutige auszugeben.
|
||||||
|
|
||||||
|
### Die Leiste ohne `unsafe-inline`
|
||||||
|
|
||||||
|
Fremde Apps bekommen die Leiste über den Reverse Proxy (siehe README). Dabei
|
||||||
|
muss deren CSP heute `style-src 'unsafe-inline'` erlauben, weil die Leiste ihre
|
||||||
|
Stile im Shadow DOM mitbringt — ohne das erscheint sie schwarz auf schwarz.
|
||||||
|
Gemessen am 28.08.2026 an einer nachgebauten fremden App.
|
||||||
|
|
||||||
|
**Auflösbar:** Die Stile als eigene Datei neben `honeybar.js` ausliefern und im
|
||||||
|
Shadow DOM per `<link>` einbinden. Dann genügt `style-src 'self' https://honeyos…`,
|
||||||
|
und die CSP der fremden App bleibt streng. Kostet eine zweite Anfrage, die
|
||||||
|
zwischengespeichert wird.
|
||||||
|
|
||||||
|
Zu prüfen ist dabei, was sonst noch inline gesetzt wird: die Lage der Leiste
|
||||||
|
selbst und der Innenabstand, den sie der Seite verpasst. Über die CSSOM gesetzte
|
||||||
|
Stile (`el.style.x = …`) fallen nicht unter die CSP — was im Markup steht, schon.
|
||||||
|
|
||||||
### Widgets in der Leiste selbst
|
### Widgets in der Leiste selbst
|
||||||
|
|
||||||
Bisher sind Widgets als Fenster auf dem Schreibtisch gedacht. Der Schreibtisch
|
Bisher sind Widgets als Fenster auf dem Schreibtisch gedacht. Der Schreibtisch
|
||||||
|
|||||||
@@ -183,6 +183,56 @@ hinein, ihre Stile nicht hinaus. Sie schiebt den Seiteninhalt um 32 px nach unte
|
|||||||
|
|
||||||
Vorschau ohne Einbau: `/honeybar/demo.html`.
|
Vorschau ohne Einbau: `/honeybar/demo.html`.
|
||||||
|
|
||||||
|
## Die Leiste in fremde Apps einsetzen (Reverse Proxy)
|
||||||
|
|
||||||
|
Für Werkzeuge, die man **nicht selbst geschrieben hat**, gibt es keinen
|
||||||
|
`<script>`-Tag zum Ändern — den setzt der Reverse Proxy ein, während er die
|
||||||
|
Seite durchreicht. Getestet mit nginx gegen eine App mit gzip und eigener CSP:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8181;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# 1. Unkomprimiert anfordern — in einem gzip-Strom ist nichts zu ersetzen.
|
||||||
|
proxy_set_header Accept-Encoding "";
|
||||||
|
|
||||||
|
# 2. Die CSP der App ersetzen, nicht ergänzen. Zwei CSP-Kopfzeilen bedeuten
|
||||||
|
# nicht „mehr erlaubt", sondern „beide müssen zustimmen".
|
||||||
|
proxy_hide_header Content-Security-Policy;
|
||||||
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://honeyos.example.com; connect-src 'self' https://honeyos.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:" always;
|
||||||
|
|
||||||
|
# 3. Nur HTML anfassen; JSON, Bilder und Downloads bleiben unberührt.
|
||||||
|
sub_filter_types text/html;
|
||||||
|
sub_filter_once on;
|
||||||
|
sub_filter '</head>' '<script defer src="https://honeyos.example.com/honeybar/honeybar.js" data-app="werkzeug"></script></head>';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Dazu muss der Ursprung dieser App **in HoneyOS als App eingetragen** sein — die
|
||||||
|
Liste ist zugleich die CORS-Freigabe.
|
||||||
|
|
||||||
|
**Warum `style-src 'unsafe-inline'`:** Die Leiste bringt ihre Stile mit, im
|
||||||
|
Shadow DOM. Eine strenge CSP verbietet die — gemessen: die Leiste erscheint,
|
||||||
|
aber schwarz auf schwarz, ohne Röhre. Das ist eine echte Abschwächung der
|
||||||
|
CSP dieser App; viele fertige Werkzeuge brauchen `unsafe-inline` ohnehin für
|
||||||
|
sich selbst, aber wissen sollte man es. (Auflösbar, indem die Leiste ihre Stile
|
||||||
|
als eigene Datei ausliefert — steht in [IDEAS.md](IDEAS.md).)
|
||||||
|
|
||||||
|
**Was dabei zu erwarten ist:**
|
||||||
|
|
||||||
|
- **Das Layout der fremden App kennt die Leiste nicht.** Rechnet sie mit
|
||||||
|
`100vh`, wird die Seite um 32 px zu hoch (Bildlaufleiste) — ihr CSS lässt
|
||||||
|
sich nicht anpassen wie das eigene. Dann hilft `data-push="none"`: Die Leiste
|
||||||
|
legt sich darüber, statt zu schieben. Verdeckt dafür die oberste Zeile.
|
||||||
|
- **Apps mit eigener Kopfleiste** sehen doppelt belegt aus. Geschmackssache.
|
||||||
|
- **Anmeldeseiten, iframes, Downloads** bekommen die Leiste ebenfalls, soweit
|
||||||
|
sie HTML sind. `sub_filter` unterscheidet das nicht.
|
||||||
|
- **Andere Proxys:** Caddy braucht ein Zusatzmodul (`replace-response`),
|
||||||
|
Traefik ein Plugin für den Antwortkörper. nginx kann es ohne Erweiterung.
|
||||||
|
|
||||||
## Wer ist wo angemeldet
|
## Wer ist wo angemeldet
|
||||||
|
|
||||||
Das Feld **Wer-bin-ich** ist der Pfad, unter dem eine App „wer bin ich" beantwortet
|
Das Feld **Wer-bin-ich** ist der Pfad, unter dem eine App „wer bin ich" beantwortet
|
||||||
|
|||||||
Reference in new issue
Block a user